Merge branch 'master' of github.com:spring-projects/sts4
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,7 @@
|
||||
hs_err_pid*
|
||||
|
||||
target/
|
||||
bin/
|
||||
*.log
|
||||
|
||||
# Mac OSX aux files
|
||||
|
||||
@@ -39,6 +39,14 @@ resources:
|
||||
secret_access_key: {{s3_secretkey}}
|
||||
region_name: {{s3_region}}
|
||||
regexp: sts4/vscode-extensions/snapshots/vscode-boot-properties-(.*).vsix
|
||||
- name: s3-boot-java-vsix-snapshot
|
||||
type: s3
|
||||
source:
|
||||
bucket: {{s3_bucket}}
|
||||
access_key_id: {{s3_accesskey}}
|
||||
secret_access_key: {{s3_secretkey}}
|
||||
region_name: {{s3_region}}
|
||||
regexp: sts4/vscode-extensions/snapshots/vscode-boot-java-(.*).vsix
|
||||
- name: s3-concourse-vsix-snapshot
|
||||
type: s3
|
||||
source:
|
||||
@@ -103,6 +111,10 @@ jobs:
|
||||
params:
|
||||
file: vsix-files/vscode-boot-properties-*.vsix
|
||||
acl: public-read
|
||||
- put: s3-boot-java-vsix-snapshot
|
||||
params:
|
||||
file: vsix-files/vscode-boot-java-*.vsix
|
||||
acl: public-read
|
||||
- put: s3-concourse-vsix-snapshot
|
||||
params:
|
||||
file: vsix-files/vscode-concourse-*.vsix
|
||||
@@ -144,6 +156,10 @@ jobs:
|
||||
passed:
|
||||
- build-vsix-snapshots
|
||||
trigger: true
|
||||
- get: s3-boot-java-vsix-snapshot
|
||||
passed:
|
||||
- build-vsix-snapshots
|
||||
trigger: true
|
||||
- get: s3-concourse-vsix-snapshot
|
||||
passed:
|
||||
- build-vsix-snapshots
|
||||
|
||||
@@ -15,6 +15,8 @@ export vscode_manifest_yaml=$(basename s3-manifest-yaml-vsix-${dist_type}/*.vsix
|
||||
echo "vscode_manifest_yaml=$vscode_manifest_yaml"
|
||||
export vscode_boot_properties=$(basename s3-boot-properties-vsix-${dist_type}/*.vsix)
|
||||
echo "vscode_boot_properties=$vscode_boot_properties"
|
||||
export vscode_boot_java=$(basename s3-boot-java-vsix-${dist_type}/*.vsix)
|
||||
echo "vscode_boot_java=$vscode_boot_java"
|
||||
export vscode_concourse=$(basename s3-concourse-vsix-${dist_type}/*.vsix)
|
||||
echo "vscode_concourse=$vscode_concourse"
|
||||
|
||||
@@ -23,6 +25,9 @@ envsubst > "$target/vscode-extensions-snippet.html" << XXXXXX
|
||||
<li>Spring Boot Property Language Server:
|
||||
<a href="http://s3-test.spring.io/sts4/vscode-extensions/${dist_type}s/${vscode_boot_properties}">${vscode_boot_properties}</a>
|
||||
</li>
|
||||
<li>Spring Boot Java Language Server:
|
||||
<a href="http://s3-test.spring.io/sts4/vscode-extensions/${dist_type}s/${vscode_boot_java}">${vscode_boot_java}</a>
|
||||
</li>
|
||||
<li>Cloud Foundry Manifest Language Server:
|
||||
<a href="http://s3-test.spring.io/sts4/vscode-extensions/${dist_type}s/${vscode_manifest_yaml}">${vscode_manifest_yaml}</a>
|
||||
</li>
|
||||
|
||||
@@ -2,6 +2,7 @@ inputs:
|
||||
- name: sts4
|
||||
- name: s3-manifest-yaml-vsix-snapshot
|
||||
- name: s3-boot-properties-vsix-snapshot
|
||||
- name: s3-boot-java-vsix-snapshot
|
||||
- name: s3-concourse-vsix-snapshot
|
||||
outputs:
|
||||
- name: website
|
||||
|
||||
@@ -55,4 +55,9 @@
|
||||
<category name="Spring Boot IDE Language Servers for Eclipse" />
|
||||
</feature>
|
||||
|
||||
<feature
|
||||
id="org.springframework.boot.ide.java.servers.feature" version="0.0.0">
|
||||
<category name="Spring Boot IDE Language Servers for Eclipse" />
|
||||
</feature>
|
||||
|
||||
</site>
|
||||
|
||||
@@ -83,6 +83,7 @@ openFile</programArgs>
|
||||
<feature id="org.springframework.boot.ide.branding.feature" installMode="root"/>
|
||||
<feature id="org.springframework.boot.ide.main.feature" installMode="root"/>
|
||||
<feature id="org.springframework.boot.ide.properties.servers.feature" installMode="root"/>
|
||||
<feature id="org.springframework.boot.ide.java.servers.feature" installMode="root"/>
|
||||
<feature id="org.springframework.boot.ide.cloudfoundry.server.feature" installMode="root"/>
|
||||
|
||||
</features>
|
||||
|
||||
@@ -55,4 +55,9 @@
|
||||
<category name="Spring Boot IDE Language Servers for Eclipse" />
|
||||
</feature>
|
||||
|
||||
<feature
|
||||
id="org.springframework.boot.ide.java.servers.feature" version="0.0.0">
|
||||
<category name="Spring Boot IDE Language Servers for Eclipse" />
|
||||
</feature>
|
||||
|
||||
</site>
|
||||
|
||||
@@ -10,8 +10,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.ui.genericeditor;bundle-version="1.0.0",
|
||||
org.eclipse.jface.text;bundle-version="3.11.100",
|
||||
org.eclipse.jdt.ui;bundle-version="3.13.0",
|
||||
org.eclipse.tm4e.core;bundle-version="1.0.0",
|
||||
org.eclipse.tm4e.ui;bundle-version="1.0.0"
|
||||
org.eclipse.tm4e.core;bundle-version="0.1.0",
|
||||
org.eclipse.tm4e.ui;bundle-version="0.1.0"
|
||||
Import-Package: org.eclipse.jface.preference,
|
||||
org.eclipse.lsp4j.jsonrpc.messages;version="0.1.0.v20170117-0759",
|
||||
org.eclipse.lsp4j.services;version="0.1.0.v20170117-0759",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
bin.includes = feature.xml
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feature
|
||||
id="org.springframework.boot.ide.java.servers.feature"
|
||||
label="Spring Boot IDE Java Editing Language Server Feature"
|
||||
version="4.0.0.qualifier"
|
||||
provider-name="Pivotal, Inc.">
|
||||
|
||||
<requires>
|
||||
<import plugin="org.eclipse.ui.genericeditor"/>
|
||||
<import plugin="org.eclipse.lsp4e"/>
|
||||
</requires>
|
||||
|
||||
<plugin
|
||||
id="org.springframework.boot.ide.java.servers"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false">
|
||||
</plugin>
|
||||
|
||||
</feature>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot.ide</groupId>
|
||||
<artifactId>org.springframework.boot.ide.servers</artifactId>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.springframework.boot.ide.java.servers.feature</artifactId>
|
||||
<packaging>eclipse-feature</packaging>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.springframework.boot.ide.java.servers</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -0,0 +1,21 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Servers
|
||||
Bundle-SymbolicName: org.springframework.boot.ide.java.servers;singleton:=true
|
||||
Bundle-Version: 4.0.0.qualifier
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.core.runtime;bundle-version="3.12.0",
|
||||
org.eclipse.lsp4e;bundle-version="0.1.0",
|
||||
org.eclipse.ui.genericeditor;bundle-version="1.0.0",
|
||||
org.eclipse.jface.text;bundle-version="3.11.100",
|
||||
org.eclipse.jdt.ui;bundle-version="3.13.0",
|
||||
org.eclipse.lsp4j,
|
||||
org.eclipse.ui.workbench,
|
||||
org.eclipse.jface,
|
||||
org.eclipse.xtext.xbase.lib
|
||||
Import-Package: com.google.gson;version="2.7.0",
|
||||
org.eclipse.jface.preference,
|
||||
org.eclipse.lsp4j.jsonrpc.messages;version="0.1.0.v20170117-0759",
|
||||
org.eclipse.lsp4j.services;version="0.1.0.v20170117-0759",
|
||||
org.osgi.framework
|
||||
@@ -0,0 +1,6 @@
|
||||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
plugin.xml,\
|
||||
servers/
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<plugin>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.lsp4e.languageServer">
|
||||
<server
|
||||
class="org.springframework.boot.ide.java.servers.SpringBootJavaLanguageServer"
|
||||
id="org.eclipse.languageserver.languages.springbootjava"
|
||||
label="Spring Boot Java Language Server">
|
||||
</server>
|
||||
<contentTypeMapping
|
||||
contentType="org.eclipse.jdt.core.javaSource"
|
||||
id="org.eclipse.languageserver.languages.springbootjava">
|
||||
</contentTypeMapping>
|
||||
</extension>
|
||||
|
||||
<extension
|
||||
id="springbootjava-completion-computer"
|
||||
point="org.eclipse.jdt.ui.javaCompletionProposalComputer">
|
||||
<javaCompletionProposalComputer
|
||||
activate="true"
|
||||
categoryId="org.eclipse.jdt.ui.defaultProposalCategory"
|
||||
class="org.springframework.boot.ide.java.servers.SpringBootJavaCompletionProposalComputer"
|
||||
needsSortingAfterFiltering="false">
|
||||
</javaCompletionProposalComputer>
|
||||
</extension>
|
||||
<extension
|
||||
id="springbootjava-hover-provider"
|
||||
point="org.eclipse.jdt.ui.javaEditorTextHovers">
|
||||
<hover
|
||||
activate="true"
|
||||
class="org.springframework.boot.ide.java.servers.SpringBootJavaHoverProvider"
|
||||
id="org.springframework.boot.ide.java.servers.hoverprovider">
|
||||
</hover>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot.ide</groupId>
|
||||
<artifactId>org.springframework.boot.ide.servers</artifactId>
|
||||
<version>4.0.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.springframework.boot.ide.java.servers</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>vscode-boot-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.10</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactItems>
|
||||
<artifactItem>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>vscode-boot-java</artifactId>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>${project.build.directory}/../servers</outputDirectory>
|
||||
</artifactItem>
|
||||
</artifactItems>
|
||||
<overWriteReleases>true</overWriteReleases>
|
||||
<overWriteSnapshots>true</overWriteSnapshots>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,20 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.boot.ide.java.servers;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
public static final String PLUGIN_ID = "org.springframework.boot.ide.java.servers";
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.boot.ide.java.servers;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext;
|
||||
import org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer;
|
||||
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||
import org.eclipse.jface.text.contentassist.IContextInformation;
|
||||
import org.eclipse.lsp4e.operations.completion.LSContentAssistProcessor;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class SpringBootJavaCompletionProposalComputer implements IJavaCompletionProposalComputer {
|
||||
|
||||
private LSContentAssistProcessor lsContentAssistProcessor;
|
||||
|
||||
public SpringBootJavaCompletionProposalComputer() {
|
||||
lsContentAssistProcessor = new LSContentAssistProcessor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sessionStarted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICompletionProposal> computeCompletionProposals(ContentAssistInvocationContext context,
|
||||
IProgressMonitor monitor) {
|
||||
System.out.println("Spring Boot Java Completion Proposal - compute completion proposals");
|
||||
|
||||
ICompletionProposal[] proposals = lsContentAssistProcessor.computeCompletionProposals(context.getViewer(), context.getInvocationOffset());
|
||||
return Arrays.asList(proposals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IContextInformation> computeContextInformation(ContentAssistInvocationContext context,
|
||||
IProgressMonitor monitor) {
|
||||
IContextInformation[] contextInformation = lsContentAssistProcessor.computeContextInformation(context.getViewer(), context.getInvocationOffset());
|
||||
return Arrays.asList(contextInformation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return lsContentAssistProcessor.getErrorMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sessionEnded() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.boot.ide.java.servers;
|
||||
|
||||
import org.eclipse.jdt.ui.text.java.hover.IJavaEditorTextHover;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.lsp4e.operations.hover.LSBasedHover;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class SpringBootJavaHoverProvider implements IJavaEditorTextHover {
|
||||
|
||||
private LSBasedHover lsBasedHover;
|
||||
|
||||
public SpringBootJavaHoverProvider() {
|
||||
lsBasedHover = new LSBasedHover();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||
return this.lsBasedHover.getHoverInfo(textViewer, hoverRegion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
|
||||
return this.lsBasedHover.getHoverRegion(textViewer, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEditor(IEditorPart editor) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.boot.ide.java.servers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jdt.internal.launching.StandardVMType;
|
||||
import org.eclipse.jdt.launching.IVMInstall;
|
||||
import org.eclipse.jdt.launching.JavaRuntime;
|
||||
import org.eclipse.jface.action.IStatusLineManager;
|
||||
import org.eclipse.lsp4e.server.ProcessStreamConnectionProvider;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Message;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.NotificationMessage;
|
||||
import org.eclipse.lsp4j.services.LanguageServer;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
public class SpringBootJavaLanguageServer extends ProcessStreamConnectionProvider {
|
||||
|
||||
public SpringBootJavaLanguageServer() {
|
||||
List<String> commands = new ArrayList<>();
|
||||
commands.add(getJDKLocation());
|
||||
|
||||
commands.add("-Xdebug");
|
||||
commands.add("-Xrunjdwp:server=y,transport=dt_socket,address=4000,suspend=n");
|
||||
|
||||
commands.add("-jar");
|
||||
commands.add(getLanguageServerJARLocation());
|
||||
|
||||
String workingDir = getWorkingDirLocation();
|
||||
|
||||
setCommands(commands);
|
||||
setWorkingDirectory(workingDir);
|
||||
}
|
||||
|
||||
public void handleMessage(Message message, LanguageServer languageServer, String rootPath) {
|
||||
if (message instanceof NotificationMessage) {
|
||||
NotificationMessage notificationMessage = (NotificationMessage) message;
|
||||
if ("sts/progress".equals(notificationMessage.getMethod())) {
|
||||
JsonObject params = (JsonObject) notificationMessage.getParams();
|
||||
String status = params.has("statusMsg") ? params.get("statusMsg").getAsString() : "";
|
||||
showStatusMessage(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showStatusMessage(final String status) {
|
||||
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IStatusLineManager statusLineManager = getStatusLineManager();
|
||||
if (statusLineManager != null) {
|
||||
statusLineManager.setMessage(status);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private IStatusLineManager getStatusLineManager() {
|
||||
try {
|
||||
return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor().getEditorSite().getActionBars().getStatusLineManager();
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getJDKLocation() {
|
||||
IVMInstall jdk = JavaRuntime.getDefaultVMInstall();
|
||||
File javaExecutable = StandardVMType.findJavaExecutable(jdk.getInstallLocation());
|
||||
return javaExecutable.getAbsolutePath();
|
||||
}
|
||||
|
||||
protected String getLanguageServerJARLocation() {
|
||||
String languageServer = "vscode-boot-java-0.0.1-SNAPSHOT.jar";
|
||||
|
||||
Bundle bundle = Platform.getBundle(Constants.PLUGIN_ID);
|
||||
File dataFile = bundle.getDataFile(languageServer);
|
||||
// if (!dataFile.exists()) {
|
||||
try {
|
||||
copyLanguageServerJAR(languageServer);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// }
|
||||
|
||||
return dataFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
protected String getWorkingDirLocation() {
|
||||
// TODO: identify a reasonable working directory for the language server process
|
||||
return System.getProperty("user.dir");
|
||||
}
|
||||
|
||||
protected void copyLanguageServerJAR(String languageServerJarName) throws Exception {
|
||||
Bundle bundle = Platform.getBundle(Constants.PLUGIN_ID);
|
||||
InputStream stream = FileLocator.openStream( bundle, new Path("servers/" + languageServerJarName), false );
|
||||
|
||||
File dataFile = bundle.getDataFile(languageServerJarName);
|
||||
Files.copy(stream, dataFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,8 +10,8 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.9.0",
|
||||
org.eclipse.ui.genericeditor;bundle-version="1.0.0",
|
||||
org.eclipse.jface.text;bundle-version="3.11.100",
|
||||
org.eclipse.jdt.ui;bundle-version="3.13.0",
|
||||
org.eclipse.tm4e.core;bundle-version="1.0.0",
|
||||
org.eclipse.tm4e.ui;bundle-version="1.0.0",
|
||||
org.eclipse.tm4e.core;bundle-version="0.1.0",
|
||||
org.eclipse.tm4e.ui;bundle-version="0.1.0",
|
||||
org.eclipse.lsp4j,
|
||||
org.eclipse.ui.workbench,
|
||||
org.eclipse.jface
|
||||
|
||||
@@ -94,14 +94,14 @@ public class SpringBootPropertiesLanguageServer extends ProcessStreamConnectionP
|
||||
|
||||
Bundle bundle = Platform.getBundle(Constants.PLUGIN_ID);
|
||||
File dataFile = bundle.getDataFile(languageServer);
|
||||
if (!dataFile.exists()) {
|
||||
// if (!dataFile.exists()) {
|
||||
try {
|
||||
copyLanguageServerJAR(languageServer);
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
return dataFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
<category name="Spring Boot IDE Language Servers for Eclipse"/>
|
||||
</feature>
|
||||
|
||||
<feature id="org.springframework.boot.ide.java.servers.feature">
|
||||
<category name="Spring Boot IDE Language Servers for Eclipse"/>
|
||||
</feature>
|
||||
|
||||
<category-def name="deps" label="Dependencies"/>
|
||||
|
||||
<feature id="tm-feature">
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
<module>org.springframework.boot.ide.properties.servers</module>
|
||||
<module>org.springframework.boot.ide.properties.servers.feature</module>
|
||||
|
||||
<module>org.springframework.boot.ide.java.servers</module>
|
||||
<module>org.springframework.boot.ide.java.servers.feature</module>
|
||||
|
||||
<module>org.springframework.boot.ide.cloudfoundry.server</module>
|
||||
<module>org.springframework.boot.ide.cloudfoundry.server.feature</module>
|
||||
|
||||
@@ -81,6 +84,11 @@
|
||||
<layout>p2</layout>
|
||||
<url>http://download.eclipse.org/tools/orbit/downloads/drops/S20161205183421/repository/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>lsp4j-snapshots</id>
|
||||
<layout>p2</layout>
|
||||
<url>http://services.typefox.io/open-source/jenkins/job/lsp4j/job/master/lastStableBuild/artifact/build/p2-repository/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>lsp4e</id>
|
||||
<layout>p2</layout>
|
||||
@@ -89,7 +97,7 @@
|
||||
<repository>
|
||||
<id>tm4e</id>
|
||||
<layout>p2</layout>
|
||||
<url>http://oss.opensagres.fr/textmate/1.0.0-SNAPSHOT/</url>
|
||||
<url>http://oss.opensagres.fr/textmate/0.1.0-SNAPSHOT/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
public interface CFDomain {
|
||||
|
||||
String getName();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client;
|
||||
|
||||
class CFDomainImpl implements CFDomain {
|
||||
|
||||
private final String name;
|
||||
|
||||
public CFDomainImpl(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CFDomainImpl other = (CFDomainImpl) obj;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -29,4 +29,7 @@ public class CFEntities {
|
||||
/* dasboard Url */ null);
|
||||
}
|
||||
|
||||
public static CFDomain createDomain(String name) {
|
||||
return new CFDomainImpl(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,6 @@ public interface ClientRequests {
|
||||
|
||||
List<CFBuildpack> getBuildpacks() throws Exception;
|
||||
List<CFServiceInstance> getServices() throws Exception;
|
||||
List<CFDomain> getDomains() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFDomain;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.ClientRequests;
|
||||
|
||||
@@ -37,15 +38,21 @@ public class CFTarget {
|
||||
/*
|
||||
* Cached information
|
||||
*/
|
||||
private final LoadingCache<String, List<CFBuildpack>> buildpacksCache;
|
||||
private final LoadingCache<String, List<CFServiceInstance>> servicesCache;
|
||||
private LoadingCache<String, List<CFBuildpack>> buildpacksCache;
|
||||
private LoadingCache<String, List<CFServiceInstance>> servicesCache;
|
||||
private LoadingCache<String, List<CFDomain>> domainCache;
|
||||
private CFCallableContext callableContext;
|
||||
|
||||
public CFTarget(String targetName, CFClientParams params, ClientRequests requests, CFCallableContext callableContext) {
|
||||
public CFTarget(String targetName, CFClientParams params, ClientRequests requests,
|
||||
CFCallableContext callableContext) {
|
||||
this.params = params;
|
||||
this.requests = requests;
|
||||
this.targetName = targetName;
|
||||
this.callableContext = callableContext;
|
||||
initCache(requests);
|
||||
}
|
||||
|
||||
private void initCache(ClientRequests requests) {
|
||||
CacheLoader<String, List<CFServiceInstance>> servicesLoader = new CacheLoader<String, List<CFServiceInstance>>() {
|
||||
|
||||
@Override
|
||||
@@ -71,12 +78,23 @@ public class CFTarget {
|
||||
};
|
||||
this.buildpacksCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(CFTargetCache.TARGET_EXPIRATION, TimeUnit.HOURS).build(buildpacksLoader);
|
||||
|
||||
CacheLoader<String, List<CFDomain>> domainLoader = new CacheLoader<String, List<CFDomain>>() {
|
||||
|
||||
@Override
|
||||
public List<CFDomain> load(String key) throws Exception {
|
||||
return runAndCheckForFailure(() -> requests.getDomains());
|
||||
}
|
||||
|
||||
};
|
||||
this.domainCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(CFTargetCache.TARGET_EXPIRATION, TimeUnit.HOURS).build(domainLoader);
|
||||
}
|
||||
|
||||
|
||||
protected <T> T runAndCheckForFailure(Callable<T> callable) throws Exception {
|
||||
return callableContext.checkConnection(callable);
|
||||
}
|
||||
|
||||
|
||||
public boolean hasConnectionError() {
|
||||
return callableContext.hasConnectionError();
|
||||
}
|
||||
@@ -102,6 +120,11 @@ public class CFTarget {
|
||||
String key = getName();
|
||||
return this.servicesCache.get(key);
|
||||
}
|
||||
|
||||
public List<CFDomain> getDomains() throws Exception {
|
||||
String key = getName();
|
||||
return this.domainCache.get(key);
|
||||
}
|
||||
|
||||
public ClientRequests getClientRequests() {
|
||||
return requests;
|
||||
|
||||
@@ -11,10 +11,11 @@
|
||||
package org.springframework.ide.vscode.commons.cloudfoundry.client.v2;
|
||||
|
||||
import org.cloudfoundry.operations.buildpacks.Buildpack;
|
||||
import org.cloudfoundry.operations.services.ServiceInstance;
|
||||
import org.cloudfoundry.operations.domains.Domain;
|
||||
import org.cloudfoundry.operations.services.ServiceInstanceSummary;
|
||||
import org.cloudfoundry.operations.services.ServiceInstanceType;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFDomain;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFEntities;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
|
||||
|
||||
@@ -32,6 +33,11 @@ public class CFWrappingV2 {
|
||||
return CFEntities.createBuildpack(name);
|
||||
}
|
||||
|
||||
public static CFDomain wrap(Domain domain) {
|
||||
String name = domain.getName();
|
||||
return CFEntities.createDomain(name);
|
||||
}
|
||||
|
||||
public static CFServiceInstance wrap(ServiceInstanceSummary serviceInstance) {
|
||||
String name = serviceInstance.getName();
|
||||
String plan = serviceInstance.getPlan();
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.cloudfoundry.client.CloudFoundryClient;
|
||||
import org.cloudfoundry.operations.CloudFoundryOperations;
|
||||
import org.cloudfoundry.operations.DefaultCloudFoundryOperations;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFBuildpack;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFDomain;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.ClientRequests;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.ClientTimeouts;
|
||||
@@ -82,7 +83,22 @@ public class DefaultClientRequestsV2 implements ClientRequests {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CFDomain> getDomains() throws Exception {
|
||||
|
||||
return ReactorUtils.get(timeouts.getBuildpacksTimeout(), CancelationTokens.NULL,
|
||||
log("operations.domains.list",
|
||||
_operations
|
||||
.domains()
|
||||
.list()
|
||||
.map(CFWrappingV2::wrap)
|
||||
.collectList()
|
||||
.map(ImmutableList::copyOf)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CFBuildpack> getBuildpacks() throws Exception {
|
||||
return ReactorUtils.get(timeouts.getBuildpacksTimeout(), CancelationTokens.NULL,
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.concurrent.Callable;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFParamsProviderMessages;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTarget;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTargetCache;
|
||||
@@ -28,6 +29,8 @@ import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.Conne
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.NoTargetsException;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class CFClientTest {
|
||||
|
||||
MockCfCli cloudfoundry = new MockCfCli();
|
||||
@@ -70,6 +73,62 @@ public class CFClientTest {
|
||||
CFTarget target = targetCache.getOrCreate().get(0);
|
||||
assertError(() -> target.getBuildpacks(), ConnectionException.class, expectedMessages.noNetworkConnection());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnknownHostDomains() throws Exception {
|
||||
ClientRequests client = cloudfoundry.client;
|
||||
when(client.getDomains()).thenThrow(new UnknownHostException("api.run.pivotal.io"));
|
||||
CFTarget target = targetCache.getOrCreate().get(0);
|
||||
assertError(() -> target.getDomains(), ConnectionException.class, expectedMessages.noNetworkConnection());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildpacksFromTarget() throws Exception {
|
||||
ClientRequests client = cloudfoundry.client;
|
||||
CFBuildpack buildpack = Mockito.mock(CFBuildpack.class);
|
||||
when(buildpack.getName()).thenReturn("java_buildpack");
|
||||
when(client.getBuildpacks()).thenReturn(ImmutableList.of(buildpack));
|
||||
|
||||
CFTarget target = targetCache.getOrCreate().get(0);
|
||||
assertEquals("java_buildpack", target.getBuildpacks().get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDomainsFromTarget() throws Exception {
|
||||
ClientRequests client = cloudfoundry.client;
|
||||
CFDomain domain = Mockito.mock(CFDomain.class);
|
||||
when(domain.getName()).thenReturn("cfapps.io");
|
||||
when(client.getDomains()).thenReturn(ImmutableList.of(domain));
|
||||
|
||||
CFTarget target = targetCache.getOrCreate().get(0);
|
||||
assertEquals("cfapps.io", target.getDomains().get(0).getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServicesFromTarget() throws Exception {
|
||||
ClientRequests client = cloudfoundry.client;
|
||||
CFServiceInstance service = Mockito.mock(CFServiceInstance.class);
|
||||
when(service.getName()).thenReturn("appdb");
|
||||
when(service.getPlan()).thenReturn("spark");
|
||||
when(service.getService()).thenReturn("cleardb");
|
||||
|
||||
when(client.getServices()).thenReturn(ImmutableList.of(service));
|
||||
|
||||
CFTarget target = targetCache.getOrCreate().get(0);
|
||||
assertEquals("appdb", target.getServices().get(0).getName());
|
||||
assertEquals("spark", target.getServices().get(0).getPlan());
|
||||
assertEquals("cleardb", target.getServices().get(0).getService());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoServicesFromTarget() throws Exception {
|
||||
ClientRequests client = cloudfoundry.client;
|
||||
|
||||
when(client.getServices()).thenReturn(ImmutableList.of());
|
||||
|
||||
CFTarget target = targetCache.getOrCreate().get(0);
|
||||
assertTrue(target.getServices().isEmpty());
|
||||
}
|
||||
|
||||
protected void assertError(Callable<?> callable, Class<? extends Throwable> expected, String expectedMessage)
|
||||
throws Exception {
|
||||
|
||||
36
vscode-extensions/commons/commons-gradle/.classpath
Normal file
36
vscode-extensions/commons/commons-gradle/.classpath
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
vscode-extensions/commons/commons-gradle/.project
Normal file
23
vscode-extensions/commons/commons-gradle/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>commons-gradle</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,6 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF-8
|
||||
encoding//src/main/resources=UTF-8
|
||||
encoding//src/test/java=UTF-8
|
||||
encoding//src/test/resources=UTF-8
|
||||
encoding/<project>=UTF-8
|
||||
@@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -0,0 +1,4 @@
|
||||
activeProfiles=
|
||||
eclipse.preferences.version=1
|
||||
resolveWorkspaceProjects=true
|
||||
version=1
|
||||
41
vscode-extensions/commons/commons-gradle/pom.xml
Normal file
41
vscode-extensions/commons/commons-gradle/pom.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>commons-gradle</artifactId>
|
||||
<name>commons-gradle</name>
|
||||
<description>Gradle Utilities</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<gradle-tooling.version>3.3</gradle-tooling.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>gradle-repo</id>
|
||||
<name>Gradle Tooling Repo</name>
|
||||
<url>https://repo.gradle.org/gradle/libs-releases</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-java</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.gradle</groupId>
|
||||
<artifactId>gradle-tooling-api</artifactId>
|
||||
<version>${gradle-tooling.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,78 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.gradle.tooling.GradleConnectionException;
|
||||
import org.gradle.tooling.GradleConnector;
|
||||
import org.gradle.tooling.ProjectConnection;
|
||||
import org.gradle.tooling.model.build.BuildEnvironment;
|
||||
import org.gradle.tooling.model.eclipse.EclipseProject;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
|
||||
/**
|
||||
* Gradle API tooling utility
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleCore {
|
||||
|
||||
@FunctionalInterface
|
||||
public interface GradleConfiguration {
|
||||
void configure(GradleConnector connector);
|
||||
}
|
||||
|
||||
public interface GradleCoreProject {
|
||||
EclipseProject getProject();
|
||||
BuildEnvironment getBuildEnvironment();
|
||||
}
|
||||
|
||||
static final String GRADLE_BUILD_FILE = "build.gradle";
|
||||
|
||||
private static GradleCore defaultInstance = null;
|
||||
|
||||
public static GradleCore getDefault() {
|
||||
if (defaultInstance == null) {
|
||||
defaultInstance = new GradleCore();
|
||||
}
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
private GradleConfiguration configuration;
|
||||
|
||||
public GradleCore() {
|
||||
this.configuration = (connector) -> {};
|
||||
}
|
||||
|
||||
public GradleCore(GradleConfiguration configuration) {
|
||||
Assert.isNotNull(configuration);
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public <T> T getModel(File projectDir, Class<T> modelType) throws GradleException {
|
||||
ProjectConnection connection = null;
|
||||
try {
|
||||
GradleConnector gradleConnector = GradleConnector.newConnector().forProjectDirectory(projectDir);
|
||||
configuration.configure(gradleConnector);
|
||||
connection = gradleConnector.connect();
|
||||
return connection.getModel(modelType);
|
||||
} catch (GradleConnectionException e) {
|
||||
throw new GradleException(e);
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Gradle wrapper exception
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 7958309594787399714L;
|
||||
|
||||
private Throwable[] t;
|
||||
|
||||
public GradleException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public GradleException(Throwable... t) {
|
||||
super();
|
||||
this.t = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
if (t != null) {
|
||||
return String.join("\n", Arrays.stream(t).map(t -> t.getMessage()).collect(Collectors.toList()));
|
||||
}
|
||||
return super.getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
/**
|
||||
* Implementation of Gradle Java project
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleJavaProject implements IJavaProject {
|
||||
|
||||
private GradleProjectClasspath classpath;
|
||||
|
||||
public GradleJavaProject(GradleCore gradle, File projectDir) throws GradleException {
|
||||
this.classpath = new GradleProjectClasspath(gradle, projectDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GradleProjectClasspath getClasspath() {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.gradle.tooling.model.build.BuildEnvironment;
|
||||
import org.gradle.tooling.model.eclipse.EclipseProject;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexClasspath;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexIndex;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.parser.ParserJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.HtmlJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.SourceUrlProviderFromSourceContainer;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
/**
|
||||
* Implementation of {@link IClasspath} for Gradle projects
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleProjectClasspath extends JandexClasspath {
|
||||
|
||||
private static final String JAVA_HOME = "java.home";
|
||||
private static final String JAVA_RUNTIME_VERSION = "java.runtime.version";
|
||||
private static final String JAVA_BOOT_CLASS_PATH = "sun.boot.class.path";
|
||||
|
||||
private EclipseProject gradleProject;
|
||||
private Supplier<BuildEnvironment> buildEnvironment;
|
||||
|
||||
public GradleProjectClasspath(GradleCore gradle, File projectDir) throws GradleException {
|
||||
super();
|
||||
this.gradleProject = gradle.getModel(projectDir, EclipseProject.class);
|
||||
this.buildEnvironment = Suppliers.memoize(() -> {
|
||||
try {
|
||||
return gradle.getModel(projectDir, BuildEnvironment.class);
|
||||
} catch (GradleException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JandexIndex[] getBaseIndices() {
|
||||
return new JandexIndex[] { new JandexIndex(getJreLibs().map(path -> path.toFile()).collect(Collectors.toList()),
|
||||
jarFile -> findIndexFile(jarFile), (classpathResource) -> {
|
||||
try {
|
||||
String javaVersion = getJavaRuntimeMinorVersion();
|
||||
if (javaVersion == null) {
|
||||
javaVersion = "8";
|
||||
}
|
||||
URL javadocUrl = new URL("http://docs.oracle.com/javase/" + javaVersion + "/docs/api/");
|
||||
return new HtmlJavadocProvider(
|
||||
(type) -> SourceUrlProviderFromSourceContainer.JAVADOC_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(javadocUrl, type));
|
||||
} catch (MalformedURLException e) {
|
||||
Log.log(e);
|
||||
return null;
|
||||
}
|
||||
}) };
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<Path> getClasspathEntries() throws Exception {
|
||||
return Stream.concat(gradleProject.getClasspath().stream().map(dep -> dep.getFile().toPath()),
|
||||
gradleProject.getProjectDependencies().stream().map(project -> new File(project.getPath()).toPath()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getClasspathResources() {
|
||||
return gradleProject.getSourceDirectories().stream().map(sourceDirectory -> sourceDirectory.getDirectory()).flatMap(folder -> {
|
||||
try {
|
||||
return Files.walk(folder.toPath())
|
||||
.filter(path -> Files.isRegularFile(path))
|
||||
.map(path -> folder.toPath().relativize(path))
|
||||
.map(relativePath -> relativePath.toString())
|
||||
.filter(pathString -> !pathString.endsWith(".java") && !pathString.endsWith(".class"));
|
||||
} catch (IOException e) {
|
||||
return Stream.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Path getOutputFolder() {
|
||||
return gradleProject.getProjectDirectory().toPath().resolve(gradleProject.getOutputLocation().getPath());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return gradleProject.getName();
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
return gradleProject != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IJavadocProvider createParserJavadocProvider(File classpathResource) {
|
||||
if (classpathResource.isDirectory()) {
|
||||
Optional<File> classpathFolder = gradleProject.getSourceDirectories().stream()
|
||||
.map(dir -> dir.getDirectory())
|
||||
.filter(dir -> classpathResource.toPath().startsWith(dir.toPath()))
|
||||
.findFirst();
|
||||
if (classpathFolder.isPresent()) {
|
||||
return new ParserJavadocProvider(type -> {
|
||||
return SourceUrlProviderFromSourceContainer.SOURCE_FOLDER_URL_SUPPLIER
|
||||
.sourceUrl(classpathFolder.get().toURI().toURL(), type);
|
||||
});
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IJavadocProvider createHtmlJavdocProvider(File classpathResource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getGradleVersion() throws GradleException {
|
||||
if (buildEnvironment.get() == null) {
|
||||
throw new GradleException(new Exception("Cannot find Gradle version"));
|
||||
} else {
|
||||
return buildEnvironment.get().getGradle().getGradleVersion();
|
||||
}
|
||||
}
|
||||
|
||||
public File getGradleHome() throws GradleException {
|
||||
if (buildEnvironment.get() == null) {
|
||||
throw new GradleException(new Exception("Cannot find Gradle home folder"));
|
||||
} else {
|
||||
return buildEnvironment.get().getGradle().getGradleUserHome();
|
||||
}
|
||||
}
|
||||
|
||||
public String getJavaRuntimeVersion() {
|
||||
return System.getProperty(JAVA_RUNTIME_VERSION);
|
||||
}
|
||||
|
||||
public String getJavaRuntimeMinorVersion() {
|
||||
String fullVersion = getJavaRuntimeVersion();
|
||||
String[] tokenized = fullVersion.split("\\.");
|
||||
if (tokenized.length > 1) {
|
||||
return tokenized[1];
|
||||
} else {
|
||||
Log.log("Cannot determine minor version for the Java Runtime Version: " + fullVersion);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getJavaHome() {
|
||||
if (buildEnvironment.get() == null) {
|
||||
return System.getProperty(JAVA_HOME);
|
||||
} else {
|
||||
return buildEnvironment.get().getJava().getJavaHome().toString();
|
||||
}
|
||||
}
|
||||
|
||||
private Stream<Path> getJreLibs() {
|
||||
String s = System.getProperty(JAVA_BOOT_CLASS_PATH);
|
||||
return Arrays.stream(s.split(File.pathSeparator))
|
||||
.map(strPath -> strPath.replace(System.getProperty(JAVA_HOME), getJavaHome()))
|
||||
.map(File::new)
|
||||
.filter(f -> f.canRead())
|
||||
.map(f -> f.toPath());
|
||||
}
|
||||
|
||||
private File findIndexFile(File jarFile) {
|
||||
String suffix = null;
|
||||
String javaHome = getJavaHome();
|
||||
if (javaHome != null) {
|
||||
int index = javaHome.lastIndexOf('/');
|
||||
if (index != -1) {
|
||||
javaHome = javaHome.substring(0, index);
|
||||
}
|
||||
}
|
||||
if (jarFile.toString().startsWith(javaHome)) {
|
||||
suffix = getJavaRuntimeVersion();
|
||||
}
|
||||
return new File(JandexIndex.getIndexFolder().toString(), jarFile.getName() + "-" + suffix + ".jdx");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.IJavaProjectFinderStrategy;
|
||||
import org.springframework.ide.vscode.commons.util.FileUtils;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* Tests whether document belongs to a Gradle project
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleProjectFinderStrategy implements IJavaProjectFinderStrategy {
|
||||
|
||||
private Cache<File, GradleJavaProject> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
private GradleCore gradle;
|
||||
|
||||
public GradleProjectFinderStrategy(GradleCore gradle) {
|
||||
this.gradle = gradle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GradleJavaProject find(IDocument d) throws ExecutionException, URISyntaxException {
|
||||
String uriStr = d.getUri();
|
||||
if (StringUtil.hasText(uriStr)) {
|
||||
URI uri = new URI(uriStr);
|
||||
// TODO: This only work with File uri. Should it work with others
|
||||
// too?
|
||||
if (uri.getScheme().equalsIgnoreCase("file")) {
|
||||
File file = new File(uri).getAbsoluteFile();
|
||||
File gradlebuild = FileUtils.findFile(file, GradleCore.GRADLE_BUILD_FILE);
|
||||
if (gradlebuild != null) {
|
||||
return cache.get(gradlebuild.getParentFile(), () -> {
|
||||
return new GradleJavaProject(gradle, gradlebuild.getParentFile());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.gradle;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests covering Gradle project data
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class GradleProjectTest {
|
||||
|
||||
private GradleJavaProject getGradleProject(String projectName) throws Exception {
|
||||
Path testProjectPath = Paths.get(GradleProjectTest.class.getResource("/" + projectName).toURI());
|
||||
return new GradleJavaProject(GradleCore.getDefault(), testProjectPath.toFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEclipseGradleProject() throws Exception {
|
||||
GradleJavaProject project = getGradleProject("empty-gradle-project");
|
||||
Set<Path> calculatedClassPath = project.getClasspath().getClasspathEntries().collect(Collectors.toSet());
|
||||
assertEquals(48, calculatedClassPath.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputFolder() throws Exception {
|
||||
GradleJavaProject project = getGradleProject("test-app-1");
|
||||
assertTrue(project.getClasspath().getOutputFolder().endsWith("bin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void gradleClasspathResource() throws Exception {
|
||||
GradleJavaProject project = getGradleProject("test-app-1");
|
||||
List<String> resources = project.getClasspath().getClasspathResources().collect(Collectors.toList());
|
||||
assertArrayEquals(new String[] {"test-resource-1.txt"}, resources.toArray(new String[resources.size()]));
|
||||
}
|
||||
|
||||
}
|
||||
25
vscode-extensions/commons/commons-gradle/src/test/resources/empty-gradle-project/.gitignore
vendored
Normal file
25
vscode-extensions/commons/commons-gradle/src/test/resources/empty-gradle-project/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
.gradle
|
||||
/build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
@@ -0,0 +1,33 @@
|
||||
buildscript {
|
||||
ext {
|
||||
springBootVersion = '1.5.1.RELEASE'
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'org.springframework.boot'
|
||||
|
||||
jar {
|
||||
baseName = 'empty-boot-1.4.0-web-app'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
compile('org.springframework.boot:spring-boot-starter-actuator')
|
||||
compile('org.springframework.boot:spring-boot-starter-web')
|
||||
testCompile('org.springframework.boot:spring-boot-starter-test')
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip
|
||||
164
vscode-extensions/commons/commons-gradle/src/test/resources/empty-gradle-project/gradlew
vendored
Executable file
164
vscode-extensions/commons/commons-gradle/src/test/resources/empty-gradle-project/gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
vscode-extensions/commons/commons-gradle/src/test/resources/empty-gradle-project/gradlew.bat
vendored
Normal file
90
vscode-extensions/commons/commons-gradle/src/test/resources/empty-gradle-project/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.example;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class EmptyGradleProjectApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(EmptyGradleProjectApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.example;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class EmptyGradleProjectApplicationTests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This build file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* This generated file contains a sample Java project to get you started.
|
||||
* For more details take a look at the Java Quickstart chapter in the Gradle
|
||||
* user guide available at https://docs.gradle.org/3.3/userguide/tutorial_java_projects.html
|
||||
*/
|
||||
|
||||
// Apply the java plugin to add support for Java
|
||||
apply plugin: 'java'
|
||||
|
||||
// In this section you declare where to find the dependencies of your project
|
||||
repositories {
|
||||
// Use jcenter for resolving your dependencies.
|
||||
// You can declare any Maven/Ivy/file repository here.
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// The production code uses Guava
|
||||
compile 'com.google.guava:guava:20.0'
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '1.5.1.RELEASE'
|
||||
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.1.RELEASE'
|
||||
|
||||
// Use JUnit test framework
|
||||
testCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#Tue Feb 07 11:31:46 EST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip
|
||||
172
vscode-extensions/commons/commons-gradle/src/test/resources/test-app-1/gradlew
vendored
Executable file
172
vscode-extensions/commons/commons-gradle/src/test/resources/test-app-1/gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save ( ) {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
84
vscode-extensions/commons/commons-gradle/src/test/resources/test-app-1/gradlew.bat
vendored
Normal file
84
vscode-extensions/commons/commons-gradle/src/test/resources/test-app-1/gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* This settings file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
* In a single project build this file can be empty or even removed.
|
||||
*
|
||||
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||
* in the user guide at https://docs.gradle.org/3.3/userguide/multi_project_builds.html
|
||||
*/
|
||||
|
||||
/*
|
||||
// To declare projects as part of a multi-project build use the 'include' method
|
||||
include 'shared'
|
||||
include 'api'
|
||||
include 'services:webservice'
|
||||
*/
|
||||
|
||||
rootProject.name = 'test-app-1'
|
||||
//org.gradle.java.home = '/Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home'
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
public class Library {
|
||||
public boolean someLibraryMethod() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class LibraryTest {
|
||||
@Test public void testSomeLibraryMethod() {
|
||||
Library classUnderTest = new Library();
|
||||
assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Some text
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.springframework.ide.vscode.commons.jandex;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
public abstract class JandexClasspath implements IClasspath {
|
||||
|
||||
public static JavadocProviderTypes providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
public enum JavadocProviderTypes {
|
||||
JAVA_PARSER,
|
||||
HTML
|
||||
}
|
||||
|
||||
private Supplier<JandexIndex> javaIndex;
|
||||
|
||||
public JandexClasspath() {
|
||||
this.javaIndex = Suppliers.memoize(() -> createIndex());
|
||||
}
|
||||
|
||||
protected JandexIndex createIndex() {
|
||||
Stream<Path> classpathEntries = Stream.empty();
|
||||
try {
|
||||
classpathEntries = getClasspathEntries();
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return new JandexIndex(classpathEntries.map(p -> p.toFile()).collect(Collectors.toList()), jarFile -> findIndexFile(jarFile), classpathResource -> {
|
||||
switch (providerType) {
|
||||
case JAVA_PARSER:
|
||||
return createParserJavadocProvider(classpathResource);
|
||||
default:
|
||||
return createHtmlJavdocProvider(classpathResource);
|
||||
}
|
||||
}, getBaseIndices());
|
||||
}
|
||||
|
||||
protected JandexIndex[] getBaseIndices() {
|
||||
return new JandexIndex[0];
|
||||
}
|
||||
|
||||
public IType findType(String fqName) {
|
||||
return javaIndex.get().findType(fqName);
|
||||
}
|
||||
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter) {
|
||||
return javaIndex.get().fuzzySearchTypes(searchTerm, typeFilter);
|
||||
}
|
||||
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return javaIndex.get().fuzzySearchPackages(searchTerm);
|
||||
}
|
||||
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return javaIndex.get().allSubtypesOf(type);
|
||||
}
|
||||
|
||||
private File findIndexFile(File jarFile) {
|
||||
File indexFolder = getIndexFolder();
|
||||
if (indexFolder == null) {
|
||||
return null;
|
||||
}
|
||||
return new File(indexFolder.toString(), jarFile.getName() + "-" + jarFile.lastModified() + ".jdx");
|
||||
}
|
||||
|
||||
protected File getIndexFolder() {
|
||||
return JandexIndex.getIndexFolder();
|
||||
}
|
||||
|
||||
abstract protected IJavadocProvider createParserJavadocProvider(File classpathResource);
|
||||
|
||||
abstract protected IJavadocProvider createHtmlJavdocProvider(File classpathResource);
|
||||
|
||||
}
|
||||
@@ -54,19 +54,29 @@ import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
public class JandexIndex {
|
||||
|
||||
|
||||
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface IndexFileFinder {
|
||||
File findIndexFile(File jarFile);
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public static interface JavadocProviderFactory {
|
||||
IJavadocProvider createJavadocProvider(File jarContainer);
|
||||
}
|
||||
|
||||
|
||||
public static File getIndexFolder() {
|
||||
File folder = new File(System.getProperty(JAVA_IO_TMPDIR), "jandex");
|
||||
if (!folder.isDirectory()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
private static final IJavadocProvider ABSENT_JAVADOC_PROVIDER = new IJavadocProvider() {
|
||||
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavadoc(IType type) {
|
||||
return null;
|
||||
@@ -86,30 +96,31 @@ public class JandexIndex {
|
||||
public IJavadoc getJavadoc(IAnnotation method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
private Map<File, Supplier<Optional<IndexView>>> index;
|
||||
|
||||
|
||||
private JavadocProviderFactory javadocProviderFactory;
|
||||
|
||||
|
||||
private Map<File, Supplier<List<Tuple2<String, IType>>>> knownTypes;
|
||||
|
||||
|
||||
private Map<File, Supplier<List<String>>> knownPackages;
|
||||
|
||||
|
||||
private Cache<File, IJavadocProvider> javadocProvidersCache = CacheBuilder.newBuilder().build();
|
||||
|
||||
private JandexIndex[] baseIndex;
|
||||
|
||||
|
||||
public void setJvadocProviderFactory(JavadocProviderFactory sourceContainerProvider) {
|
||||
this.javadocProviderFactory = sourceContainerProvider;
|
||||
}
|
||||
|
||||
|
||||
public JavadocProviderFactory getJavadocProviderFactory() {
|
||||
return javadocProviderFactory;
|
||||
}
|
||||
|
||||
public JandexIndex(Collection<File> classpathEntries, IndexFileFinder indexFileFinder, JavadocProviderFactory javadocProviderFactory, JandexIndex... baseIndex) {
|
||||
|
||||
public JandexIndex(Collection<File> classpathEntries, IndexFileFinder indexFileFinder,
|
||||
JavadocProviderFactory javadocProviderFactory, JandexIndex... baseIndex) {
|
||||
this.baseIndex = baseIndex;
|
||||
this.index = new ConcurrentHashMap<>();
|
||||
this.knownTypes = new HashMap<>();
|
||||
@@ -121,186 +132,185 @@ public class JandexIndex {
|
||||
knownPackages.put(file, Suppliers.memoize(() -> getKnownPackages(file).collect(Collectors.toList())));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private Optional<IndexView> createIndex(File file, IndexFileFinder indexFileFinder) {
|
||||
if (file.isFile() && file.getName().endsWith(".jar")) {
|
||||
if (file != null && file.isFile() && file.getName().endsWith(".jar")) {
|
||||
return indexJar(file, indexFileFinder);
|
||||
} else if (file.isDirectory()) {
|
||||
} else if (file != null && file.isDirectory()) {
|
||||
return indexFolder(file);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static Optional<IndexView> indexFolder(File folder) {
|
||||
Indexer indexer = new Indexer();
|
||||
for (Iterator<File> itr = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder).iterator(); itr.hasNext();) {
|
||||
for (Iterator<File> itr = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder)
|
||||
.iterator(); itr.hasNext();) {
|
||||
File file = itr.next();
|
||||
if (file.isFile() && file.getName().endsWith(".class")) {
|
||||
try {
|
||||
final InputStream stream = new FileInputStream(file);
|
||||
try {
|
||||
indexer.index(stream);
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
try {
|
||||
final InputStream stream = new FileInputStream(file);
|
||||
try {
|
||||
indexer.index(stream);
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.of(indexer.complete());
|
||||
}
|
||||
|
||||
|
||||
private static Optional<IndexView> indexJar(File file, IndexFileFinder indexFileFinder) {
|
||||
File indexFile = indexFileFinder.findIndexFile(file);
|
||||
if (indexFile != null) {
|
||||
try {
|
||||
if (indexFile.createNewFile()) {
|
||||
try {
|
||||
return Optional.of(JarIndexer
|
||||
.createJarIndex(file, new Indexer(), indexFile,
|
||||
false, false, false, System.out, System.err)
|
||||
.getIndex());
|
||||
} catch (IOException e) {
|
||||
Log.log("Failed to index '" + file + "'", e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return Optional.of(new IndexReader(new FileInputStream(indexFile)).read());
|
||||
} catch (IOException e) {
|
||||
Log.log("Failed to read index file '" + indexFile + "'. Creating new index file.", e);
|
||||
if (indexFile.delete()) {
|
||||
return indexJar(file, indexFileFinder);
|
||||
} else {
|
||||
Log.log("Failed to read index file '" + indexFile);
|
||||
}
|
||||
File indexFile = indexFileFinder.findIndexFile(file);
|
||||
if (indexFile != null) {
|
||||
try {
|
||||
if (indexFile.createNewFile()) {
|
||||
try {
|
||||
return Optional.of(JarIndexer.createJarIndex(file, new Indexer(), indexFile, false, false,
|
||||
false, System.out, System.err).getIndex());
|
||||
} catch (IOException e) {
|
||||
Log.log("Failed to index '" + file + "'", e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return Optional.of(new IndexReader(new FileInputStream(indexFile)).read());
|
||||
} catch (IOException e) {
|
||||
Log.log("Failed to read index file '" + indexFile + "'. Creating new index file.", e);
|
||||
if (indexFile.delete()) {
|
||||
return indexJar(file, indexFileFinder);
|
||||
} else {
|
||||
Log.log("Failed to read index file '" + indexFile);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.log("Unable to create index file '" + indexFile +"'");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return Optional.of(JarIndexer
|
||||
.createJarIndex(file, new Indexer(), file.canWrite(), file.getParentFile().canWrite(), false)
|
||||
.getIndex());
|
||||
} catch (IOException e) {
|
||||
Log.log("Failed to index '" + file + "'", e);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.log("Unable to create index file '" + indexFile + "'");
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return Optional.of(JarIndexer
|
||||
.createJarIndex(file, new Indexer(), file.canWrite(), file.getParentFile().canWrite(), false)
|
||||
.getIndex());
|
||||
} catch (IOException e) {
|
||||
Log.log("Failed to index '" + file + "'", e);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public IType findType(String fqName) {
|
||||
return getClassByName(DotName.createSimple(fqName));
|
||||
}
|
||||
|
||||
|
||||
IType getClassByName(DotName fqName) {
|
||||
// First look for type in the base index array
|
||||
return (baseIndex == null ? Stream.<IType>empty()
|
||||
: Arrays.stream(baseIndex)
|
||||
.filter(jandexIndex -> jandexIndex != null)
|
||||
.map(jandexIndex -> jandexIndex.getClassByName(fqName)))
|
||||
.filter(type -> type != null)
|
||||
.findFirst()
|
||||
// If not found look at indices owned by this JandexIndex instance
|
||||
.orElseGet(() -> streamOfIndices()
|
||||
.map(e -> Tuples.of(e.getT1(), e.getT2().getClassByName(fqName)))
|
||||
.filter(e -> e.getT2() != null)
|
||||
.map(e -> createType(e))
|
||||
.findFirst()
|
||||
.orElse(null));
|
||||
|
||||
: Arrays.stream(
|
||||
baseIndex)
|
||||
.filter(
|
||||
jandexIndex -> jandexIndex != null)
|
||||
.map(jandexIndex -> jandexIndex.getClassByName(fqName))).filter(type -> type != null)
|
||||
.findFirst()
|
||||
// If not found look at indices owned by this
|
||||
// JandexIndex instance
|
||||
.orElseGet(() -> streamOfIndices()
|
||||
.map(e -> Tuples.of(e.getT1(), e.getT2().getClassByName(fqName)))
|
||||
.filter(e -> e.getT2() != null).map(e -> createType(e)).findFirst()
|
||||
.orElse(null));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private IType createType(Tuple2<File, ClassInfo> match) {
|
||||
File classpathResource = match.getT1();
|
||||
IJavadocProvider javadocProvider = null;
|
||||
try {
|
||||
javadocProvider = javadocProvidersCache.get(classpathResource, () -> javadocProviderFactory == null ? ABSENT_JAVADOC_PROVIDER : javadocProviderFactory.createJavadocProvider(classpathResource));
|
||||
javadocProvider = javadocProvidersCache.get(classpathResource, () -> {
|
||||
IJavadocProvider provider = null;
|
||||
if (javadocProviderFactory != null) {
|
||||
provider = javadocProviderFactory.createJavadocProvider(classpathResource);
|
||||
}
|
||||
return provider == null ? ABSENT_JAVADOC_PROVIDER : provider;
|
||||
});
|
||||
} catch (ExecutionException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return Wrappers.wrap(this, match.getT2(), javadocProvider);
|
||||
return Wrappers.wrap(this, match.getT2(), javadocProvider);
|
||||
}
|
||||
|
||||
|
||||
private Stream<Tuple2<File, IndexView>> streamOfIndices() {
|
||||
return index.entrySet().parallelStream().map(e -> Tuples.of(e.getKey(), e.getValue().get())).filter(t -> t.getT2().isPresent()).map(t -> Tuples.of(t.getT1(), t.getT2().get()));
|
||||
return index.entrySet().parallelStream().map(e -> Tuples.of(e.getKey(), e.getValue().get()))
|
||||
.filter(t -> t.getT2().isPresent()).map(t -> Tuples.of(t.getT1(), t.getT2().get()));
|
||||
}
|
||||
|
||||
|
||||
private Stream<Tuple2<String, IType>> getKnownTypesStream(File file) {
|
||||
Optional<IndexView> indexView = index.get(file).get();
|
||||
if (indexView.isPresent()) {
|
||||
return indexView.get().getKnownClasses().parallelStream().map(info -> Tuples.of(info.name().toString(), createType(Tuples.of(file, info))));
|
||||
return indexView.get().getKnownClasses().parallelStream()
|
||||
.map(info -> Tuples.of(info.name().toString(), createType(Tuples.of(file, info))));
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
|
||||
private Stream<String> getKnownPackages(File file) {
|
||||
Optional<IndexView> indexView = index.get(file).get();
|
||||
if (indexView.isPresent()) {
|
||||
return indexView.get()
|
||||
.getKnownClasses()
|
||||
.parallelStream()
|
||||
.map(info -> {
|
||||
String name = info.name().toString();
|
||||
return name.substring(0, name.lastIndexOf('.'));
|
||||
})
|
||||
.distinct();
|
||||
return indexView.get().getKnownClasses().parallelStream().map(info -> {
|
||||
String name = info.name().toString();
|
||||
return name.substring(0, name.lastIndexOf('.'));
|
||||
}).distinct();
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter) {
|
||||
Flux<Tuple2<IType, Double>> flux = Flux.fromIterable(knownTypes.values())
|
||||
.publishOn(Schedulers.parallel())
|
||||
.flatMap(s -> Flux.fromIterable(s.get()))
|
||||
.filter(t -> typeFilter == null || typeFilter.test(t.getT2()))
|
||||
Flux<Tuple2<IType, Double>> flux = Flux.fromIterable(knownTypes.values()).publishOn(Schedulers.parallel())
|
||||
.flatMap(s -> Flux.fromIterable(s.get())).filter(t -> typeFilter == null || typeFilter.test(t.getT2()))
|
||||
.map(t -> Tuples.of(t.getT2(), FuzzyMatcher.matchScore(searchTerm, t.getT1())))
|
||||
.filter(t -> t.getT2() != 0.0);
|
||||
if (baseIndex == null) {
|
||||
return flux;
|
||||
} else {
|
||||
return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchTypes(searchTerm, typeFilter)));
|
||||
return Flux.merge(flux,
|
||||
Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchTypes(searchTerm, typeFilter)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
Flux<Tuple2<String, Double>> flux = Flux.fromIterable(knownPackages.values())
|
||||
.publishOn(Schedulers.parallel())
|
||||
Flux<Tuple2<String, Double>> flux = Flux.fromIterable(knownPackages.values()).publishOn(Schedulers.parallel())
|
||||
.flatMap(s -> Flux.fromIterable(s.get()))
|
||||
.map(pkg -> Tuples.of(pkg, FuzzyMatcher.matchScore(searchTerm, pkg)))
|
||||
.filter(t -> t.getT2() != 0.0);
|
||||
.map(pkg -> Tuples.of(pkg, FuzzyMatcher.matchScore(searchTerm, pkg))).filter(t -> t.getT2() != 0.0);
|
||||
if (baseIndex == null) {
|
||||
return flux;
|
||||
} else {
|
||||
return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchPackages(searchTerm)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
DotName name = DotName.createSimple(type.getFullyQualifiedName());
|
||||
Flux<IType> flux = Flux.fromIterable(index.keySet())
|
||||
.publishOn(Schedulers.parallel())
|
||||
.flatMap(file -> {
|
||||
Optional<IndexView> optional = index.get(file).get();
|
||||
if (optional.isPresent()) {
|
||||
return Flux.fromIterable(type.isInterface() ? optional.get().getAllKnownImplementors(name) : optional.get().getAllKnownSubclasses(name))
|
||||
.publishOn(Schedulers.parallel())
|
||||
.map(info -> createType(Tuples.of(file, info)));
|
||||
} else {
|
||||
return Flux.empty();
|
||||
}
|
||||
});
|
||||
Flux<IType> flux = Flux.fromIterable(index.keySet()).publishOn(Schedulers.parallel()).flatMap(file -> {
|
||||
Optional<IndexView> optional = index.get(file).get();
|
||||
if (optional.isPresent()) {
|
||||
return Flux
|
||||
.fromIterable(type.isInterface() ? optional.get().getAllKnownImplementors(name)
|
||||
: optional.get().getAllKnownSubclasses(name))
|
||||
.publishOn(Schedulers.parallel()).map(info -> createType(Tuples.of(file, info)));
|
||||
} else {
|
||||
return Flux.empty();
|
||||
}
|
||||
});
|
||||
if (baseIndex == null) {
|
||||
return flux;
|
||||
} else {
|
||||
return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.allSubtypesOf(type)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
/**
|
||||
* Classpath for a Java artifact
|
||||
*
|
||||
@@ -21,7 +25,21 @@ import java.util.stream.Stream;
|
||||
*
|
||||
*/
|
||||
public interface IClasspath {
|
||||
|
||||
String getName();
|
||||
|
||||
boolean exists();
|
||||
|
||||
IType findType(String fqName);
|
||||
|
||||
Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter);
|
||||
|
||||
Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm);
|
||||
|
||||
Flux<IType> allSubtypesOf(IType type);
|
||||
|
||||
Path getOutputFolder();
|
||||
|
||||
/**
|
||||
* Classpath entries paths
|
||||
*
|
||||
|
||||
@@ -10,20 +10,25 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
|
||||
public interface IJavaProject extends IJavaElement {
|
||||
|
||||
IType findType(String fqName);
|
||||
|
||||
Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter);
|
||||
|
||||
Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm);
|
||||
|
||||
Flux<IType> allSubtypesOf(IType type);
|
||||
|
||||
IClasspath getClasspath();
|
||||
|
||||
@Override
|
||||
default String getElementName() {
|
||||
return getClasspath().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
default IJavadoc getJavaDoc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean exists() {
|
||||
return getClasspath().exists();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
@@ -37,7 +37,6 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcil
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemSeverity;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Futures;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -118,14 +117,14 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Object> shutdown() {
|
||||
return Futures.of(null);
|
||||
return CompletableFuture.completedFuture(new Object());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit() {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
|
||||
public Path getWorkspaceRoot() {
|
||||
return workspaceRoot;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ public class MavenCore {
|
||||
private static final String CLASSIFIER_TESTS = "tests";
|
||||
private static final String CLASSIFIER_TESTSOURCES = "test-sources";
|
||||
|
||||
public static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
|
||||
private static final String JAVA_HOME = "java.home";
|
||||
private static final String JAVA_RUNTIME_VERSION = "java.runtime.version";
|
||||
private static final String JAVA_BOOT_CLASS_PATH = "sun.boot.class.path";
|
||||
@@ -336,18 +335,11 @@ public class MavenCore {
|
||||
} catch (MavenException e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return new File(getIndexFolder().toString(), jarFile.getName() + "-" + suffix + ".jdx");
|
||||
return new File(JandexIndex.getIndexFolder().toString(), jarFile.getName() + "-" + suffix + ".jdx");
|
||||
}
|
||||
|
||||
public JandexIndex getJavaIndexForJreLibs() {
|
||||
return javaCoreIndex.get();
|
||||
}
|
||||
|
||||
public File getIndexFolder() {
|
||||
File folder = new File(System.getProperty(JAVA_IO_TMPDIR), "jandex");
|
||||
if (!folder.isDirectory()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,13 @@ import com.google.common.cache.CacheBuilder;
|
||||
*/
|
||||
public class MavenProjectFinderStrategy implements IJavaProjectFinderStrategy {
|
||||
|
||||
public Cache<File, MavenJavaProject> cache = CacheBuilder.newBuilder().build();
|
||||
private Cache<File, MavenJavaProject> cache = CacheBuilder.newBuilder().build();
|
||||
|
||||
private MavenCore maven;
|
||||
|
||||
public MavenProjectFinderStrategy(MavenCore maven) {
|
||||
this.maven = maven;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MavenJavaProject find(IDocument d) throws ExecutionException, URISyntaxException {
|
||||
@@ -46,7 +52,7 @@ public class MavenProjectFinderStrategy implements IJavaProjectFinderStrategy {
|
||||
File pomFile = FileUtils.findFile(file, MavenCore.POM_XML);
|
||||
if (pomFile != null) {
|
||||
return cache.get(pomFile, () -> {
|
||||
return new MavenJavaProject(pomFile);
|
||||
return new MavenJavaProject(maven, pomFile);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,18 +11,10 @@
|
||||
package org.springframework.ide.vscode.commons.maven.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
/**
|
||||
* Wrapper for Maven Core project
|
||||
*
|
||||
@@ -32,46 +24,9 @@ import reactor.util.function.Tuple2;
|
||||
public class MavenJavaProject implements IJavaProject {
|
||||
|
||||
private MavenProjectClasspath classpath;
|
||||
private MavenCore maven;
|
||||
|
||||
public MavenJavaProject(File pom) {
|
||||
this.maven = MavenCore.getDefault();
|
||||
this.classpath = new MavenProjectClasspath(pom, maven);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return classpath.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavaDoc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return classpath.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
return classpath.findType(fqName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter) {
|
||||
return classpath.fuzzySearchType(searchTerm, typeFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return classpath.fuzzySearchPackages(searchTerm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return classpath.allSubtypesOf(type);
|
||||
public MavenJavaProject(MavenCore maven, File pom) {
|
||||
this.classpath = new MavenProjectClasspath(maven, pom);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,8 +34,4 @@ public class MavenJavaProject implements IJavaProject {
|
||||
return classpath;
|
||||
}
|
||||
|
||||
public Path getOutputFolder() {
|
||||
return Paths.get(new File(classpath.getOutputFolder()).toURI());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,17 +19,14 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.codehaus.plexus.util.DirectoryScanner;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexClasspath;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexIndex;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.java.parser.ParserJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.HtmlJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.javadoc.SourceUrlProviderFromSourceContainer;
|
||||
@@ -40,58 +37,30 @@ import org.springframework.ide.vscode.commons.util.Log;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
/**
|
||||
* Classpath for a maven project
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class MavenProjectClasspath implements IClasspath {
|
||||
|
||||
public static JavadocProviderTypes providerType = JavadocProviderTypes.HTML;
|
||||
|
||||
public enum JavadocProviderTypes {
|
||||
JAVA_PARSER,
|
||||
// ROASTER,
|
||||
HTML
|
||||
}
|
||||
public class MavenProjectClasspath extends JandexClasspath {
|
||||
|
||||
private MavenCore maven;
|
||||
private File pom;
|
||||
private Supplier<MavenProject> projectSupplier;
|
||||
private Supplier<JandexIndex> javaIndex;
|
||||
|
||||
public MavenProjectClasspath(File pom) {
|
||||
this(pom, MavenCore.getDefault());
|
||||
}
|
||||
|
||||
MavenProjectClasspath(File pom, MavenCore maven) {
|
||||
MavenProjectClasspath(MavenCore maven, File pom) {
|
||||
super();
|
||||
this.maven = maven;
|
||||
this.pom = pom;
|
||||
this.projectSupplier = Suppliers.memoize(() -> createMavenProject());
|
||||
this.javaIndex = Suppliers.memoize(() -> {
|
||||
Stream<Path> classpathEntries = Stream.empty();
|
||||
try {
|
||||
classpathEntries = getClasspathEntries();
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return new JandexIndex(classpathEntries.map(p -> p.toFile()).collect(Collectors.toList()), jarFile -> findIndexFile(jarFile), classpathResource -> {
|
||||
switch (providerType) {
|
||||
case JAVA_PARSER:
|
||||
return createParserJavadocProvider(classpathResource);
|
||||
// case ROASTER:
|
||||
// return createRoasterJavadocProvider(classpathResource);
|
||||
default:
|
||||
return createHtmlJavdocProvider(classpathResource);
|
||||
}
|
||||
}, maven.getJavaIndexForJreLibs());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JandexIndex[] getBaseIndices() {
|
||||
return new JandexIndex[] { maven.getJavaIndexForJreLibs() };
|
||||
}
|
||||
|
||||
private final MavenProject createMavenProject() {
|
||||
try {
|
||||
// Read with resolved dependencies
|
||||
@@ -139,29 +108,9 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
}
|
||||
}
|
||||
|
||||
public String getOutputFolder() {
|
||||
public Path getOutputFolder() {
|
||||
MavenProject project = projectSupplier.get();
|
||||
return project == null ? null : project.getBuild().getOutputDirectory();
|
||||
}
|
||||
|
||||
public IType findType(String fqName) {
|
||||
return javaIndex.get().findType(fqName);
|
||||
}
|
||||
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchType(String searchTerm, Predicate<IType> typeFilter) {
|
||||
return javaIndex.get().fuzzySearchTypes(searchTerm, typeFilter);
|
||||
}
|
||||
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return javaIndex.get().fuzzySearchPackages(searchTerm);
|
||||
}
|
||||
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return javaIndex.get().allSubtypesOf(type);
|
||||
}
|
||||
|
||||
private File findIndexFile(File jarFile) {
|
||||
return new File(maven.getIndexFolder().toString(), jarFile.getName() + "-" + jarFile.lastModified() + ".jdx");
|
||||
return project == null ? null : new File(project.getBuild().getOutputDirectory()).toPath();
|
||||
}
|
||||
|
||||
private Optional<Artifact> getArtifactFromJarFile(File file) throws MavenException {
|
||||
@@ -226,7 +175,7 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
// }
|
||||
// }
|
||||
|
||||
private IJavadocProvider createParserJavadocProvider(File classpathResource) {
|
||||
protected IJavadocProvider createParserJavadocProvider(File classpathResource) {
|
||||
MavenProject project = projectSupplier.get();
|
||||
if (project == null) {
|
||||
return null;
|
||||
@@ -263,7 +212,7 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
}
|
||||
}
|
||||
|
||||
private IJavadocProvider createHtmlJavdocProvider(File classpathResource) {
|
||||
protected IJavadocProvider createHtmlJavdocProvider(File classpathResource) {
|
||||
MavenProject project = projectSupplier.get();
|
||||
if (project == null) {
|
||||
return null;
|
||||
|
||||
@@ -10,12 +10,18 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.maven.java.classpathfile;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
/**
|
||||
* Classpath for a project containing classpath text file
|
||||
*
|
||||
@@ -41,5 +47,41 @@ public class FileClasspath implements IClasspath {
|
||||
public Stream<String> getClasspathResources() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return classpathFilePath.toFile().getParentFile().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return Files.exists(classpathFilePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
//TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getOutputFolder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,15 +12,9 @@ package org.springframework.ide.vscode.commons.maven.java.classpathfile;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
/**
|
||||
* Java project that contains classpath text file
|
||||
@@ -38,42 +32,6 @@ public class JavaProjectWithClasspathFile implements IJavaProject {
|
||||
this.classpath = new FileClasspath(Paths.get(cpFile.toURI()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return cpFile.getParentFile().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJavadoc getJavaDoc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return cpFile.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
//TODO: implement
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<IType, Double>> fuzzySearchTypes(String searchTerm, Predicate<IType> typeFilter) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<IType> allSubtypesOf(IType type) {
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClasspath getClasspath() {
|
||||
return classpath;
|
||||
|
||||
@@ -21,13 +21,13 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexClasspath;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexClasspath.JavadocProviderTypes;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectClasspath;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectClasspath.JavadocProviderTypes;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
@@ -37,10 +37,10 @@ public class HtmlJavadocTest {
|
||||
private static Supplier<MavenJavaProject> projectSupplier = Suppliers.memoize(() -> {
|
||||
Path testProjectPath;
|
||||
try {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
JandexClasspath.providerType = JavadocProviderTypes.HTML;
|
||||
testProjectPath = Paths.get(HtmlJavadocTest.class.getResource("/gs-rest-service-cors-boot-1.4.1-with-classpath-file").toURI());
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().javadoc().skipTests().execute();
|
||||
return new MavenJavaProject(testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
return new MavenJavaProject(MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public class HtmlJavadocTest {
|
||||
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("java.util.Map");
|
||||
IType type = project.getClasspath().findType("java.util.Map");
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
"<div class=\"block\">An object that maps keys to values. A map cannot contain duplicate keys;",
|
||||
@@ -68,7 +68,7 @@ public class HtmlJavadocTest {
|
||||
Assume.assumeTrue(javaVersionHigherThan(6));
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
IType type = project.getClasspath().findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod method = type.getMethod("<init>", Stream.empty());
|
||||
assertNotNull(method);
|
||||
@@ -86,7 +86,7 @@ public class HtmlJavadocTest {
|
||||
public void html_testEmptyJavadocClass() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("hello.Application");
|
||||
IType type = project.getClasspath().findType("hello.Application");
|
||||
assertNotNull(type);
|
||||
assertNull(type.getJavaDoc());
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public class HtmlJavadocTest {
|
||||
public void html_testFieldAndMethodJavadocForJar() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("org.springframework.boot.SpringApplication");
|
||||
IType type = project.getClasspath().findType("org.springframework.boot.SpringApplication");
|
||||
assertNotNull(type);
|
||||
|
||||
IField field = type.getField("BANNER_LOCATION_PROPERTY_VALUE");
|
||||
@@ -135,7 +135,7 @@ public class HtmlJavadocTest {
|
||||
public void html_testInnerClassJavadocForOutputFolder() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("hello.Greeting$TestInnerClass");
|
||||
IType type = project.getClasspath().findType("hello.Greeting$TestInnerClass");
|
||||
assertNotNull(type);
|
||||
IJavadoc javaDoc = type.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
@@ -168,7 +168,7 @@ public class HtmlJavadocTest {
|
||||
public void html_testInnerClassLevel2_JavadocForOutputFolder() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("hello.Greeting$TestInnerClass$TestInnerClassLevel2");
|
||||
IType type = project.getClasspath().findType("hello.Greeting$TestInnerClass$TestInnerClassLevel2");
|
||||
assertNotNull(type);
|
||||
IJavadoc javaDoc = type.getJavaDoc();
|
||||
assertNotNull(javaDoc);
|
||||
@@ -200,7 +200,7 @@ public class HtmlJavadocTest {
|
||||
@Test
|
||||
public void html_testJavadocOutputFolder() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
IType type = project.findType("hello.Greeting");
|
||||
IType type = project.getClasspath().findType("hello.Greeting");
|
||||
|
||||
assertNotNull(type);
|
||||
String expected = "<div class=\"block\">Comment for Greeting class</div>";
|
||||
@@ -237,7 +237,7 @@ public class HtmlJavadocTest {
|
||||
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
IType type = project.getClasspath().findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod method = type.getMethod("size", Stream.empty());
|
||||
assertNotNull(method);
|
||||
@@ -258,7 +258,7 @@ public class HtmlJavadocTest {
|
||||
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("java.util.Map$Entry");
|
||||
IType type = project.getClasspath().findType("java.util.Map$Entry");
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
"<div class=\"block\">A map entry (key-value pair). The <tt>Map.entrySet</tt> method returns",
|
||||
@@ -272,7 +272,7 @@ public class HtmlJavadocTest {
|
||||
public void html_testNoJavadocClass() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();;
|
||||
|
||||
IType type = project.findType("hello.GreetingController");
|
||||
IType type = project.getClasspath().findType("hello.GreetingController");
|
||||
assertNotNull(type);
|
||||
assertNull(type.getJavaDoc());
|
||||
}
|
||||
@@ -281,7 +281,7 @@ public class HtmlJavadocTest {
|
||||
public void html_testNoJavadocField() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("hello.GreetingController");
|
||||
IType type = project.getClasspath().findType("hello.GreetingController");
|
||||
assertNotNull(type);
|
||||
IField field = type.getField("template");
|
||||
assertNotNull(field);
|
||||
@@ -302,7 +302,7 @@ public class HtmlJavadocTest {
|
||||
public void html_testNoJavadocMethod() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("hello.Application");
|
||||
IType type = project.getClasspath().findType("hello.Application");
|
||||
assertNotNull(type);
|
||||
IMethod method = type.getMethod("corsConfigurer", Stream.empty());
|
||||
assertNotNull(method);
|
||||
|
||||
@@ -45,7 +45,7 @@ public class JavaIndexTest {
|
||||
public MavenJavaProject load(String projectName) throws Exception {
|
||||
Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/" + projectName).toURI());
|
||||
MavenBuilder.newBuilder(testProjectPath).clean().pack().javadoc().skipTests().execute();
|
||||
return new MavenJavaProject(testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
return new MavenJavaProject(MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
}
|
||||
|
||||
});
|
||||
@@ -83,28 +83,28 @@ public class JavaIndexTest {
|
||||
@Test
|
||||
public void findClassInJar() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("org.springframework.test.web.client.ExpectedCount");
|
||||
IType type = project.getClasspath().findType("org.springframework.test.web.client.ExpectedCount");
|
||||
assertNotNull(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findClassInOutputFolder() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("hello.Greeting");
|
||||
IType type = project.getClasspath().findType("hello.Greeting");
|
||||
assertNotNull(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classNotFound() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("hello.NonExistentClass");
|
||||
IType type = project.getClasspath().findType("hello.NonExistentClass");
|
||||
assertNull(type);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void voidMethodNoParams() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
IType type = project.getClasspath().findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod m = type.getMethod("clear", Stream.empty());
|
||||
assertEquals("clear", m.getElementName());
|
||||
@@ -115,7 +115,7 @@ public class JavaIndexTest {
|
||||
@Test
|
||||
public void voidConstructor() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
IType type = project.getClasspath().findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod m = type.getMethod("<init>", Stream.empty());
|
||||
assertEquals(type.getElementName(), m.getElementName());
|
||||
@@ -126,7 +126,7 @@ public class JavaIndexTest {
|
||||
@Test
|
||||
public void constructorMethodWithParams() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
IType type = project.findType("java.util.ArrayList");
|
||||
IType type = project.getClasspath().findType("java.util.ArrayList");
|
||||
assertNotNull(type);
|
||||
IMethod m = type.getMethod("<init>", Stream.of(IPrimitiveType.INT));
|
||||
assertEquals(m.getDeclaringType().getElementName(), m.getElementName());
|
||||
|
||||
@@ -19,12 +19,12 @@ import java.nio.file.Paths;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexClasspath;
|
||||
import org.springframework.ide.vscode.commons.jandex.JandexClasspath.JavadocProviderTypes;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectClasspath;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenProjectClasspath.JavadocProviderTypes;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
@@ -34,9 +34,9 @@ public class SourceJavadocTest {
|
||||
private static Supplier<MavenJavaProject> projectSupplier = Suppliers.memoize(() -> {
|
||||
Path testProjectPath;
|
||||
try {
|
||||
MavenProjectClasspath.providerType = JavadocProviderTypes.JAVA_PARSER;
|
||||
JandexClasspath.providerType = JavadocProviderTypes.JAVA_PARSER;
|
||||
testProjectPath = Paths.get(SourceJavadocTest.class.getResource("/gs-rest-service-cors-boot-1.4.1-with-classpath-file").toURI());
|
||||
return new MavenJavaProject(testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
return new MavenJavaProject(MavenCore.getDefault(), testProjectPath.resolve(MavenCore.POM_XML).toFile());
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public class SourceJavadocTest {
|
||||
public void parser_testClassJavadocForJar() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener");
|
||||
IType type = project.getClasspath().findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener");
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
"/**",
|
||||
@@ -54,7 +54,7 @@ public class SourceJavadocTest {
|
||||
);
|
||||
assertEquals(expected, type.getJavaDoc().raw().trim().substring(0, expected.length()));
|
||||
|
||||
type = project.findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener$LiquibasePresent");
|
||||
type = project.getClasspath().findType("org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener$LiquibasePresent");
|
||||
assertNotNull(type);
|
||||
expected = String.join("\n",
|
||||
"/**",
|
||||
@@ -67,7 +67,7 @@ public class SourceJavadocTest {
|
||||
@Test
|
||||
public void parser_testClassJavadocForOutputFolder() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
IType type = project.findType("hello.Greeting");
|
||||
IType type = project.getClasspath().findType("hello.Greeting");
|
||||
|
||||
assertNotNull(type);
|
||||
String expected = String.join("\n",
|
||||
@@ -100,7 +100,7 @@ public class SourceJavadocTest {
|
||||
public void parser_testFieldAndMethodJavadocForJar() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
|
||||
IType type = project.findType("org.springframework.boot.SpringApplication");
|
||||
IType type = project.getClasspath().findType("org.springframework.boot.SpringApplication");
|
||||
assertNotNull(type);
|
||||
|
||||
IField field = type.getField("BANNER_LOCATION_PROPERTY_VALUE");
|
||||
@@ -124,7 +124,7 @@ public class SourceJavadocTest {
|
||||
@Test
|
||||
public void parser_testInnerClassJavadocForOutputFolder() throws Exception {
|
||||
MavenJavaProject project = projectSupplier.get();
|
||||
IType type = project.findType("hello.Greeting$TestInnerClass");
|
||||
IType type = project.getClasspath().findType("hello.Greeting$TestInnerClass");
|
||||
assertNotNull(type);
|
||||
assertEquals("/**\n * Comment for inner class\n */", type.getJavaDoc().raw().trim());
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.metadata.util;
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -8,18 +8,17 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.metadata;
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.metadata.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.boot.metadata.util.FuzzyMap.Match;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap.Match;
|
||||
|
||||
public class FuzzyMapTest {
|
||||
|
||||
@@ -302,6 +302,7 @@ public class LanguageServerHarness {
|
||||
TextDocumentPositionParams params = new TextDocumentPositionParams();
|
||||
params.setPosition(cursor);
|
||||
params.setTextDocument(doc.getId());
|
||||
server.waitForReconcile();
|
||||
return server.getTextDocumentService().completion(params).get();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
<module>java-properties</module>
|
||||
<module>commons-cf</module>
|
||||
<module>commons-maven</module>
|
||||
|
||||
|
||||
<module>commons-gradle</module>
|
||||
</modules>
|
||||
|
||||
<repositories>
|
||||
@@ -73,13 +72,13 @@
|
||||
<yaml-version>1.17</yaml-version>
|
||||
<junit-version>4.11</junit-version>
|
||||
<assertj-version>3.5.2</assertj-version>
|
||||
<slf4j-version>1.7.21</slf4j-version>
|
||||
<slf4j-version>1.7.22</slf4j-version>
|
||||
<guava-version>19.0</guava-version>
|
||||
<jackson-2-version>2.5.0</jackson-2-version>
|
||||
<jersey-2-version>2.10</jersey-2-version>
|
||||
<lsp4j-version>0.1.0</lsp4j-version>
|
||||
<!-- NOTE: Reactor version must match version used by the CF client -->
|
||||
<reactor-version>3.0.4.RELEASE</reactor-version>
|
||||
<reactor-version>3.0.5.RELEASE</reactor-version>
|
||||
<reactor-netty>0.6.0.RELEASE</reactor-netty>
|
||||
<cloudfoundry-client-version>2.4.0.BUILD-SNAPSHOT</cloudfoundry-client-version>
|
||||
</properties>
|
||||
|
||||
@@ -19,7 +19,7 @@ export function activate(context: VSCode.ExtensionContext) {
|
||||
|
||||
let options: commons.ActivatorOptions = {
|
||||
DEBUG: false,
|
||||
CONNECT_TO_LS: true,
|
||||
CONNECT_TO_LS: false,
|
||||
extensionId: 'vscode-boot-java',
|
||||
fatJarFile: 'target/vscode-boot-java-0.0.1-SNAPSHOT.jar',
|
||||
clientOptions: {
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>vscode-boot-java</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../commons/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
<repositories>
|
||||
<!-- Sonatype snapshots repository -->
|
||||
<repository>
|
||||
@@ -23,7 +23,7 @@
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>distribution-repository</id>
|
||||
@@ -31,19 +31,24 @@
|
||||
<url>file://${basedir}/dist</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-maven</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-gradle</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<artifactId>commons-language-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- Eclipse JDT for parsing (at the moment) -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jdt</groupId>
|
||||
@@ -57,6 +62,12 @@
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-metadata</artifactId>
|
||||
<version>1.5.1.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test harness -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
@@ -64,7 +75,7 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
@@ -102,6 +113,6 @@
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -15,15 +15,21 @@ import org.eclipse.lsp4j.ServerCapabilities;
|
||||
import org.eclipse.lsp4j.TextDocumentSyncKind;
|
||||
import org.springframework.ide.vscode.boot.java.completions.BootJavaCompletionEngine;
|
||||
import org.springframework.ide.vscode.boot.java.completions.BootJavaReconcileEngine;
|
||||
import org.springframework.ide.vscode.boot.java.hover.BootJavaHoverProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleCore;
|
||||
import org.springframework.ide.vscode.commons.gradle.GradleProjectFinderStrategy;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.DefaultJavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.IJavaProjectFinderStrategy;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.maven.JavaProjectWithClasspathFileFinderStrategy;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenProjectFinderStrategy;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
@@ -35,15 +41,14 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
|
||||
public static final JavaProjectFinder DEFAULT_PROJECT_FINDER = new DefaultJavaProjectFinder(new IJavaProjectFinderStrategy[] {
|
||||
new MavenProjectFinderStrategy(),
|
||||
new MavenProjectFinderStrategy(MavenCore.getDefault()),
|
||||
new GradleProjectFinderStrategy(GradleCore.getDefault()),
|
||||
new JavaProjectWithClasspathFileFinderStrategy()
|
||||
});
|
||||
|
||||
private final JavaProjectFinder javaProjectFinder;
|
||||
private final VscodeCompletionEngineAdapter completionEngine;
|
||||
|
||||
public BootJavaLanguageServer(JavaProjectFinder javaProjectFinder) {
|
||||
this.javaProjectFinder = javaProjectFinder;
|
||||
public BootJavaLanguageServer(JavaProjectFinder javaProjectFinder, SpringPropertyIndexProvider indexProvider) {
|
||||
SimpleTextDocumentService documents = getTextDocumentService();
|
||||
|
||||
IReconcileEngine reconcileEngine = new BootJavaReconcileEngine();
|
||||
@@ -52,11 +57,14 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
validateWith(doc, reconcileEngine);
|
||||
});
|
||||
|
||||
ICompletionEngine bootCompletionEngine = new BootJavaCompletionEngine(javaProjectFinder);
|
||||
ICompletionEngine bootCompletionEngine = new BootJavaCompletionEngine(javaProjectFinder, indexProvider);
|
||||
completionEngine = new VscodeCompletionEngineAdapter(this, bootCompletionEngine);
|
||||
completionEngine.setMaxCompletionsNumber(100);
|
||||
documents.onCompletion(completionEngine::getCompletions);
|
||||
documents.onCompletionResolve(completionEngine::resolveCompletion);
|
||||
|
||||
HoverHandler hoverInfoProvider = new BootJavaHoverProvider(this, javaProjectFinder);
|
||||
documents.onHover(hoverInfoProvider);
|
||||
}
|
||||
|
||||
public void setMaxCompletionsNumber(int number) {
|
||||
@@ -71,6 +79,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
|
||||
CompletionOptions completionProvider = new CompletionOptions();
|
||||
completionProvider.setResolveProvider(false);
|
||||
c.setCompletionProvider(completionProvider);
|
||||
c.setHoverProvider(true);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.java;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.ide.vscode.boot.metadata.DefaultSpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
@@ -26,7 +27,8 @@ public class Main {
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
LaunguageServerApp.start(() -> {
|
||||
JavaProjectFinder javaProjectFinder = BootJavaLanguageServer.DEFAULT_PROJECT_FINDER;
|
||||
SimpleLanguageServer server = new BootJavaLanguageServer(javaProjectFinder);
|
||||
DefaultSpringPropertyIndexProvider indexProvider = new DefaultSpringPropertyIndexProvider(javaProjectFinder);
|
||||
SimpleLanguageServer server = new BootJavaLanguageServer(javaProjectFinder, indexProvider);
|
||||
return server;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.NodeFinder;
|
||||
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
@@ -38,11 +39,14 @@ import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
|
||||
private static final String SPRING_SCOPE = "org.springframework.context.annotation.Scope";
|
||||
private static final String SPRING_VALUE = "org.springframework.beans.factory.annotation.Value";
|
||||
|
||||
private JavaProjectFinder projectFinder;
|
||||
private SpringPropertyIndexProvider indexProvider;
|
||||
|
||||
public BootJavaCompletionEngine(JavaProjectFinder projectFinder) {
|
||||
public BootJavaCompletionEngine(JavaProjectFinder projectFinder, SpringPropertyIndexProvider indexProvider) {
|
||||
this.projectFinder = projectFinder;
|
||||
this.indexProvider = indexProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,6 +109,9 @@ public class BootJavaCompletionEngine implements ICompletionEngine {
|
||||
if (type.getQualifiedName().equals(SPRING_SCOPE)) {
|
||||
new ScopeCompletionProcessor().collectCompletionsForScopeAnnotation(node, annotation, type, completions, offset, doc);
|
||||
}
|
||||
else if (type.getQualifiedName().equals(SPRING_VALUE)) {
|
||||
new ValueCompletionProcessor(indexProvider.getIndex(doc)).collectCompletionsForValueAnnotation(node, annotation, type, completions, offset, doc);
|
||||
}
|
||||
}
|
||||
|
||||
private String[] getClasspathEntries(IDocument doc) throws Exception {
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.completions;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.util.StringUtil.camelCaseToHyphens;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap.Match;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class ValueCompletionProcessor {
|
||||
|
||||
private FuzzyMap<ConfigurationMetadataProperty> index;
|
||||
|
||||
public ValueCompletionProcessor(FuzzyMap<ConfigurationMetadataProperty> index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void collectCompletionsForValueAnnotation(ASTNode node, Annotation annotation, ITypeBinding type,
|
||||
List<ICompletionProposal> completions, int offset, IDocument doc) {
|
||||
|
||||
try {
|
||||
// case: @Value(<*>)
|
||||
if (node == annotation && doc.get(offset - 1, 2).endsWith("()")) {
|
||||
List<Match<ConfigurationMetadataProperty>> matches = findMatches("");
|
||||
|
||||
for (Match<ConfigurationMetadataProperty> match : matches) {
|
||||
|
||||
DocumentEdits edits = new DocumentEdits(doc);
|
||||
edits.replace(offset, offset, "\"${" + match.data.getId() + "}\"");
|
||||
|
||||
ValuePropertyKeyProposal proposal = new ValuePropertyKeyProposal(edits, match.data.getId(), match.data.getName(), null);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
// case: @Value(prefix<*>)
|
||||
else if (node instanceof SimpleName && node.getParent() instanceof Annotation) {
|
||||
computeProposalsForSimpleName(node, completions, offset, doc);
|
||||
}
|
||||
// case: @Value(value=<*>)
|
||||
else if (node instanceof SimpleName && node.getParent() instanceof MemberValuePair
|
||||
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
|
||||
computeProposalsForSimpleName(node, completions, offset, doc);
|
||||
}
|
||||
// case: @Value("prefix<*>")
|
||||
else if (node instanceof StringLiteral && node.getParent() instanceof Annotation) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
computeProposalsForStringLiteral(node, completions, offset, doc);
|
||||
}
|
||||
}
|
||||
// case: @Value(value="prefix<*>")
|
||||
else if (node instanceof StringLiteral && node.getParent() instanceof MemberValuePair
|
||||
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
computeProposalsForStringLiteral(node, completions, offset, doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void computeProposalsForSimpleName(ASTNode node, List<ICompletionProposal> completions, int offset,
|
||||
IDocument doc) {
|
||||
String prefix = identifyPropertyPrefix(node.toString(), offset - node.getStartPosition());
|
||||
|
||||
int startOffset = node.getStartPosition();
|
||||
int endOffset = node.getStartPosition() + node.getLength();
|
||||
|
||||
String proposalPrefix = "\"";
|
||||
String proposalPostfix = "\"";
|
||||
|
||||
List<Match<ConfigurationMetadataProperty>> matches = findMatches(prefix);
|
||||
|
||||
for (Match<ConfigurationMetadataProperty> match : matches) {
|
||||
|
||||
DocumentEdits edits = new DocumentEdits(doc);
|
||||
edits.replace(startOffset, endOffset, proposalPrefix + "${" + match.data.getId() + "}" + proposalPostfix);
|
||||
|
||||
ValuePropertyKeyProposal proposal = new ValuePropertyKeyProposal(edits, match.data.getId(), match.data.getName(), null);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
|
||||
private void computeProposalsForStringLiteral(ASTNode node, List<ICompletionProposal> completions, int offset,
|
||||
IDocument doc) throws BadLocationException {
|
||||
String prefix = identifyPropertyPrefix(doc.get(node.getStartPosition() + 1, offset - (node.getStartPosition() + 1)), offset - (node.getStartPosition() + 1));
|
||||
|
||||
int startOffset = offset - prefix.length();
|
||||
int endOffset = offset;
|
||||
|
||||
String prePrefix = doc.get(node.getStartPosition() + 1, offset - prefix.length() - node.getStartPosition() - 1);
|
||||
|
||||
String preCompletion;
|
||||
if (prePrefix.endsWith("${")) {
|
||||
preCompletion = "";
|
||||
}
|
||||
else if (prePrefix.endsWith("$")) {
|
||||
preCompletion = "{";
|
||||
}
|
||||
else {
|
||||
preCompletion = "${";
|
||||
}
|
||||
|
||||
String fullNodeContent = doc.get(node.getStartPosition(), node.getLength());
|
||||
String postCompletion = isClosingBracketMissing(fullNodeContent + preCompletion) ? "}" : "";
|
||||
|
||||
List<Match<ConfigurationMetadataProperty>> matches = findMatches(prefix);
|
||||
|
||||
for (Match<ConfigurationMetadataProperty> match : matches) {
|
||||
|
||||
DocumentEdits edits = new DocumentEdits(doc);
|
||||
edits.replace(startOffset, endOffset, preCompletion + match.data.getId() + postCompletion);
|
||||
|
||||
ValuePropertyKeyProposal proposal = new ValuePropertyKeyProposal(edits, match.data.getId(), match.data.getName(), null);
|
||||
completions.add(proposal);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isClosingBracketMissing(String fullNodeContent) {
|
||||
int bracketOpens = 0;
|
||||
|
||||
for (int i = 0; i < fullNodeContent.length(); i++) {
|
||||
if (fullNodeContent.charAt(i) == '{') {
|
||||
bracketOpens++;
|
||||
}
|
||||
else if (fullNodeContent.charAt(i) == '}') {
|
||||
bracketOpens--;
|
||||
}
|
||||
}
|
||||
|
||||
return bracketOpens > 0;
|
||||
}
|
||||
|
||||
public String identifyPropertyPrefix(String nodeContent, int offset) {
|
||||
String result = nodeContent.substring(0, offset);
|
||||
|
||||
int i = offset - 1;
|
||||
while (i >= 0) {
|
||||
char c = nodeContent.charAt(i);
|
||||
if (c == '}' || c == '{' || c == '$' || c == '#') {
|
||||
result = result.substring(i + 1, offset);
|
||||
break;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Match<ConfigurationMetadataProperty>> findMatches(String prefix) {
|
||||
List<Match<ConfigurationMetadataProperty>> matches = index.find(camelCaseToHyphens(prefix));
|
||||
return matches;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.completions;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItemKind;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class ValuePropertyKeyProposal implements ICompletionProposal {
|
||||
|
||||
private DocumentEdits edits;
|
||||
private String label;
|
||||
private String detail;
|
||||
private Renderable documentation;
|
||||
|
||||
public ValuePropertyKeyProposal(DocumentEdits edits, String label, String detail, Renderable documentation) {
|
||||
this.edits = edits;
|
||||
this.label = label;
|
||||
this.detail = detail;
|
||||
this.documentation = documentation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICompletionProposal deemphasize() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return this.label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionItemKind getKind() {
|
||||
return CompletionItemKind.Property;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocumentEdits getTextEdit() {
|
||||
return this.edits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetail() {
|
||||
return this.detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getDocumentation() {
|
||||
return this.documentation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.hover;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.core.JavaCore;
|
||||
import org.eclipse.jdt.core.dom.AST;
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTParser;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.NodeFinder;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.HoverHandler;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class BootJavaHoverProvider implements HoverHandler {
|
||||
|
||||
private static final String SPRING_VALUE = "org.springframework.beans.factory.annotation.Value";
|
||||
|
||||
private JavaProjectFinder projectFinder;
|
||||
private SimpleLanguageServer server;
|
||||
|
||||
public BootJavaHoverProvider(SimpleLanguageServer server, JavaProjectFinder projectFinder) {
|
||||
this.server = server;
|
||||
this.projectFinder = projectFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Hover> handle(TextDocumentPositionParams params) {
|
||||
SimpleTextDocumentService documents = server.getTextDocumentService();
|
||||
TextDocument doc = documents.get(params).copy();
|
||||
if (doc != null) {
|
||||
try {
|
||||
int offset = doc.toOffset(params.getPosition());
|
||||
CompletableFuture<Hover> hoverResult = provideHover(doc, offset);
|
||||
if (hoverResult != null) {
|
||||
return hoverResult;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
return SimpleTextDocumentService.NO_HOVER;
|
||||
}
|
||||
|
||||
private CompletableFuture<Hover> provideHover(TextDocument document, int offset) throws Exception {
|
||||
ASTParser parser = ASTParser.newParser(AST.JLS8);
|
||||
Map<String, String> options = JavaCore.getOptions();
|
||||
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
|
||||
parser.setCompilerOptions(options);
|
||||
parser.setKind(ASTParser.K_COMPILATION_UNIT);
|
||||
parser.setStatementsRecovery(true);
|
||||
parser.setBindingsRecovery(true);
|
||||
parser.setResolveBindings(true);
|
||||
|
||||
String[] classpathEntries = getClasspathEntries(document);
|
||||
String[] sourceEntries = new String[] {};
|
||||
parser.setEnvironment(classpathEntries, sourceEntries, null, true);
|
||||
|
||||
String docURI = document.getUri();
|
||||
String unitName = docURI.substring(docURI.lastIndexOf("/"));
|
||||
parser.setUnitName(unitName);
|
||||
parser.setSource(document.get(0, document.getLength()).toCharArray());
|
||||
|
||||
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
|
||||
ASTNode node = NodeFinder.perform(cu, offset, 0);
|
||||
|
||||
if (node != null) {
|
||||
System.out.println("AST node found: " + node.getClass().getName());
|
||||
return provideHoverForAnnotation(node, offset, document);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private CompletableFuture<Hover> provideHoverForAnnotation(ASTNode node, int offset, TextDocument doc) {
|
||||
Annotation annotation = null;
|
||||
ASTNode exactNode = node;
|
||||
|
||||
while (node != null && !(node instanceof Annotation)) {
|
||||
node = node.getParent();
|
||||
}
|
||||
|
||||
if (node != null) {
|
||||
annotation = (Annotation) node;
|
||||
ITypeBinding type = annotation.resolveTypeBinding();
|
||||
if (type != null) {
|
||||
String qualifiedName = type.getQualifiedName();
|
||||
if (qualifiedName != null && qualifiedName.startsWith("org.springframework")) {
|
||||
return provideHoverForSpringAnnotation(exactNode, annotation, type, offset, doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private CompletableFuture<Hover> provideHoverForSpringAnnotation(ASTNode node, Annotation annotation, ITypeBinding type, int offset, TextDocument doc) {
|
||||
if (type.getQualifiedName().equals(SPRING_VALUE)) {
|
||||
return new ValueHoverProvider().provideHoverForValueAnnotation(node, annotation, type, offset, doc);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private String[] getClasspathEntries(IDocument doc) throws Exception {
|
||||
IJavaProject project = this.projectFinder.find(doc);
|
||||
IClasspath classpath = project.getClasspath();
|
||||
Stream<Path> classpathEntries = classpath.getClasspathEntries();
|
||||
return classpathEntries
|
||||
.filter(path -> path.toFile().exists())
|
||||
.map(path -> path.toAbsolutePath().toString()).toArray(String[]::new);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.hover;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.lsp4j.Hover;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class ValueHoverProvider {
|
||||
|
||||
public CompletableFuture<Hover> provideHoverForValueAnnotation(ASTNode node, Annotation annotation,
|
||||
ITypeBinding type, int offset, TextDocument doc) {
|
||||
|
||||
try {
|
||||
// case: @Value("prefix<*>")
|
||||
if (node instanceof StringLiteral && node.getParent() instanceof Annotation) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
return provideHover(node.toString(), offset - node.getStartPosition(), node.getStartPosition(), doc);
|
||||
}
|
||||
}
|
||||
// case: @Value(value="prefix<*>")
|
||||
else if (node instanceof StringLiteral && node.getParent() instanceof MemberValuePair
|
||||
&& "value".equals(((MemberValuePair)node.getParent()).getName().toString())) {
|
||||
if (node.toString().startsWith("\"") && node.toString().endsWith("\"")) {
|
||||
return provideHover(node.toString(), offset - node.getStartPosition(), node.getStartPosition(), doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private CompletableFuture<Hover> provideHover(String value, int offset, int nodeStartOffset, TextDocument doc) {
|
||||
|
||||
try {
|
||||
LocalRange range = getPropertyRange(value, offset);
|
||||
if (range != null) {
|
||||
String propertyKey = value.substring(range.getStart(), range.getEnd());
|
||||
|
||||
JSONObject properties = getPropertiesFromProcess();
|
||||
if (propertyKey != null && properties != null) {
|
||||
Iterator<?> keys = properties.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = (String) keys.next();
|
||||
JSONObject props = properties.getJSONObject(key);
|
||||
|
||||
if (props.has(propertyKey)) {
|
||||
String propertyValue = props.getString(propertyKey);
|
||||
|
||||
Range hoverRange = doc.toRange(nodeStartOffset + range.getStart(), range.getEnd() - range.getStart());
|
||||
|
||||
Hover hover = new Hover();
|
||||
List<String> hoverContent = new ArrayList<>();
|
||||
|
||||
hoverContent.add("property value for " + propertyKey);
|
||||
hoverContent.add(propertyValue);
|
||||
hoverContent.add("coming from:");
|
||||
hoverContent.add(key);
|
||||
|
||||
hover.setContents(hoverContent);
|
||||
hover.setRange(hoverRange);
|
||||
|
||||
return CompletableFuture.completedFuture(hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public JSONObject getPropertiesFromProcess() {
|
||||
try {
|
||||
URL url = new URL("http://localhost:8080/env");
|
||||
|
||||
URLConnection con = url.openConnection();
|
||||
InputStream in = con.getInputStream();
|
||||
String encoding = con.getContentEncoding();
|
||||
encoding = encoding == null ? "UTF-8" : encoding;
|
||||
String body = IOUtils.toString(in, encoding);
|
||||
|
||||
JSONTokener tokener = new JSONTokener(body);
|
||||
JSONObject jsonData = new JSONObject(tokener);
|
||||
|
||||
return jsonData;
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getPropertyKey(String value, int offset) {
|
||||
LocalRange range = getPropertyRange(value, offset);
|
||||
if (range != null) {
|
||||
return value.substring(range.getStart(), range.getEnd());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public LocalRange getPropertyRange(String value, int offset) {
|
||||
int start = -1;
|
||||
int end = -1;
|
||||
|
||||
for (int i = offset - 1; i >= 0; i--) {
|
||||
if (value.charAt(i) == '{') {
|
||||
start = i + 1;
|
||||
break;
|
||||
}
|
||||
else if (value.charAt(i) == '}') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = offset; i < value.length(); i++) {
|
||||
if (value.charAt(i) == '{' || value.charAt(i) == '$') {
|
||||
break;
|
||||
}
|
||||
else if (value.charAt(i) == '}') {
|
||||
end = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (start > 0 && start < value.length() && end > 0 && end <= value.length() && start < end) {
|
||||
return new LocalRange(start, end);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class LocalRange {
|
||||
private int start;
|
||||
private int end;
|
||||
|
||||
public LocalRange(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.springframework.ide.vscode.boot.metadata;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexProvider {
|
||||
|
||||
private static final FuzzyMap<ConfigurationMetadataProperty> EMPTY_INDEX = new SpringPropertyIndex(null);
|
||||
|
||||
private JavaProjectFinder javaProjectFinder;
|
||||
private SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager();
|
||||
|
||||
private ProgressService progressService = (id, msg) -> {
|
||||
/* ignore */ };
|
||||
|
||||
public DefaultSpringPropertyIndexProvider(JavaProjectFinder javaProjectFinder) {
|
||||
this.javaProjectFinder = javaProjectFinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FuzzyMap<ConfigurationMetadataProperty> getIndex(IDocument doc) {
|
||||
IJavaProject jp = javaProjectFinder.find(doc);
|
||||
if (jp != null) {
|
||||
return indexManager.get(jp, progressService);
|
||||
}
|
||||
return EMPTY_INDEX;
|
||||
}
|
||||
|
||||
public void setProgressService(ProgressService progressService) {
|
||||
this.progressService = progressService;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.springframework.ide.vscode.boot.metadata;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository;
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepositoryJsonBuilder;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
|
||||
public class PropertiesLoader {
|
||||
|
||||
private static final String MAIN_SPRING_CONFIGURATION_METADATA_JSON = "META-INF/spring-configuration-metadata.json";
|
||||
|
||||
public static final String ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON = "META-INF/additional-spring-configuration-metadata.json";
|
||||
|
||||
/**
|
||||
* The default classpath location for config metadata loaded when scanning .jar files on the classpath.
|
||||
*/
|
||||
public static final String[] JAR_META_DATA_LOCATIONS = {
|
||||
MAIN_SPRING_CONFIGURATION_METADATA_JSON
|
||||
//Not scanning 'additional' metadata because it integrated already in the main data.
|
||||
};
|
||||
|
||||
/**
|
||||
* The default classpath location for config metadata loaded when scanning project output folders.
|
||||
*/
|
||||
public static final String[] PROJECT_META_DATA_LOCATIONS = {
|
||||
MAIN_SPRING_CONFIGURATION_METADATA_JSON,
|
||||
ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON
|
||||
};
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(PropertiesLoader.class.getName());
|
||||
|
||||
private ConfigurationMetadataRepositoryJsonBuilder builder = ConfigurationMetadataRepositoryJsonBuilder.create();
|
||||
|
||||
public ConfigurationMetadataRepository load(IClasspath classPath) {
|
||||
try {
|
||||
classPath.getClasspathEntries().forEach(entry -> {
|
||||
File fileEntry = entry.toFile();
|
||||
if (fileEntry.exists()) {
|
||||
if (fileEntry.isDirectory()) {
|
||||
loadFromOutputFolder(entry);
|
||||
} else {
|
||||
loadFromJar(entry);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
LOG.log(Level.SEVERE, "Failed to retrieve classpath", e);
|
||||
}
|
||||
ConfigurationMetadataRepository repository = builder.build();
|
||||
return repository;
|
||||
}
|
||||
|
||||
private void loadFromOutputFolder(Path outputFolderPath) {
|
||||
if (outputFolderPath != null && Files.exists(outputFolderPath)) {
|
||||
Arrays.stream(PROJECT_META_DATA_LOCATIONS).forEach(mdLoc -> {
|
||||
loadFromJsonFile(outputFolderPath.resolve(mdLoc));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFromJsonFile(Path mdf) {
|
||||
if (Files.exists(mdf)) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = Files.newInputStream(mdf);
|
||||
loadFromInputStream(is);
|
||||
} catch (Exception e) {
|
||||
LOG.log(Level.SEVERE, "Error loading file '" + mdf + "'", e);
|
||||
} finally {
|
||||
if (is!=null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFromJar(Path f) {
|
||||
JarFile jarFile = null;
|
||||
try {
|
||||
jarFile = new JarFile(f.toFile());
|
||||
//jarDump(jarFile);
|
||||
for (String loc : JAR_META_DATA_LOCATIONS) {
|
||||
ZipEntry e = jarFile.getEntry(loc);
|
||||
if (e!=null) {
|
||||
loadFrom(jarFile, e);
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.SEVERE, "Error loading JAR file", e);
|
||||
} finally {
|
||||
if (jarFile!=null) {
|
||||
try {
|
||||
jarFile.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void loadFrom(JarFile jarFile, ZipEntry ze) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = jarFile.getInputStream(ze);
|
||||
loadFromInputStream(is);
|
||||
} catch (Throwable e) {
|
||||
LOG.log(Level.SEVERE, "Error loading JAR file", e);
|
||||
} finally {
|
||||
if (is!=null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFromInputStream(InputStream is) throws IOException {
|
||||
builder.withJsonResource(is);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.metadata;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.languageserver.ProgressService;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
|
||||
/**
|
||||
* Support for Reconciling, Content Assist and Hover Text in spring properties
|
||||
* file all make use of a per-project index of spring properties metadata extracted
|
||||
* from project's classpath. This Index manager is responsible for keeping at most
|
||||
* one index per-project and to keep the index up-to-date.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class SpringPropertiesIndexManager {
|
||||
|
||||
private Map<IJavaProject, SpringPropertyIndex> indexes = null;
|
||||
private static int progressIdCt = 0;
|
||||
|
||||
public SpringPropertiesIndexManager() {
|
||||
}
|
||||
|
||||
public synchronized FuzzyMap<ConfigurationMetadataProperty> get(IJavaProject project, ProgressService progressService) {
|
||||
if (indexes==null) {
|
||||
indexes = new HashMap<>();
|
||||
}
|
||||
|
||||
SpringPropertyIndex index = indexes.get(project);
|
||||
if (index==null) {
|
||||
String progressId = getProgressId();
|
||||
if (progressService != null) {
|
||||
progressService.progressEvent(progressId, "Indexing Spring Boot Properties...");
|
||||
}
|
||||
|
||||
index = new SpringPropertyIndex(project.getClasspath());
|
||||
indexes.put(project, index);
|
||||
|
||||
if (progressService != null) {
|
||||
progressService.progressEvent(progressId, null);
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private static synchronized String getProgressId() {
|
||||
return DefaultSpringPropertyIndexProvider.class.getName()+ (progressIdCt++);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.metadata;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
|
||||
public class SpringPropertyIndex extends FuzzyMap<ConfigurationMetadataProperty> {
|
||||
|
||||
public SpringPropertyIndex(IClasspath projectPath) {
|
||||
if (projectPath!=null) {
|
||||
PropertiesLoader loader = new PropertiesLoader();
|
||||
ConfigurationMetadataRepository metadata = loader.load(projectPath);
|
||||
Collection<ConfigurationMetadataProperty> allEntries = metadata.getAllProperties().values();
|
||||
for (ConfigurationMetadataProperty item : allEntries) {
|
||||
add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps out 'test data' based on the current contents of the index. This is not meant to be
|
||||
* used in 'production' code. The idea is to call this method during development to dump a
|
||||
* 'snapshot' of the index onto System.out. The data is printed in a forma so that it can be easily
|
||||
* pasted/used into JUNit testing code.
|
||||
*/
|
||||
// public void dumpAsTestData() {
|
||||
// List<Match<PropertyInfo>> allData = this.find("");
|
||||
// for (Match<PropertyInfo> match : allData) {
|
||||
// PropertyInfo d = match.data;
|
||||
// System.out.println("data("
|
||||
// +dumpString(d.getId())+", "
|
||||
// +dumpString(d.getType())+", "
|
||||
// +dumpString(d.getDefaultValue())+", "
|
||||
// +dumpString(d.getDescription()) +");"
|
||||
// );
|
||||
// for (PropertySource source : d.getSources()) {
|
||||
// String st = source.getSourceType();
|
||||
// String sm = source.getSourceMethod();
|
||||
// if (sm!=null) {
|
||||
// System.out.println(d.getId() +" from: "+st+"::"+sm);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// private String dumpString(Object v) {
|
||||
// if (v==null) {
|
||||
// return "null";
|
||||
// }
|
||||
// return dumpString(""+v);
|
||||
// }
|
||||
|
||||
private String dumpString(String s) {
|
||||
if (s==null) {
|
||||
return "null";
|
||||
} else {
|
||||
StringBuilder buf = new StringBuilder("\"");
|
||||
for (char c : s.toCharArray()) {
|
||||
switch (c) {
|
||||
case '\r':
|
||||
buf.append("\\r");
|
||||
break;
|
||||
case '\n':
|
||||
buf.append("\\n");
|
||||
break;
|
||||
case '\\':
|
||||
buf.append("\\\\");
|
||||
break;
|
||||
case '\"':
|
||||
buf.append("\\\"");
|
||||
break;
|
||||
default:
|
||||
buf.append(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf.append("\"");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getKey(ConfigurationMetadataProperty entry) {
|
||||
return entry.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the longest known property that is a prefix of the given name. Here prefix does not mean
|
||||
* 'string prefix' but a prefix in the sense of treating '.' as a kind of separators. So
|
||||
* 'prefix' is not allowed to end in the middle of a 'segment'.
|
||||
*/
|
||||
// public static PropertyInfo findLongestValidProperty(FuzzyMap<PropertyInfo> index, String name) {
|
||||
// int bracketPos = name.indexOf('[');
|
||||
// int endPos = bracketPos>=0?bracketPos:name.length();
|
||||
// PropertyInfo prop = null;
|
||||
// String prefix = null;
|
||||
// while (endPos>0 && prop==null) {
|
||||
// prefix = name.substring(0, endPos);
|
||||
// String canonicalPrefix = StringUtil.camelCaseToHyphens(prefix);
|
||||
// prop = index.get(canonicalPrefix);
|
||||
// if (prop==null) {
|
||||
// endPos = name.lastIndexOf('.', endPos-1);
|
||||
// }
|
||||
// }
|
||||
// if (prop!=null) {
|
||||
// //We should meet caller's expectation that matched properties returned by this method
|
||||
// // match the names exactly even if we found them using relaxed name matching.
|
||||
// return prop.withId(prefix);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.metadata;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SpringPropertyIndexProvider {
|
||||
FuzzyMap<ConfigurationMetadataProperty> getIndex(IDocument doc);
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFin
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
|
||||
import org.springframework.ide.vscode.project.harness.PropertyIndexHarness;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
@@ -36,18 +37,21 @@ public class ScopeCompletionTest {
|
||||
private final JavaProjectFinder javaProjectFinder = (doc) -> getTestProject();
|
||||
|
||||
private LanguageServerHarness harness;
|
||||
private PropertyIndexHarness indexHarness;
|
||||
private IJavaProject testProject;
|
||||
|
||||
private Editor editor;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
testProject = ProjectsHarness.INSTANCE.mavenProject("test-scope-annotation");
|
||||
testProject = ProjectsHarness.INSTANCE.mavenProject("test-annotations");
|
||||
indexHarness = new PropertyIndexHarness();
|
||||
|
||||
harness = new LanguageServerHarness(new Callable<BootJavaLanguageServer>() {
|
||||
@Override
|
||||
public BootJavaLanguageServer call() throws Exception {
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(javaProjectFinder);
|
||||
BootJavaLanguageServer server = new BootJavaLanguageServer(javaProjectFinder, indexHarness.getIndexProvider());
|
||||
return server;
|
||||
}
|
||||
}) {
|
||||
@@ -155,7 +159,7 @@ public class ScopeCompletionTest {
|
||||
}
|
||||
|
||||
private void prepareCase(String selectedAnnotation, String annotationStatementBeforeTest) throws Exception {
|
||||
InputStream resource = this.getClass().getResourceAsStream("/test-projects/test-scope-annotation/src/main/java/org/test/TestScopeCompletion.java");
|
||||
InputStream resource = this.getClass().getResourceAsStream("/test-projects/test-annotations/src/main/java/org/test/TestScopeCompletion.java");
|
||||
String content = IOUtils.toString(resource);
|
||||
|
||||
content = content.replace(selectedAnnotation, annotationStatementBeforeTest);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user