From 377040f2a09aa10fb098917f639fa0a47ef8066d Mon Sep 17 00:00:00 2001 From: nsingh Date: Tue, 15 Nov 2016 16:07:55 -0800 Subject: [PATCH 1/2] Added interfaces for hover engine and adapter --- .../languageserver/hover/HoverInfo.java | 16 +++++ .../languageserver/hover/IHoverEngine.java | 19 ++++++ .../hover/VscodeHoverEngine.java | 22 +++++++ .../hover/VscodeHoverEngineAdapter.java | 64 +++++++++++++++++++ .../util/SimpleTextDocumentService.java | 2 + .../yaml/ManifestYamlLanguageServer.java | 8 ++- .../manifest/yaml/ManifestYmlHoverEngine.java | 27 ++++++++ .../vscode/manifest/yaml/YamlHoverInfo.java | 32 ++++++++++ 8 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/IHoverEngine.java create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngine.java create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java create mode 100644 vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlHoverEngine.java create mode 100644 vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/YamlHoverInfo.java diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/HoverInfo.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/HoverInfo.java index 3673eb44a..be9b94cb1 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/HoverInfo.java +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/HoverInfo.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2016 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.languageserver.hover; /** @@ -5,4 +15,10 @@ package org.springframework.ide.vscode.commons.languageserver.hover; */ public interface HoverInfo { + String renderAsText(); + + String renderAsHtml(); + + String renderAsMarkdown(); + } diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/IHoverEngine.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/IHoverEngine.java new file mode 100644 index 000000000..c000d9ef9 --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/IHoverEngine.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2016 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.languageserver.hover; + +import org.springframework.ide.vscode.commons.languageserver.util.IDocument; + +public interface IHoverEngine { + + HoverInfo getHover(IDocument document, int offset) throws Exception; + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngine.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngine.java new file mode 100644 index 000000000..96e5a368f --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngine.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2016 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.languageserver.hover; + +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lsp4j.Hover; +import org.eclipse.lsp4j.TextDocumentPositionParams; + +public interface VscodeHoverEngine { + + CompletableFuture getHover(TextDocumentPositionParams params); + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java new file mode 100644 index 000000000..990dbdafb --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/hover/VscodeHoverEngineAdapter.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2016 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.languageserver.hover; + +import java.util.Collections; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.lsp4j.Hover; +import org.eclipse.lsp4j.TextDocumentPositionParams; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; +import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; +import org.springframework.ide.vscode.commons.languageserver.util.TextDocument; +import org.springframework.ide.vscode.commons.util.Futures; + +public class VscodeHoverEngineAdapter implements VscodeHoverEngine { + + private IHoverEngine engine; + private SimpleLanguageServer server; + final static Logger logger = LoggerFactory.getLogger(VscodeHoverEngineAdapter.class); + + + public VscodeHoverEngineAdapter(SimpleLanguageServer server, IHoverEngine engine) { + this.engine = engine; + this.server = server; + } + + @Override + public CompletableFuture getHover(TextDocumentPositionParams params) { + //TODO: This returns a CompletableFuture which suggests we should try to do expensive work asyncly. + // We are currently just doing all this in a blocking way and wrapping the already computed list into + // a trivial pre-resolved future. + try { + SimpleTextDocumentService documents = server.getTextDocumentService(); + TextDocument doc = documents.get(params); + if (doc!=null) { + int offset = doc.toOffset(params.getPosition()); + HoverInfo hoverInfo = engine.getHover(doc, offset); + if (hoverInfo != null) { + Hover hover = new Hover(); + hover.setContents(Collections.singletonList(hoverInfo.renderAsMarkdown())); + return Futures.of(hover); + } + else{ + return Futures.of(null); + } + + } + } catch (Exception e) { + logger.error("error computing hover", e); + } + return SimpleTextDocumentService.NO_HOVER; + } + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java index 72980cb60..27c990dd0 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/SimpleTextDocumentService.java @@ -167,6 +167,8 @@ public class SimpleTextDocumentService implements TextDocumentService { public final static CompletableFuture NO_COMPLETIONS = Futures.of( new CompletionList(false, Collections.emptyList())); + public final static CompletableFuture NO_HOVER = Futures.of(null); + @Override public CompletableFuture completion(TextDocumentPositionParams position) { diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java index 16de543ca..82c5d1c39 100644 --- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java +++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYamlLanguageServer.java @@ -9,6 +9,9 @@ import org.eclipse.lsp4j.ServerCapabilities; import org.eclipse.lsp4j.TextDocumentSyncKind; import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngine; import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter; +import org.springframework.ide.vscode.commons.languageserver.hover.IHoverEngine; +import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngine; +import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter; import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine; import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer; import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; @@ -40,7 +43,9 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { YamlAssistContextProvider contextProvider = new SchemaBasedYamlAssistContextProvider(schema); YamlCompletionEngine yamlCompletionEngine = new YamlCompletionEngine(structureProvider, contextProvider); VscodeCompletionEngine completionEngine = new VscodeCompletionEngineAdapter(this, yamlCompletionEngine); - + IHoverEngine yamlHoverEngine = new ManifestYmlHoverEngine(); + VscodeHoverEngine hoverEngine = new VscodeHoverEngineAdapter(this, yamlHoverEngine ); + // SimpleWorkspaceService workspace = getWorkspaceService(); documents.onDidChangeContent(params -> { TextDocument doc = params.getDocument(); @@ -60,6 +65,7 @@ public class ManifestYamlLanguageServer extends SimpleLanguageServer { documents.onCompletion(completionEngine::getCompletions); documents.onCompletionResolve(completionEngine::resolveCompletion); + documents.onHover(hoverEngine ::getHover); } protected IReconcileEngine getReconcileEngine() { diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlHoverEngine.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlHoverEngine.java new file mode 100644 index 000000000..f1698d40a --- /dev/null +++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/ManifestYmlHoverEngine.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 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.manifest.yaml; + +import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo; +import org.springframework.ide.vscode.commons.languageserver.hover.IHoverEngine; +import org.springframework.ide.vscode.commons.languageserver.util.IDocument; + +public class ManifestYmlHoverEngine implements IHoverEngine { + + @Override + public HoverInfo getHover(IDocument document, int offset) throws Exception { + // TODO. Create the hover info based on AST + HoverInfo info = new YamlHoverInfo(); + + return info; + } + +} diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/YamlHoverInfo.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/YamlHoverInfo.java new file mode 100644 index 000000000..d522c377f --- /dev/null +++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/YamlHoverInfo.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2016 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.manifest.yaml; + +import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfo; + +public class YamlHoverInfo implements HoverInfo { + + @Override + public String renderAsText() { + return null; + } + + @Override + public String renderAsHtml() { + return null; + } + + @Override + public String renderAsMarkdown() { + return null; + } + +} From 34f56ae882564ffc31829a39726b3ad758bfcc5c Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Tue, 15 Nov 2016 19:30:25 -0500 Subject: [PATCH 2/2] Ability to download artifacts sources, javadoc, tests and tests sources --- .../ide/vscode/commons/maven/MavenBridge.java | 77 +++++++++++++++++++ .../ide/vscode/commons/maven/MavenCore.java | 21 +++++ .../vscode/commons/maven/MavenException.java | 9 ++- .../commons/project-test-harness/.gitignore | 2 +- 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenBridge.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenBridge.java index 59e7a1670..969269d77 100644 --- a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenBridge.java +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenBridge.java @@ -12,9 +12,11 @@ package org.springframework.ide.vscode.commons.maven; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -28,6 +30,7 @@ import java.util.Properties; import org.apache.maven.DefaultMaven; import org.apache.maven.Maven; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -95,6 +98,9 @@ import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.dag.CycleDetectedException; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -800,5 +806,76 @@ class MavenBridge { } } } + + public Artifact resolve(String groupId, String artifactId, String version, String type, String classifier, + List remoteRepositories, MavenExecutionRequest request) throws MavenException { + Artifact artifact = lookup(RepositorySystem.class).createArtifactWithClassifier(groupId, artifactId, version, + type, classifier); + + return resolve(artifact, remoteRepositories, request); + } + + public Artifact resolve(final Artifact artifact, List remoteRepositories, + MavenExecutionRequest executionRequest) throws MavenException { + if (remoteRepositories == null) { + try { + remoteRepositories = getArtifactRepositories(); + } catch (MavenException e) { + // we've tried + remoteRepositories = Collections.emptyList(); + } + } + final List _remoteRepositories = remoteRepositories; + + org.eclipse.aether.RepositorySystem repoSystem = lookup(org.eclipse.aether.RepositorySystem.class); + + ArtifactRequest request = new ArtifactRequest(); + request.setArtifact(RepositoryUtils.toArtifact(artifact)); + request.setRepositories(RepositoryUtils.toRepos(_remoteRepositories)); + + ArtifactResult result; + try { + result = repoSystem.resolveArtifact(createRepositorySession(executionRequest), request); + } catch (ArtifactResolutionException ex) { + result = ex.getResults().get(0); + } + + setLastUpdated(executionRequest.getLocalRepository(), _remoteRepositories, artifact); + + if (result.isResolved()) { + artifact.selectVersion(result.getArtifact().getVersion()); + artifact.setFile(result.getArtifact().getFile()); + artifact.setResolved(true); + } else { + throw new MavenException(result.getExceptions().toArray(new Exception[result.getExceptions().size()])); + } + + return artifact; + } + + /* package */void setLastUpdated(ArtifactRepository localRepository, List remoteRepositories, + Artifact artifact) throws MavenException { + + Properties lastUpdated = loadLastUpdated(localRepository, artifact); + + String timestamp = Long.toString(System.currentTimeMillis()); + + for (ArtifactRepository repository : remoteRepositories) { + lastUpdated.setProperty(getLastUpdatedKey(repository, artifact), timestamp); + } + + File lastUpdatedFile = getLastUpdatedFile(localRepository, artifact); + try { + lastUpdatedFile.getParentFile().mkdirs(); + BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(lastUpdatedFile)); + try { + lastUpdated.store(os, null); + } finally { + IOUtil.close(os); + } + } catch (IOException ex) { + throw new MavenException(ex); + } + } } diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java index 52ea4578a..acf5d7ea1 100644 --- a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java @@ -65,6 +65,11 @@ import com.google.common.base.Suppliers; */ public class MavenCore { + private static final String CLASSIFIER_SOURCES = "sources"; + private static final String CLASSIFIER_JAVADOC = "javadoc"; + 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"; @@ -235,6 +240,22 @@ public class MavenCore { return artifacts; } + public Artifact getSources(Artifact artifact) throws MavenException { + return maven.resolve(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(), CLASSIFIER_SOURCES, null, maven.createExecutionRequest()); + } + + public Artifact getJavadoc(Artifact artifact) throws MavenException { + return maven.resolve(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(), CLASSIFIER_JAVADOC, null, maven.createExecutionRequest()); + } + + public Artifact getTests(Artifact artifact) throws MavenException { + return maven.resolve(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(), CLASSIFIER_TESTS, null, maven.createExecutionRequest()); + } + + public Artifact getTestSources(Artifact artifact) throws MavenException { + return maven.resolve(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(), CLASSIFIER_TESTSOURCES, null, maven.createExecutionRequest()); + } + public Stream getJreLibs() throws MavenException { String s = (String) maven.createExecutionRequest().getSystemProperties().get(JAVA_BOOT_CLASS_PATH); return Arrays.stream(s.split(File.pathSeparator)).map(File::new).filter(f -> f.canRead()).map(f -> Paths.get(f.toURI())); diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenException.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenException.java index 40dc239cd..f28bcbe5e 100644 --- a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenException.java +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenException.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.maven; +import java.util.Arrays; +import java.util.stream.Collectors; + /** * Wrapper for Maven exceptions * @@ -20,13 +23,13 @@ public class MavenException extends Exception { private static final long serialVersionUID = 1L; - private Throwable t; + private Throwable[] t; public MavenException() { super(); } - public MavenException(Throwable t) { + public MavenException(Throwable... t) { super(); this.t = t; } @@ -34,7 +37,7 @@ public class MavenException extends Exception { @Override public String getMessage() { if (t != null) { - return t.getMessage(); + return String.join("\n", Arrays.stream(t).map(t -> t.getMessage()).collect(Collectors.toList())); } return super.getMessage(); } diff --git a/vscode-extensions/commons/project-test-harness/.gitignore b/vscode-extensions/commons/project-test-harness/.gitignore index 10c9f8a89..145500786 100644 --- a/vscode-extensions/commons/project-test-harness/.gitignore +++ b/vscode-extensions/commons/project-test-harness/.gitignore @@ -1,2 +1,2 @@ **/classpath.txt - +**/bin/**