Added support for multiple apps in request mapping live hovers
This commit is contained in:
@@ -58,7 +58,7 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
public Collection<Range> getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) {
|
||||
try {
|
||||
if (runningApps.length > 0) {
|
||||
Optional<RequestMappingMethod> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
Optional<List<RequestMappingMethod>> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
if (val.isPresent()) {
|
||||
Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength());
|
||||
return ImmutableList.of(hoverRange);
|
||||
@@ -77,7 +77,7 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
try {
|
||||
List<Either<String, MarkedString>> hoverContent = new ArrayList<>();
|
||||
|
||||
Optional<RequestMappingMethod> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
Optional<List<RequestMappingMethod>> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
|
||||
if (val.isPresent()) {
|
||||
addHoverContent(val.get(), hoverContent);
|
||||
@@ -97,13 +97,14 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Optional<RequestMappingMethod> getRequestMappingMethodFromRunningApp(Annotation annotation,
|
||||
private Optional<List<RequestMappingMethod>> getRequestMappingMethodFromRunningApp(Annotation annotation,
|
||||
SpringBootApp[] runningApps) {
|
||||
|
||||
try {
|
||||
List<RequestMappingMethod> methods = new ArrayList<>();
|
||||
for (SpringBootApp app : runningApps) {
|
||||
String mappings = app.getRequestMappings();
|
||||
if (mappings!=null) {
|
||||
if (mappings != null) {
|
||||
JSONObject requestMappings = new JSONObject(mappings);
|
||||
String rawPath = getRawPath(annotation, requestMappings);
|
||||
if (rawPath != null) {
|
||||
@@ -112,12 +113,16 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
String rawMethod = getRawMethod(annotation, requestMappings);
|
||||
JLRMethod parsedMethod = JLRMethodParser.parse(rawMethod);
|
||||
if (methodMatchesAnnotation(annotation, parsedMethod)) {
|
||||
return Optional.of(new RequestMappingMethod(path, parsedMethod, app));
|
||||
methods.add(new RequestMappingMethod(path, parsedMethod, app));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!methods.isEmpty()) {
|
||||
return Optional.of(methods);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
@@ -141,28 +146,37 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addHoverContent(RequestMappingMethod mappingMethod, List<Either<String, MarkedString>> hoverContent) throws Exception {
|
||||
String processId = mappingMethod.app.getProcessID();
|
||||
String processName = mappingMethod.app.getProcessName();
|
||||
String path = mappingMethod.requestMappingPath;
|
||||
private void addHoverContent(List<RequestMappingMethod> mappingMethods, List<Either<String, MarkedString>> hoverContent)
|
||||
throws Exception {
|
||||
for (int i = 0; i < mappingMethods.size() ; i++) {
|
||||
RequestMappingMethod method = mappingMethods.get(i);
|
||||
String processId = method.app.getProcessID();
|
||||
String processName = method.app.getProcessName();
|
||||
String path = method.requestMappingPath;
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
String port = mappingMethod.app.getPort();
|
||||
String host = mappingMethod.app.getHost();
|
||||
String url = UrlUtil.createUrl(host, port, path);
|
||||
String port = method.app.getPort();
|
||||
String host = method.app.getHost();
|
||||
String url = UrlUtil.createUrl(host, port, path);
|
||||
|
||||
builder.append("Path: ");
|
||||
builder.append("[");
|
||||
builder.append(path);
|
||||
builder.append("]");
|
||||
builder.append("(");
|
||||
builder.append(url);
|
||||
builder.append(")");
|
||||
builder.append("Path: ");
|
||||
builder.append("[");
|
||||
builder.append(path);
|
||||
builder.append("]");
|
||||
builder.append("(");
|
||||
builder.append(url);
|
||||
builder.append(")");
|
||||
|
||||
hoverContent.add(Either.forLeft(builder.toString()));
|
||||
hoverContent.add(Either.forLeft("Process ID: " + processId));
|
||||
hoverContent.add(Either.forLeft("Process Name: " + processName));
|
||||
if (i < mappingMethods.size() - 1) {
|
||||
// Three dashes == line separator in Markdown
|
||||
hoverContent.add(Either.forLeft("---"));
|
||||
}
|
||||
}
|
||||
|
||||
hoverContent.add(Either.forLeft(builder.toString()));
|
||||
hoverContent.add(Either.forLeft("Process ID: " + processId));
|
||||
hoverContent.add(Either.forLeft("Process Name: " + processName));
|
||||
}
|
||||
|
||||
private String getRawMethod(Annotation annotation, JSONObject mappings) {
|
||||
@@ -170,7 +184,7 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
if (matchesAnnotation(annotation, key)) {
|
||||
Object ob= mappings.get(key);
|
||||
Object ob = mappings.get(key);
|
||||
if (ob instanceof JSONObject) {
|
||||
JSONObject methodMap = (JSONObject) ob;
|
||||
return methodMap.getString("method");
|
||||
@@ -196,18 +210,18 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
if (annotation instanceof SingleMemberAnnotation) {
|
||||
Expression valueContent = ((SingleMemberAnnotation) annotation).getValue();
|
||||
if (valueContent instanceof StringLiteral) {
|
||||
mappingPath = ((StringLiteral)valueContent).getLiteralValue();
|
||||
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();
|
||||
String name = ((MemberValuePair) value).getName().toString();
|
||||
if (name != null && name.equals("value")) {
|
||||
Expression valueContent = ((MemberValuePair)value).getValue();
|
||||
Expression valueContent = ((MemberValuePair) value).getValue();
|
||||
if (valueContent instanceof StringLiteral) {
|
||||
mappingPath = ((StringLiteral)valueContent).getLiteralValue();
|
||||
mappingPath = ((StringLiteral) valueContent).getLiteralValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,4 +132,75 @@ public class RequestMappingLiveHoverTest {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testMultipleAppsLiveHover() throws Exception {
|
||||
|
||||
File directory = new File(
|
||||
ProjectsHarness.class.getResource("/test-projects/test-request-mapping-live-hover/").toURI());
|
||||
String docUri = "file://" +directory.getAbsolutePath() + "/src/main/java/example/RestApi.java";
|
||||
|
||||
// Build three different instances of the same app running on different ports with different process IDs
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("1000")
|
||||
.processId("70000")
|
||||
.host("cfapps.io")
|
||||
.processName("test-request-mapping-live-hover")
|
||||
// Ugly, but this is real JSON copied from a real live running app. We want the
|
||||
// mock app to return realistic results if possible
|
||||
.getRequestMappings(
|
||||
"{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}")
|
||||
. build();
|
||||
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("1001")
|
||||
.processId("80000")
|
||||
.host("cfapps.io")
|
||||
.processName("test-request-mapping-live-hover")
|
||||
// Ugly, but this is real JSON copied from a real live running app. We want the
|
||||
// mock app to return realistic results if possible
|
||||
.getRequestMappings(
|
||||
"{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}")
|
||||
. build();
|
||||
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("1002")
|
||||
.processId("90000")
|
||||
.host("cfapps.io")
|
||||
.processName("test-request-mapping-live-hover")
|
||||
// Ugly, but this is real JSON copied from a real live running app. We want the
|
||||
// mock app to return realistic results if possible
|
||||
.getRequestMappings(
|
||||
"{\"/webjars/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**\":{\"bean\":\"resourceHandlerMapping\"},\"/**/favicon.ico\":{\"bean\":\"faviconHandlerMapping\"},\"{[/hello-world],methods=[GET]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public example.Greeting example.HelloWorldController.sayHello(java.lang.String)\"},\"{[/goodbye]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.goodbye()\"},\"{[/hello]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public java.lang.String example.RestApi.hello()\"},\"{[/error]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)\"},\"{[/error],produces=[text/html]}\":{\"bean\":\"requestMappingHandlerMapping\",\"method\":\"public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)\"}}")
|
||||
. build();
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditorFromFileUri(docUri, LanguageId.JAVA);
|
||||
editor.assertHoverContains("@RequestMapping(\"/hello\")", "Path: [/hello](http://cfapps.io:1000/hello)\n" +
|
||||
"\n" +
|
||||
"Process ID: 70000\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover\n" +
|
||||
"\n" +
|
||||
"---\n" +
|
||||
"\n" +
|
||||
"Path: [/hello](http://cfapps.io:1001/hello)\n" +
|
||||
"\n" +
|
||||
"Process ID: 80000\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover\n" +
|
||||
"\n" +
|
||||
"---\n" +
|
||||
"\n" +
|
||||
"Path: [/hello](http://cfapps.io:1002/hello)\n" +
|
||||
"\n" +
|
||||
"Process ID: 90000\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user