diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/build.properties b/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/build.properties new file mode 100644 index 000000000..64f93a9f0 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/feature.xml b/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/feature.xml new file mode 100644 index 000000000..310128412 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/feature.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/pom.xml b/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/pom.xml new file mode 100644 index 000000000..e8c8474ff --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers.feature/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + org.springframework.boot.ide + org.springframework.boot.ide.servers + 4.0.0-SNAPSHOT + ../pom.xml + + + org.springframework.boot.ide.java.servers.feature + eclipse-feature + + diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/.classpath b/eclipse-language-servers/org.springframework.boot.ide.java.servers/.classpath new file mode 100644 index 000000000..eca7bdba8 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/.project b/eclipse-language-servers/org.springframework.boot.ide.java.servers/.project new file mode 100644 index 000000000..1dac181c4 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/.project @@ -0,0 +1,28 @@ + + + org.springframework.boot.ide.java.servers + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/.settings/org.eclipse.jdt.core.prefs b/eclipse-language-servers/org.springframework.boot.ide.java.servers/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..0c68a61dc --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.boot.ide.java.servers/META-INF/MANIFEST.MF new file mode 100644 index 000000000..e93d746a6 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/META-INF/MANIFEST.MF @@ -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 diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/build.properties b/eclipse-language-servers/org.springframework.boot.ide.java.servers/build.properties new file mode 100644 index 000000000..3b7db0f69 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + servers/ diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/plugin.xml b/eclipse-language-servers/org.springframework.boot.ide.java.servers/plugin.xml new file mode 100644 index 000000000..64c30df54 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/plugin.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/pom.xml b/eclipse-language-servers/org.springframework.boot.ide.java.servers/pom.xml new file mode 100644 index 000000000..1308d7ebd --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + + org.springframework.boot.ide + org.springframework.boot.ide.servers + 4.0.0-SNAPSHOT + ../pom.xml + + + org.springframework.boot.ide.java.servers + eclipse-plugin + + + + org.springframework.ide.vscode + vscode-boot-java + 0.0.1-SNAPSHOT + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + copy + prepare-package + + copy + + + + + org.springframework.ide.vscode + vscode-boot-java + true + ${project.build.directory}/../servers + + + true + true + + + + + + + + diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/Constants.java b/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/Constants.java new file mode 100644 index 000000000..622375721 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/Constants.java @@ -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"; + +} diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/SpringBootJavaCompletionProposalComputer.java b/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/SpringBootJavaCompletionProposalComputer.java new file mode 100644 index 000000000..fd1b72ae7 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/SpringBootJavaCompletionProposalComputer.java @@ -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 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 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() { + } + +} diff --git a/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/SpringBootJavaLanguageServer.java b/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/SpringBootJavaLanguageServer.java new file mode 100644 index 000000000..4369f3e62 --- /dev/null +++ b/eclipse-language-servers/org.springframework.boot.ide.java.servers/src/org/springframework/boot/ide/java/servers/SpringBootJavaLanguageServer.java @@ -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 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); + } + +} diff --git a/eclipse-language-servers/org.springframework.boot.ide.servers.repository/category.xml b/eclipse-language-servers/org.springframework.boot.ide.servers.repository/category.xml index d11905dad..0f9aacb75 100644 --- a/eclipse-language-servers/org.springframework.boot.ide.servers.repository/category.xml +++ b/eclipse-language-servers/org.springframework.boot.ide.servers.repository/category.xml @@ -10,6 +10,10 @@ + + + + diff --git a/eclipse-language-servers/pom.xml b/eclipse-language-servers/pom.xml index bd1f778a1..1ffa6e0e4 100644 --- a/eclipse-language-servers/pom.xml +++ b/eclipse-language-servers/pom.xml @@ -30,6 +30,9 @@ org.springframework.boot.ide.properties.servers org.springframework.boot.ide.properties.servers.feature + org.springframework.boot.ide.java.servers + org.springframework.boot.ide.java.servers.feature + org.springframework.boot.ide.cloudfoundry.server org.springframework.boot.ide.cloudfoundry.server.feature @@ -81,6 +84,11 @@ p2 http://download.eclipse.org/tools/orbit/downloads/drops/S20161205183421/repository/ + + lsp4j-snapshots + p2 + http://services.typefox.io/open-source/jenkins/job/lsp4j/job/master/lastStableBuild/artifact/build/p2-repository/ + lsp4e p2