From 47f3f51c4fe173c5837186317751da4a10d5af48 Mon Sep 17 00:00:00 2001 From: BoykoAlex Date: Mon, 21 Aug 2017 17:23:54 -0400 Subject: [PATCH 1/7] Fix initial port. Update version --- atom-extensions/atom-commons/lib/jar-language-client.js | 3 ++- atom-extensions/atom-commons/package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/atom-extensions/atom-commons/lib/jar-language-client.js b/atom-extensions/atom-commons/lib/jar-language-client.js index 4d09c3d26..10ee372f9 100644 --- a/atom-extensions/atom-commons/lib/jar-language-client.js +++ b/atom-extensions/atom-commons/lib/jar-language-client.js @@ -27,7 +27,8 @@ export class JarLanguageClient extends AutoLanguageClient { let childProcess; return new Promise((resolve, reject) => { - PortFinder.getPort((err, port) => { + let basePort = Math.floor(Math.random() * 10000) + 40000; + PortFinder.getPort({port: basePort}, (err, port) => { this.server = net.createServer(socket => { this.socket = socket; resolve(childProcess); diff --git a/atom-extensions/atom-commons/package.json b/atom-extensions/atom-commons/package.json index fc8f69474..468391dd5 100644 --- a/atom-extensions/atom-commons/package.json +++ b/atom-extensions/atom-commons/package.json @@ -1,6 +1,6 @@ { "name": "pivotal-atom-languageclient-commons", - "version": "0.0.6", + "version": "0.0.7", "description": "Atom language client commons for STS4 language servers", "repository": "https://github.com/spring-projects/sts4", "license": "MIT", From 309d2201ae8863ab3511e51fe4a10042358e66e9 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Tue, 22 Aug 2017 11:55:42 +0200 Subject: [PATCH 2/7] updated plugin and feature metadata for eclipse language server extensions --- .../feature.xml | 2 +- .../META-INF/MANIFEST.MF | 1 + .../org.springframework.tooling.bosh.ls.feature/feature.xml | 2 +- .../org.springframework.tooling.bosh.ls/META-INF/MANIFEST.MF | 3 ++- .../feature.xml | 2 +- .../META-INF/MANIFEST.MF | 3 ++- .../META-INF/MANIFEST.MF | 3 ++- .../feature.xml | 2 +- .../META-INF/MANIFEST.MF | 3 ++- .../feature.xml | 2 +- .../META-INF/MANIFEST.MF | 3 ++- 11 files changed, 16 insertions(+), 10 deletions(-) diff --git a/eclipse-language-servers/org.springframework.tooling.boot.java.ls.feature/feature.xml b/eclipse-language-servers/org.springframework.tooling.boot.java.ls.feature/feature.xml index 6def1606c..2b386fb4c 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.java.ls.feature/feature.xml +++ b/eclipse-language-servers/org.springframework.tooling.boot.java.ls.feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/eclipse-language-servers/org.springframework.tooling.boot.java.ls/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.boot.java.ls/META-INF/MANIFEST.MF index eebaa526c..a81db164e 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.java.ls/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.boot.java.ls/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Spring Boot Java Language Server +Bundle-Vendor: Pivotal, Inc. Bundle-SymbolicName: org.springframework.tooling.boot.java.ls;singleton:=true Bundle-Version: 4.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/eclipse-language-servers/org.springframework.tooling.bosh.ls.feature/feature.xml b/eclipse-language-servers/org.springframework.tooling.bosh.ls.feature/feature.xml index f84aa822a..cfd874491 100644 --- a/eclipse-language-servers/org.springframework.tooling.bosh.ls.feature/feature.xml +++ b/eclipse-language-servers/org.springframework.tooling.bosh.ls.feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/eclipse-language-servers/org.springframework.tooling.bosh.ls/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.bosh.ls/META-INF/MANIFEST.MF index e447f04ab..edd524f1c 100644 --- a/eclipse-language-servers/org.springframework.tooling.bosh.ls/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.bosh.ls/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Servers +Bundle-Name: BOSH Manifest Language Server +Bundle-Vendor: Pivotal, Inc. Bundle-SymbolicName: org.springframework.tooling.bosh.ls;singleton:=true Bundle-Version: 4.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration.feature/feature.xml b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration.feature/feature.xml index 256fb7292..f07be0ab1 100644 --- a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration.feature/feature.xml +++ b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration.feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration/META-INF/MANIFEST.MF index 1a1d742bc..77835433f 100644 --- a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls.integration/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Server +Bundle-Name: Cloud Foundry Manifest Language Server Generic Editor Integration +Bundle-Vendor: Pivotal, Inc. Bundle-SymbolicName: org.springframework.tooling.cloudfoundry.manifest.ls.integration;singleton:=true Bundle-Version: 4.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF index 37632754d..999f003be 100644 --- a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Server +Bundle-Name: Cloud Foundry Manifest Language Server +Bundle-Vendor: Pivotal, Inc. Bundle-SymbolicName: org.springframework.tooling.cloudfoundry.manifest.ls;singleton:=true Bundle-Version: 0.0.9.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/eclipse-language-servers/org.springframework.tooling.concourse.ls.feature/feature.xml b/eclipse-language-servers/org.springframework.tooling.concourse.ls.feature/feature.xml index fb169bf4b..349505733 100644 --- a/eclipse-language-servers/org.springframework.tooling.concourse.ls.feature/feature.xml +++ b/eclipse-language-servers/org.springframework.tooling.concourse.ls.feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/eclipse-language-servers/org.springframework.tooling.concourse.ls/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.concourse.ls/META-INF/MANIFEST.MF index 79b325123..dfeac777c 100644 --- a/eclipse-language-servers/org.springframework.tooling.concourse.ls/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.concourse.ls/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Servers +Bundle-Name: Concourse Pipeline Language Server +Bundle-Vendor: Pivotal, Inc. Bundle-SymbolicName: org.springframework.tooling.concourse.ls;singleton:=true Bundle-Version: 4.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/eclipse-language-servers/org.springframework.tooling.properties.ls.feature/feature.xml b/eclipse-language-servers/org.springframework.tooling.properties.ls.feature/feature.xml index 5a6af9039..568524d00 100644 --- a/eclipse-language-servers/org.springframework.tooling.properties.ls.feature/feature.xml +++ b/eclipse-language-servers/org.springframework.tooling.properties.ls.feature/feature.xml @@ -1,7 +1,7 @@ diff --git a/eclipse-language-servers/org.springframework.tooling.properties.ls/META-INF/MANIFEST.MF b/eclipse-language-servers/org.springframework.tooling.properties.ls/META-INF/MANIFEST.MF index 68c3ead13..4e8b8a8d0 100644 --- a/eclipse-language-servers/org.springframework.tooling.properties.ls/META-INF/MANIFEST.MF +++ b/eclipse-language-servers/org.springframework.tooling.properties.ls/META-INF/MANIFEST.MF @@ -1,6 +1,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: Servers +Bundle-Name: Spring Boot Properties Language Server +Bundle-Vendor: Pivotal, Inc. Bundle-SymbolicName: org.springframework.tooling.properties.ls;singleton:=true Bundle-Version: 4.0.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 From 8789bba6db305dcf3aea21664319f1daaeddbdb0 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Tue, 22 Aug 2017 12:05:39 +0200 Subject: [PATCH 3/7] enabled about dialog qualifier replacements --- .../about.properties | 1 - .../plugin.properties | 1 - .../pom.xml | 51 ++++++++++++++++--- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/about.properties b/eclipse-distribution/org.springframework.boot.ide.branding/about.properties index 4d694ac87..171fd23c6 100644 --- a/eclipse-distribution/org.springframework.boot.ide.branding/about.properties +++ b/eclipse-distribution/org.springframework.boot.ide.branding/about.properties @@ -8,7 +8,6 @@ title=Spring Boot IDE \n\ \n\ Version: @QUALIFIER@\n\ Build Id: @BUILD_ID@\n\ -Platform: Eclipse @PLATFORM_VERSION@\n\ \n\ Copyright (c) 2007 - 2017 Pivotal Software, Inc.\n\ All rights reserved. Visit http://spring.io/tools/sts\n\ diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/plugin.properties b/eclipse-distribution/org.springframework.boot.ide.branding/plugin.properties index 95f3ae739..032292018 100644 --- a/eclipse-distribution/org.springframework.boot.ide.branding/plugin.properties +++ b/eclipse-distribution/org.springframework.boot.ide.branding/plugin.properties @@ -6,7 +6,6 @@ productBlurb=Spring Boot IDE \n\ \n\ Version: @QUALIFIER@\n\ Build Id: @BUILD_ID@\n\ -Platform: Eclipse @PLATFORM_VERSION@\n\ \n\ Copyright (c) 2007 - 2017 Pivotal Software, Inc.\n\ All rights reserved. Visit http://spring.io/tools/sts\n\ diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml b/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml index 092f2d1c6..3e5ae66c6 100644 --- a/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml +++ b/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml @@ -1,8 +1,8 @@ - 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"> + 4.0.0 org.springframework.boot.ide @@ -11,13 +11,48 @@ ../pom.xml - org.springframework.boot.ide.branding - eclipse-plugin + org.springframework.boot.ide.branding + eclipse-plugin - org.springframework.boot.ide.branding + org.springframework.boot.ide.branding - + + + org.apache.maven.plugins + maven-antrun-plugin + 1.7 + + + add-version-details-about-dialog + validate + + + + + + + + + + + + + + + + + + + + + + run + + + + + org.eclipse.tycho tycho-p2-plugin @@ -33,5 +68,5 @@ - + From 4248d69e6b3ee94bf62677b71cc8170530c51c7a Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Tue, 22 Aug 2017 12:21:28 +0200 Subject: [PATCH 4/7] fixed wrong path for qualifier replacements --- .../org.springframework.boot.ide.branding/pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml b/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml index 3e5ae66c6..dbfd6a65e 100644 --- a/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml +++ b/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml @@ -38,10 +38,10 @@ - - - - + + + + From a80acf88725760c249d908c4af6f8d6be2c37213 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Tue, 22 Aug 2017 12:32:56 +0200 Subject: [PATCH 5/7] next attempt to fix qualifier replacements --- .../org.springframework.boot.ide.branding/pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml b/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml index dbfd6a65e..3b2d3cf55 100644 --- a/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml +++ b/eclipse-distribution/org.springframework.boot.ide.branding/pom.xml @@ -38,10 +38,10 @@ - - - - + + + + From 4bdeec295a51539282c13572aa16055d2af797ee Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Tue, 22 Aug 2017 17:00:33 +0200 Subject: [PATCH 6/7] integrated dynamic and automatic identification of running boot apps to grab property information for hovers --- .../boot-java-language-server/pom.xml | 5 ++ .../boot/java/hover/ValueHoverProvider.java | 84 ++++++++++--------- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/headless-services/boot-java-language-server/pom.xml b/headless-services/boot-java-language-server/pom.xml index 0fc1279a4..6b5b5e5db 100644 --- a/headless-services/boot-java-language-server/pom.xml +++ b/headless-services/boot-java-language-server/pom.xml @@ -62,6 +62,11 @@ commons-yaml ${dependencies.version} + + org.springframework.ide.vscode + commons-boot-app-cli + ${dependencies.version} + diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/ValueHoverProvider.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/ValueHoverProvider.java index 3781b68d9..a17941e10 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/ValueHoverProvider.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/ValueHoverProvider.java @@ -10,15 +10,12 @@ *******************************************************************************/ 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.Map; 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; @@ -29,7 +26,7 @@ import org.eclipse.lsp4j.MarkedString; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.json.JSONObject; -import org.json.JSONTokener; +import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; import org.springframework.ide.vscode.commons.util.text.TextDocument; /** @@ -69,32 +66,37 @@ public class ValueHoverProvider { 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 (propertyKey != null) { + JSONObject[] allProperties = getPropertiesFromProcesses(); - if (props.has(propertyKey)) { - String propertyValue = props.getString(propertyKey); + List> hoverContent = new ArrayList<>(); - Range hoverRange = doc.toRange(nodeStartOffset + range.getStart(), range.getEnd() - range.getStart()); + for (int i = 0; i < allProperties.length; i++) { + Iterator keys = allProperties[i].keys(); + while (keys.hasNext()) { + String key = (String) keys.next(); + if (allProperties[i].get(key) instanceof JSONObject) { + JSONObject props = allProperties[i].getJSONObject(key); - Hover hover = new Hover(); - List> hoverContent = new ArrayList<>(); + if (props.has(propertyKey)) { + String propertyValue = props.getString(propertyKey); - hoverContent.add(Either.forLeft("property value for " + propertyKey)); - hoverContent.add(Either.forLeft(propertyValue)); - hoverContent.add(Either.forLeft("coming from:")); - hoverContent.add(Either.forLeft(key)); - - hover.setContents(hoverContent); - hover.setRange(hoverRange); - - return CompletableFuture.completedFuture(hover); + hoverContent.add(Either.forLeft("property value for " + propertyKey)); + hoverContent.add(Either.forLeft(propertyValue)); + hoverContent.add(Either.forLeft("coming from:")); + hoverContent.add(Either.forLeft(key)); + } + } } } + + Range hoverRange = doc.toRange(nodeStartOffset + range.getStart(), range.getEnd() - range.getStart()); + Hover hover = new Hover(); + + hover.setContents(hoverContent); + hover.setRange(hoverRange); + + return CompletableFuture.completedFuture(hover); } } } @@ -105,26 +107,30 @@ public class ValueHoverProvider { return null; } - public JSONObject getPropertiesFromProcess() { + public JSONObject[] getPropertiesFromProcesses() { + List result = new ArrayList<>(); + 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; + Map apps = SpringBootApp.getAllRunningJavaApps(); + Iterator appsIter = apps.values().iterator(); + while (appsIter.hasNext()) { + SpringBootApp app = appsIter.next(); + if (app.isSpringBootApp()) { + String environment = app.getEnvironment(); + if (environment != null) { + JSONObject env = new JSONObject(environment); + if (env != null) { + result.add(env); + } + } + } + } } catch (Exception e) { e.printStackTrace(); } - return null; + return result.toArray(new JSONObject[result.size()]); } public String getPropertyKey(String value, int offset) { From a6d10441f8ac2437f3248a8931d0e2acea146b78 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Wed, 23 Aug 2017 16:35:51 +0200 Subject: [PATCH 7/7] first prototype to display request mapping information from running apps as hover on source code --- .../java/hover/BootJavaHoverProvider.java | 14 ++ .../hover/RequestMappingHoverProvider.java | 136 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/RequestMappingHoverProvider.java diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/BootJavaHoverProvider.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/BootJavaHoverProvider.java index 8771d2dd5..6e0b0f5c9 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/BootJavaHoverProvider.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/BootJavaHoverProvider.java @@ -41,6 +41,13 @@ public class BootJavaHoverProvider implements HoverHandler { private static final String SPRING_VALUE = "org.springframework.beans.factory.annotation.Value"; + private static final String SPRING_REQUEST_MAPPING = "org.springframework.web.bind.annotation.RequestMapping"; + private static final String SPRING_GET_MAPPING = "org.springframework.web.bind.annotation.GetMapping"; + private static final String SPRING_POST_MAPPING = "org.springframework.web.bind.annotation.PostMapping"; + private static final String SPRING_PUT_MAPPING = "org.springframework.web.bind.annotation.PutMapping"; + private static final String SPRING_DELETE_MAPPING = "org.springframework.web.bind.annotation.DeleteMapping"; + private static final String SPRING_PATCH_MAPPING = "org.springframework.web.bind.annotation.PatchMapping"; + private JavaProjectFinder projectFinder; private SimpleLanguageServer server; @@ -123,6 +130,13 @@ public class BootJavaHoverProvider implements HoverHandler { private CompletableFuture 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); + } else if (type.getQualifiedName().equals(SPRING_REQUEST_MAPPING) + || type.getQualifiedName().equals(SPRING_GET_MAPPING) + || type.getQualifiedName().equals(SPRING_POST_MAPPING) + || type.getQualifiedName().equals(SPRING_PUT_MAPPING) + || type.getQualifiedName().equals(SPRING_DELETE_MAPPING) + || type.getQualifiedName().equals(SPRING_PATCH_MAPPING)) { + return new RequestMappingHoverProvider().provideHoverForRequestMappingAnnotation(node, annotation, type, offset, doc); } return null; diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/RequestMappingHoverProvider.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/RequestMappingHoverProvider.java new file mode 100644 index 000000000..d24509701 --- /dev/null +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/hover/RequestMappingHoverProvider.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * 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.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.Annotation; +import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.MemberValuePair; +import org.eclipse.jdt.core.dom.NormalAnnotation; +import org.eclipse.jdt.core.dom.SingleMemberAnnotation; +import org.eclipse.jdt.core.dom.StringLiteral; +import org.eclipse.lsp4j.Hover; +import org.eclipse.lsp4j.MarkedString; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.jsonrpc.messages.Either; +import org.json.JSONObject; +import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; +import org.springframework.ide.vscode.commons.util.text.TextDocument; + +/** + * @author Martin Lippert + */ +public class RequestMappingHoverProvider { + + public CompletableFuture provideHoverForRequestMappingAnnotation(ASTNode node, Annotation annotation, + ITypeBinding type, int offset, TextDocument doc) { + return provideHover(annotation, doc); + } + + private CompletableFuture provideHover(Annotation annotation, TextDocument doc) { + + try { + JSONObject[] mappings = getRequestMappingsFromProcesses(); + + List> hoverContent = new ArrayList<>(); + + for (int i = 0; i < mappings.length; i++) { + addHoverContent(mappings[i], hoverContent, annotation); + } + + + Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength()); + Hover hover = new Hover(); + + hover.setContents(hoverContent); + hover.setRange(hoverRange); + + return CompletableFuture.completedFuture(hover); + } + catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + private void addHoverContent(JSONObject jsonObject, List> hoverContent, Annotation annotation) { + Iterator keys = jsonObject.keys(); + while (keys.hasNext()) { + String key = keys.next(); + if (doesMatch(annotation, key)) { + hoverContent.add(Either.forLeft(key)); + hoverContent.add(Either.forLeft(jsonObject.get(key).toString())); + } + } + } + + private boolean doesMatch(Annotation annotation, String key) { + String mappingPath = null; + if (annotation instanceof SingleMemberAnnotation) { + Expression valueContent = ((SingleMemberAnnotation) annotation).getValue(); + if (valueContent instanceof StringLiteral) { + mappingPath = ((StringLiteral)valueContent).getLiteralValue(); + } + } + else if (annotation instanceof NormalAnnotation) { + List values = ((NormalAnnotation) annotation).values(); + for (Object value : values) { + if (value instanceof MemberValuePair) { + String name = ((MemberValuePair)value).getName().toString(); + if (name != null && name.equals("value")) { + Expression valueContent = ((MemberValuePair)value).getValue(); + if (valueContent instanceof StringLiteral) { + mappingPath = ((StringLiteral)valueContent).getLiteralValue(); + } + } + } + } + + } + + return mappingPath != null ? key.contains(mappingPath) : false; + } + + public JSONObject[] getRequestMappingsFromProcesses() { + List result = new ArrayList<>(); + + try { + Map apps = SpringBootApp.getAllRunningJavaApps(); + Iterator appsIter = apps.values().iterator(); + while (appsIter.hasNext()) { + SpringBootApp app = appsIter.next(); + if (app.isSpringBootApp()) { + String mappings = app.getRequestMappings(); + if (mappings != null) { + JSONObject requestMappings = new JSONObject(mappings); + if (requestMappings != null) { + result.add(requestMappings); + } + } + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + + return result.toArray(new JSONObject[result.size()]); + } + +}