Refine request mappings
This commit is contained in:
@@ -11,15 +11,15 @@
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.eclipse.lsp4j.SymbolInformation;
|
||||
import org.eclipse.lsp4j.SymbolKind;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
@@ -44,7 +44,12 @@ public class LiveAppURLSymbolProvider {
|
||||
SpringBootApp[] runningApps = runningAppProvider.getAllRunningSpringApps().toArray(new SpringBootApp[0]);
|
||||
for (SpringBootApp app : runningApps) {
|
||||
try {
|
||||
collectLiveAppSymbols(result, app);
|
||||
String host = app.getHost();
|
||||
String port = app.getPort();
|
||||
Stream<String> urls = app.getRequestMappings().stream()
|
||||
.flatMap(rm -> Arrays.stream(rm.getSplitPath()))
|
||||
.map(path -> UrlUtil.createUrl(host, port, path));
|
||||
urls.forEach(url -> result.add(new SymbolInformation(url, SymbolKind.Method, new Location(url, new Range(new Position(0, 0), new Position(0, 1))))));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Log.log(e);
|
||||
@@ -57,21 +62,4 @@ public class LiveAppURLSymbolProvider {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void collectLiveAppSymbols(List<SymbolInformation> result, SpringBootApp app) throws Exception {
|
||||
String mappings = app.getRequestMappings();
|
||||
JSONObject requestMappings = new JSONObject(mappings);
|
||||
Iterator<String> keys = requestMappings.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
String extractedPath = UrlUtil.extractPath(key);
|
||||
if (extractedPath != null) {
|
||||
String[] splitPath = UrlUtil.splitPath(extractedPath);
|
||||
for (String path : splitPath) {
|
||||
String url = UrlUtil.createUrl(app.getHost(), app.getPort(), path);
|
||||
result.add(new SymbolInformation(url, SymbolKind.Method, new Location(url, new Range(new Position(0, 0), new Position(0, 1)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,20 +11,27 @@
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.Annotation;
|
||||
import org.eclipse.jdt.core.dom.ArrayInitializer;
|
||||
import org.eclipse.jdt.core.dom.Expression;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MemberValuePair;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.NormalAnnotation;
|
||||
import org.eclipse.jdt.core.dom.QualifiedName;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.core.dom.StringLiteral;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
@@ -32,17 +39,18 @@ 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.boot.java.handlers.HoverProvider;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.java.parser.JLRMethodParser;
|
||||
import org.springframework.ide.vscode.commons.java.parser.JLRMethodParser.JLRMethod;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMapping;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@@ -58,7 +66,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<Tuple2<RequestMapping, SpringBootApp>> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
if (val.isPresent()) {
|
||||
Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength());
|
||||
return ImmutableList.of(hoverRange);
|
||||
@@ -77,7 +85,7 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
try {
|
||||
List<Either<String, MarkedString>> hoverContent = new ArrayList<>();
|
||||
|
||||
Optional<RequestMappingMethod> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
Optional<Tuple2<RequestMapping, SpringBootApp>> val = getRequestMappingMethodFromRunningApp(annotation, runningApps);
|
||||
|
||||
if (val.isPresent()) {
|
||||
addHoverContent(val.get(), hoverContent);
|
||||
@@ -97,25 +105,18 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Optional<RequestMappingMethod> getRequestMappingMethodFromRunningApp(Annotation annotation,
|
||||
private Optional<Tuple2<RequestMapping, SpringBootApp>> getRequestMappingMethodFromRunningApp(Annotation annotation,
|
||||
SpringBootApp[] runningApps) {
|
||||
|
||||
try {
|
||||
for (SpringBootApp app : runningApps) {
|
||||
String mappings = app.getRequestMappings();
|
||||
if (mappings!=null) {
|
||||
JSONObject requestMappings = new JSONObject(mappings);
|
||||
String rawPath = getRawPath(annotation, requestMappings);
|
||||
if (rawPath != null) {
|
||||
String path = UrlUtil.extractPath(rawPath);
|
||||
if (path != null) {
|
||||
String rawMethod = getRawMethod(annotation, requestMappings);
|
||||
JLRMethod parsedMethod = JLRMethodParser.parse(rawMethod);
|
||||
if (methodMatchesAnnotation(annotation, parsedMethod)) {
|
||||
return Optional.of(new RequestMappingMethod(path, parsedMethod, app));
|
||||
}
|
||||
}
|
||||
}
|
||||
Collection<RequestMapping> mappings = app.getRequestMappings();
|
||||
if (mappings!=null && !mappings.isEmpty()) {
|
||||
return mappings.stream()
|
||||
.filter(rm -> matchesAnnotation(annotation, rm))
|
||||
.filter(rm -> methodMatchesAnnotation(annotation, rm))
|
||||
.map(rm -> Tuples.of(rm, app))
|
||||
.findFirst();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -124,16 +125,19 @@ public class RequestMappingHoverProvider implements HoverProvider {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private boolean methodMatchesAnnotation(Annotation annotation, JLRMethod requestMappingMethod) {
|
||||
String rqClassName = requestMappingMethod.getFQClassName();
|
||||
String rqMethod = requestMappingMethod.getMethodName();
|
||||
private boolean methodMatchesAnnotation(Annotation annotation, RequestMapping rm) {
|
||||
String rqClassName = rm.getFullyQualifiedClassName();
|
||||
|
||||
ASTNode parent = annotation.getParent();
|
||||
if (parent instanceof MethodDeclaration) {
|
||||
MethodDeclaration methodDec = (MethodDeclaration) parent;
|
||||
IMethodBinding binding = methodDec.resolveBinding();
|
||||
return binding.getDeclaringClass().getQualifiedName().equals(rqClassName) &&
|
||||
binding.getName().equals(rqMethod);
|
||||
return binding.getDeclaringClass().getQualifiedName().equals(rqClassName)
|
||||
&& binding.getName().equals(rm.getMethodName())
|
||||
&& Arrays.equals(Arrays.stream(binding.getParameterTypes())
|
||||
.map(t -> t.getQualifiedName())
|
||||
.toArray(String[]::new),
|
||||
rm.getMethodParameters());
|
||||
} else if (parent instanceof TypeDeclaration) {
|
||||
TypeDeclaration typeDec = (TypeDeclaration) parent;
|
||||
return typeDec.resolveBinding().getQualifiedName().equals(rqClassName);
|
||||
@@ -141,113 +145,156 @@ 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(Tuple2<RequestMapping, SpringBootApp> mappingMethod, List<Either<String, MarkedString>> hoverContent) throws Exception {
|
||||
String processId = mappingMethod.getT2().getProcessID();
|
||||
String processName = mappingMethod.getT2().getProcessName();
|
||||
String port = mappingMethod.getT2().getPort();
|
||||
String host = mappingMethod.getT2().getHost();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
String port = mappingMethod.app.getPort();
|
||||
String host = mappingMethod.app.getHost();
|
||||
String url = UrlUtil.createUrl(host, port, path);
|
||||
Arrays.stream(mappingMethod.getT1().getSplitPath()).forEach(path -> {
|
||||
|
||||
builder.append("Path: ");
|
||||
builder.append("[");
|
||||
builder.append(path);
|
||||
builder.append("]");
|
||||
builder.append("(");
|
||||
builder.append(url);
|
||||
builder.append(")");
|
||||
String url = UrlUtil.createUrl(host, port, path);
|
||||
|
||||
if (builder.length() > 0) {
|
||||
builder.append("\n");
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
private String getRawMethod(Annotation annotation, JSONObject mappings) {
|
||||
Iterator<String> keys = mappings.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
if (matchesAnnotation(annotation, key)) {
|
||||
Object ob= mappings.get(key);
|
||||
if (ob instanceof JSONObject) {
|
||||
JSONObject methodMap = (JSONObject) ob;
|
||||
return methodMap.getString("method");
|
||||
}
|
||||
protected String getRequestMethod(SingleMemberAnnotation annotation) {
|
||||
ITypeBinding type = annotation.resolveTypeBinding();
|
||||
if (type != null) {
|
||||
switch (type.getQualifiedName()) {
|
||||
case Constants.SPRING_GET_MAPPING:
|
||||
return "GET";
|
||||
case Constants.SPRING_POST_MAPPING:
|
||||
return "POST";
|
||||
case Constants.SPRING_DELETE_MAPPING:
|
||||
return "DELETE";
|
||||
case Constants.SPRING_PUT_MAPPING:
|
||||
return "PUT";
|
||||
case Constants.SPRING_PATCH_MAPPING:
|
||||
return "PATCH";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getRawPath(Annotation annotation, JSONObject mappings) {
|
||||
Iterator<String> keys = mappings.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
if (matchesAnnotation(annotation, key)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean matchesAnnotation(Annotation annotation, String jsonKey) {
|
||||
String mappingPath = null;
|
||||
private boolean matchesAnnotation(Annotation annotation, RequestMapping rm) {
|
||||
String[] mappingPath = null;
|
||||
Set<String> methods = null;
|
||||
if (annotation instanceof SingleMemberAnnotation) {
|
||||
Expression valueContent = ((SingleMemberAnnotation) annotation).getValue();
|
||||
SingleMemberAnnotation singleAnnotation = (SingleMemberAnnotation) annotation;
|
||||
Expression valueContent = singleAnnotation.getValue();
|
||||
if (valueContent instanceof StringLiteral) {
|
||||
mappingPath = ((StringLiteral)valueContent).getLiteralValue();
|
||||
mappingPath = new String[] { ((StringLiteral)valueContent).getLiteralValue() };
|
||||
}
|
||||
String method = getRequestMethod(singleAnnotation);
|
||||
if (method != null) {
|
||||
methods = new HashSet<>();
|
||||
methods.add(method);
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
MemberValuePair pair = (MemberValuePair)value;
|
||||
String name = pair.getName().toString();
|
||||
switch (name) {
|
||||
case "value":
|
||||
case "path":
|
||||
mappingPath = getPaths(pair.getValue());
|
||||
break;
|
||||
case "method":
|
||||
methods = getRequestMethod(pair.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return mappingPath != null ? jsonKey.contains(mappingPath) : false;
|
||||
if (mappingPath != null) {
|
||||
if (Arrays.equals(mappingPath, rm.getSplitPath())) {
|
||||
if (methods == null || methods.isEmpty()) {
|
||||
return true;
|
||||
} else {
|
||||
return methods.equals(rm.getRequestMethods());
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public JSONObject[] getRequestMappingsFromProcesses(SpringBootApp[] runningApps) {
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
private static String getExpressionValueAsString(Expression exp) {
|
||||
if (exp instanceof StringLiteral) {
|
||||
return ((StringLiteral)exp).getLiteralValue();
|
||||
} else if (exp instanceof QualifiedName) {
|
||||
return getExpressionValueAsString(((QualifiedName)exp).getName());
|
||||
} else if (exp instanceof SimpleName) {
|
||||
return ((SimpleName)exp).getIdentifier();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
for (SpringBootApp app : runningApps) {
|
||||
String mappings = app.getRequestMappings();
|
||||
if (mappings != null) {
|
||||
JSONObject requestMappings = new JSONObject(mappings);
|
||||
if (requestMappings != null) {
|
||||
result.add(requestMappings);
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private static String[] getPaths(Expression exp) {
|
||||
if (exp instanceof ArrayInitializer) {
|
||||
ArrayInitializer array = (ArrayInitializer) exp;
|
||||
return ((List<Expression>)array.expressions()).stream()
|
||||
.map(e -> getExpressionValueAsString(e))
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(String[]::new);
|
||||
} else {
|
||||
String rm = getExpressionValueAsString(exp);
|
||||
if (rm != null) {
|
||||
return new String[] { rm };
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return result.toArray(new JSONObject[result.size()]);
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Set<String> getRequestMethod(Expression exp) {
|
||||
if (exp instanceof ArrayInitializer) {
|
||||
ArrayInitializer array = (ArrayInitializer) exp;
|
||||
return ((List<Expression>)array.expressions()).stream()
|
||||
.map(e -> getExpressionValueAsString(e))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
} else {
|
||||
String rm = getExpressionValueAsString(exp);
|
||||
if (rm != null) {
|
||||
HashSet<String> methods = new HashSet<>();
|
||||
methods.add(rm);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static class RequestMappingMethod {
|
||||
|
||||
public final SpringBootApp app;
|
||||
public final String requestMappingPath;
|
||||
public final JLRMethod requestMappingMethod;
|
||||
public final RequestMapping requestMapping;
|
||||
|
||||
public RequestMappingMethod(String requestMappingPath, JLRMethod requestMappingMethod, SpringBootApp app) {
|
||||
this.requestMappingPath = requestMappingPath;
|
||||
this.requestMappingMethod = requestMappingMethod;
|
||||
public RequestMappingMethod(RequestMapping requestMapping, SpringBootApp app) {
|
||||
this.requestMapping = requestMapping;
|
||||
this.app = app;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,41 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class UrlUtil {
|
||||
|
||||
|
||||
public static Stream<String> processOrPaths(String pathExp) {
|
||||
if (pathExp.contains("||")) {
|
||||
String[] paths = pathExp.split(Pattern.quote("||"));
|
||||
return Stream.of(paths).map(String::trim);
|
||||
} else {
|
||||
return Stream.of(pathExp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String extractPath(String key) {
|
||||
if (key.startsWith("{[")) { //Case 2 (see above)
|
||||
//An almost json string. Unfortunately not really json so we can't
|
||||
//use org.json or jackson Mapper to properly parse this.
|
||||
int start = 2; //right after first '['
|
||||
int end = key.indexOf(']');
|
||||
if (end>=2) {
|
||||
return key.substring(start, end);
|
||||
}
|
||||
}
|
||||
//Case 1, or some unanticipated stuff.
|
||||
//Assume the key is the path, which is right for Case 1
|
||||
// and probably more useful than null for 'unanticipated stuff'.
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates http URL string based on host, port and path
|
||||
* @param host
|
||||
@@ -67,32 +34,4 @@ public class UrlUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String[] splitPath(String path) {
|
||||
if (path.contains("||")) {
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
String basePath = path.substring(0, path.indexOf("||")).trim();
|
||||
result.add(basePath);
|
||||
|
||||
if (basePath.lastIndexOf('/') > 0) {
|
||||
basePath = basePath.substring(0, basePath.lastIndexOf('/'));
|
||||
}
|
||||
|
||||
String additionalPaths = path.substring(path.indexOf("||"));
|
||||
StringTokenizer tokenizer = new StringTokenizer(additionalPaths, "||");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String token = tokenizer.nextToken().trim();
|
||||
if (token.length() > 0) {
|
||||
result.add(basePath + "/" + token);
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray(new String[result.size()]);
|
||||
}
|
||||
else {
|
||||
return new String[] {path};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -132,4 +132,802 @@ public class RequestMappingLiveHoverTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteMappingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[DELETE]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public void com.example.RestApi.deleteGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@DeleteMapping(\"/greetings\")\n" +
|
||||
"public void deleteGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@DeleteMapping(\"/greetings\")", "Path: [/greetings](http://cfapps.io:999/greetings)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDeleteMappingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.deleteGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.DeleteMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@DeleteMapping(\"/greetings\")\n" +
|
||||
"public void deleteGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertNoHover("@DeleteMapping(\"/greetings\")");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMappingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.greetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import java.lang.String;\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.GetMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@GetMapping(\"/greetings\")\n" +
|
||||
"public String greetings() {\n" +
|
||||
"return \"Greetings!\";\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@GetMapping(\"/greetings\")", "Path: [/greetings](http://cfapps.io:999/greetings)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMappingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[DELETE]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.greetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import java.lang.String;\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.GetMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@GetMapping(\"/greetings\")\n" +
|
||||
"public String greetings() {\n" +
|
||||
"return \"Greetings!\";\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertNoHover("@GetMapping(\"/greetings\")");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostMappingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[POST]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public void com.example.RestApi.createGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.PostMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@PostMapping(\"/greetings\")\n" +
|
||||
"public void createGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@PostMapping(\"/greetings\")", "Path: [/greetings](http://cfapps.io:999/greetings)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostMappingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.createGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.PostMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@PostMapping(\"/greetings\")\n" +
|
||||
"public void createGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertNoHover("@PostMapping(\"/greetings\")");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutMappingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[PUT]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public void com.example.RestApi.updateGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.PutMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@PutMapping(\"/greetings\")\n" +
|
||||
"public void updateGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@PutMapping(\"/greetings\")", "Path: [/greetings](http://cfapps.io:999/greetings)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPutMappingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.updateGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.PutMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@PutMapping(\"/greetings\")\n" +
|
||||
"public void updateGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertNoHover("@PutMapping(\"/greetings\")");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatchMappingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[PATCH]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public void com.example.RestApi.patchGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.PatchMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@PatchMapping(\"/greetings\")\n" +
|
||||
"public void patchGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@PatchMapping(\"/greetings\")", "Path: [/greetings](http://cfapps.io:999/greetings)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatchMappingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.patchGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.PatchMapping;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@PatchMapping(\"/greetings\")\n" +
|
||||
"public void patchGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertNoHover("@PatchMapping(\"/greetings\")");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiRequestMethodMappingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[POST,PUT]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public void com.example.RestApi.updateGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMethod.*;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@RequestMapping(value=\"/greetings\", method={POST, PUT})\n" +
|
||||
"public void updateGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@RequestMapping(value=\"/greetings\", method={POST, PUT})", "Path: [/greetings](http://cfapps.io:999/greetings)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiRequestMethodMappingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings],methods=[POST,PUT,PATCH]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.updateGreetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMethod.*;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@RequestMapping(value=\"/greetings\", method={POST, PUT})\n" +
|
||||
"public void updateGreetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertNoHover("@RequestMapping(value=\"/greetings\", method={POST, PUT})");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPathMappingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings || /hello],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.greetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMethod.*;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@RequestMapping(value={\"/greetings\", \"/hello\"}, method=GET)\n" +
|
||||
"public String greetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@RequestMapping(value={\"/greetings\", \"/hello\"}, method=GET)", "Path: [/greetings](http://cfapps.io:999/greetings)\n" +
|
||||
"Path: [/hello](http://cfapps.io:999/hello)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPathMappingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/greetings || /hello || /helloAgain],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.String com.example.RestApi.greetings()\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMethod.*;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@RequestMapping(value={\"/greetings\", \"/hello\"}, method=GET)\n" +
|
||||
"public String greetings() {\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertNoHover("@RequestMapping(value={\"/greetings\", \"/hello\"}, method=GET)");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodMatchingHoverHintMethod1() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public org.springframework.http.ResponseEntity<?> com.example.RestApi.find(java.lang.String,java.util.Date,java.lang.String)\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.http.ResponseEntity;\n" +
|
||||
"import java.lang.String;\n" +
|
||||
"import java.util.Date;\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMethod.*;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@RequestMapping(value=\"/find\", method=GET)\n" +
|
||||
"public ResponseEntity<?> find(String p1, Date p2, String p3) {\n" +
|
||||
"return null;\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@RequestMapping(value=\"/find\", method=GET)", "Path: [/find](http://cfapps.io:999/find)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodMatchingHoverHintMethod2() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String,java.util.Map<java.lang.String, java.lang.String>)\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.http.ResponseEntity;\n" +
|
||||
"import java.lang.String;\n" +
|
||||
"import java.util.Map;\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMethod.*;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@RequestMapping(value=\"/find\", method=GET)\n" +
|
||||
"public Object set(String p1, Map<String, String> p2) {\n" +
|
||||
"return null;\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@RequestMapping(value=\"/find\", method=GET)", "Path: [/find](http://cfapps.io:999/find)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodMatchingHoverHintMethod3() 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 a mock running boot app
|
||||
mockAppProvider.builder()
|
||||
.isSpringBootApp(true)
|
||||
.port("999")
|
||||
.processId("76543")
|
||||
.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(
|
||||
"{\"{[/find],methods=[GET]}\": {\"bean\": \"requestMappingHandlerMapping\", \"method\":\"public java.lang.Object com.example.RestApi.set(java.lang.String,java.util.Map<java.lang.String, java.util.Map<java.lang.String, java.lang.Integer>>)\"}}")
|
||||
. build();
|
||||
|
||||
harness.intialize(directory);
|
||||
|
||||
Editor editor = harness.newEditor(LanguageId.JAVA,
|
||||
"package com.example;\n" +
|
||||
"\n" +
|
||||
"import org.springframework.http.ResponseEntity;\n" +
|
||||
"import java.lang.String;\n" +
|
||||
"import java.lang.Integer;\n" +
|
||||
"import java.util.Map;\n" +
|
||||
"import org.springframework.stereotype.Controller;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMapping;\n" +
|
||||
"import org.springframework.web.bind.annotation.RequestMethod.*;\n" +
|
||||
"\n" +
|
||||
"@Controller\n" +
|
||||
"public class RestApi {\n" +
|
||||
"\n" +
|
||||
"@RequestMapping(value=\"/find\", method=GET)\n" +
|
||||
"public Object set(String p1, Map<String, Map<String, Integer>> p2) {\n" +
|
||||
"return null;\n" +
|
||||
"}\n" +
|
||||
"\n" +
|
||||
"}",
|
||||
docUri);
|
||||
|
||||
editor.assertHoverContains("@RequestMapping(value=\"/find\", method=GET)", "Path: [/find](http://cfapps.io:999/find)\n" +
|
||||
"\n" +
|
||||
"Process ID: 76543\n" +
|
||||
"\n" +
|
||||
"Process Name: test-request-mapping-live-hover");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ import java.util.Collection;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMapping;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness.Builder;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
@@ -97,7 +97,8 @@ public class MockRunningAppProvider {
|
||||
}
|
||||
|
||||
public MockAppBuilder getRequestMappings(String mappings) throws Exception {
|
||||
when(app.getRequestMappings()).thenReturn(mappings);
|
||||
Collection<RequestMapping> requestMappings = SpringBootApp.parseRequestMappingsJson(mappings);
|
||||
when(app.getRequestMappings()).thenReturn(requestMappings);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>commons-java</artifactId>
|
||||
<groupId>org.springframework.ide.vscode</groupId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -13,7 +13,9 @@ package org.springframework.ide.vscode.commons.boot.app.cli;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -30,6 +32,8 @@ import javax.management.remote.JMXServiceURL;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMapping;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMappingImpl1;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -186,17 +190,29 @@ public class SpringBootApp {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getRequestMappings() throws Exception {
|
||||
public static Collection<RequestMapping> parseRequestMappingsJson(String json) {
|
||||
JSONObject obj = new JSONObject(json);
|
||||
Iterator<String> keys = obj.keys();
|
||||
List<RequestMapping> result = new ArrayList<>();
|
||||
while (keys.hasNext()) {
|
||||
String rawKey = keys.next();
|
||||
JSONObject value = obj.getJSONObject(rawKey);
|
||||
result.add(new RequestMappingImpl1(rawKey, value));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<RequestMapping> getRequestMappings() throws Exception {
|
||||
Object result = getActuatorDataFromAttribute("org.springframework.boot:type=Endpoint,name=requestMappingEndpoint", "Data");
|
||||
if (result != null) {
|
||||
String mappings = new ObjectMapper().writeValueAsString(result);
|
||||
return mappings;
|
||||
return parseRequestMappingsJson(mappings);
|
||||
}
|
||||
|
||||
result = getActuatorDataFromOperation("org.springframework.boot:type=Endpoint,name=Mappings", "mappings");
|
||||
if (result != null) {
|
||||
String mappings = new ObjectMapper().writeValueAsString(result);
|
||||
return mappings;
|
||||
return parseRequestMappingsJson(mappings);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* 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.boot.app.cli.requestmappings;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface RequestMapping {
|
||||
String getPath();
|
||||
String[] getSplitPath();
|
||||
String getFullyQualifiedClassName();
|
||||
String getMethodName();
|
||||
String[] getMethodParameters();
|
||||
String getMethodString();
|
||||
Set<String> getRequestMethods();
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*******************************************************************************
|
||||
* 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.boot.app.cli.requestmappings;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.ide.vscode.commons.java.parser.JLRMethodParser;
|
||||
import org.springframework.ide.vscode.commons.java.parser.JLRMethodParser.JLRMethod;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
public class RequestMappingImpl1 implements RequestMapping {
|
||||
|
||||
private static final Pattern REQUEST_METHODS_PATTERN = Pattern.compile(".*methods=\\[(.*)\\].*");
|
||||
|
||||
/*
|
||||
There are two styles of entries:
|
||||
|
||||
1) key is a 'path' String. May contain patters like "**"
|
||||
"/** /favicon.ico":{
|
||||
"bean":"faviconHandlerMapping"
|
||||
}
|
||||
|
||||
2) key is a 'almost json' String
|
||||
"{[/bye],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}":{
|
||||
"bean":"requestMappingHandlerMapping",
|
||||
"method":"public java.lang.String demo.MyController.bye()"
|
||||
}
|
||||
*/
|
||||
|
||||
private JSONObject beanInfo;
|
||||
private String pathKey;
|
||||
private Supplier<JLRMethod> methodDataSupplier;
|
||||
private Supplier<Set<String>> requestMethodsSupplier;
|
||||
private Supplier<String> requestPathSupplier;
|
||||
|
||||
public RequestMappingImpl1(String pathKey, JSONObject beanInfo) {
|
||||
this.pathKey = pathKey;
|
||||
this.beanInfo = beanInfo;
|
||||
this.requestMethodsSupplier = Suppliers.memoize(() -> parseRequestMethods());
|
||||
this.requestPathSupplier = Suppliers.memoize(() -> parseRequestPath());
|
||||
this.methodDataSupplier = Suppliers.memoize(() -> JLRMethodParser.parse(getMethodString()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath() {
|
||||
return requestPathSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RequestMapping("+pathKey+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFullyQualifiedClassName() {
|
||||
JLRMethod m = getMethodData();
|
||||
if (m!=null) {
|
||||
return m.getFQClassName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodName() {
|
||||
JLRMethod m = getMethodData();
|
||||
if (m!=null) {
|
||||
return m.getMethodName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw string found in the requestmapping info. This is a 'toString' value
|
||||
* of java.lang.reflect.Method object.
|
||||
*/
|
||||
@Override
|
||||
public String getMethodString() {
|
||||
try {
|
||||
if (beanInfo!=null) {
|
||||
if (beanInfo.has("method")) {
|
||||
return beanInfo.getString("method");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private JLRMethod getMethodData() {
|
||||
return methodDataSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return pathKey.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RequestMappingImpl1 other = (RequestMappingImpl1) obj;
|
||||
return Objects.equal(this.pathKey, other.pathKey)
|
||||
&& Objects.equal(this.getMethodString(), other.getMethodString());
|
||||
}
|
||||
|
||||
protected Set<String> parseRequestMethods() {
|
||||
Matcher matcher = REQUEST_METHODS_PATTERN.matcher(pathKey);
|
||||
if (matcher.matches()) {
|
||||
return Arrays.stream(matcher.group(1).split("\\s*,\\s*")).collect(Collectors.toSet());
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
protected String parseRequestPath() {
|
||||
if (pathKey.startsWith("{[")) { //Case 2 (see above)
|
||||
//An almost json string. Unfortunately not really json so we can't
|
||||
//use org.json or jackson Mapper to properly parse this.
|
||||
int start = 2; //right after first '['
|
||||
int end = pathKey.indexOf(']');
|
||||
if (end>=2) {
|
||||
return pathKey.substring(start, end);
|
||||
}
|
||||
}
|
||||
//Case 1, or some unanticipated stuff.
|
||||
//Assume the key is the path, which is right for Case 1
|
||||
// and probably more useful than null for 'unanticipated stuff'.
|
||||
return pathKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRequestMethods() {
|
||||
return requestMethodsSupplier.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSplitPath() {
|
||||
String paths = requestPathSupplier.get();
|
||||
return Arrays.stream(paths.split("\\|\\|")).map(s -> s.trim()).toArray(String[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getMethodParameters() {
|
||||
return getMethodData().getParameters();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,38 +8,38 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping.test;
|
||||
package org.springframework.ide.vscode.commons.boot.app.cli;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.boot.java.requestmapping.UrlUtil;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMappingImpl1;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
public class UrlUtilTest {
|
||||
public class RequestMappingImp1Test {
|
||||
|
||||
@Test
|
||||
public void testSplitPathWithoutDuplicate() {
|
||||
String path = "/superpath";
|
||||
String[] splitPath = UrlUtil.splitPath(path);
|
||||
RequestMappingImpl1 rm = new RequestMappingImpl1("/superpath", null);
|
||||
String[] splitPath = rm.getSplitPath();
|
||||
assertEquals(1, splitPath.length);
|
||||
assertEquals("/superpath", splitPath[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSplitPathSimpleCaseWithEmptyOr() {
|
||||
String path = "/superpath/mypath || ";
|
||||
String[] splitPath = UrlUtil.splitPath(path);
|
||||
RequestMappingImpl1 rm = new RequestMappingImpl1("/superpath/mypath || ", null);
|
||||
String[] splitPath = rm.getSplitPath();
|
||||
assertEquals(1, splitPath.length);
|
||||
assertEquals("/superpath/mypath", splitPath[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSplitPathSimpleCase() {
|
||||
String path = "/superpath/mypath || mypath.json";
|
||||
String[] splitPath = UrlUtil.splitPath(path);
|
||||
RequestMappingImpl1 rm = new RequestMappingImpl1("/superpath/mypath || mypath.json", null);
|
||||
String[] splitPath = rm.getSplitPath();
|
||||
assertEquals(2, splitPath.length);
|
||||
assertEquals("/superpath/mypath", splitPath[0]);
|
||||
assertEquals("/superpath/mypath.json", splitPath[1]);
|
||||
@@ -47,8 +47,8 @@ public class UrlUtilTest {
|
||||
|
||||
@Test
|
||||
public void testSplitPathMultipleCases() {
|
||||
String path = "/superpath/mypath || mypath.json || somethingelse.what";
|
||||
String[] splitPath = UrlUtil.splitPath(path);
|
||||
RequestMappingImpl1 rm = new RequestMappingImpl1("/superpath/mypath || mypath.json || somethingelse.what", null);
|
||||
String[] splitPath = rm.getSplitPath();
|
||||
assertEquals(3, splitPath.length);
|
||||
assertEquals("/superpath/mypath", splitPath[0]);
|
||||
assertEquals("/superpath/mypath.json", splitPath[1]);
|
||||
@@ -18,6 +18,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -26,6 +27,7 @@ import org.json.JSONObject;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMapping;
|
||||
import org.springframework.ide.vscode.commons.util.AsyncProcess;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
@@ -139,8 +141,8 @@ public class SpringBootAppTest {
|
||||
@Test
|
||||
public void getRequestMappings() throws Exception {
|
||||
ACondition.waitFor(TIMEOUT, () -> {
|
||||
String result = testApp.getRequestMappings();
|
||||
assertNonEmptyJsonObject(result);
|
||||
Collection<RequestMapping> result = testApp.getRequestMappings();
|
||||
assertTrue(result != null && !result.isEmpty());
|
||||
// System.out.println("requestMappings = "+result);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.java.parser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -32,6 +34,8 @@ public class JLRMethodParser {
|
||||
|
||||
private String fqClass;
|
||||
private String methodName;
|
||||
private String returnType;
|
||||
private String[] parameters;
|
||||
|
||||
//TODO: parsing arguments to handle overloading
|
||||
|
||||
@@ -49,6 +53,7 @@ public class JLRMethodParser {
|
||||
while (modifiersEnd<pieces.length && isModifier(pieces[modifiersEnd])) {
|
||||
modifiersEnd++;
|
||||
}
|
||||
returnType = pieces[modifiersEnd];
|
||||
if (pieces.length>=modifiersEnd+2) {
|
||||
methodString = pieces[modifiersEnd+1];
|
||||
int methodNameEnd = methodString.indexOf('(');
|
||||
@@ -63,6 +68,55 @@ public class JLRMethodParser {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int parametersStart = rawString.indexOf('(');
|
||||
int parametersEnd = rawString.indexOf(')');
|
||||
if (parametersStart < parametersEnd) {
|
||||
String parametersString = rawString.substring(parametersStart + 1, parametersEnd);
|
||||
this.parameters = parseParameters(parametersString);
|
||||
} else {
|
||||
this.parameters = new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
private String[] parseParameters(String parameterString) {
|
||||
List<String> parameters = new ArrayList<>();
|
||||
int openTemplateParameters = 0;
|
||||
StringBuilder currentParameter = new StringBuilder();
|
||||
for (int i = 0; i < parameterString.length(); i++) {
|
||||
char ch = parameterString.charAt(i);
|
||||
switch (ch) {
|
||||
case '.':
|
||||
currentParameter.append(ch);
|
||||
break;
|
||||
case '<':
|
||||
openTemplateParameters++;
|
||||
currentParameter.append(ch);
|
||||
break;
|
||||
case '>':
|
||||
openTemplateParameters--;
|
||||
currentParameter.append(ch);
|
||||
break;
|
||||
case ',' :
|
||||
if (openTemplateParameters == 0) {
|
||||
if (currentParameter.length() != 0) {
|
||||
parameters.add(currentParameter.toString());
|
||||
currentParameter = new StringBuilder();
|
||||
}
|
||||
} else {
|
||||
currentParameter.append(ch);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (Character.isJavaIdentifierPart(ch)) {
|
||||
currentParameter.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentParameter.length() > 0) {
|
||||
parameters.add(currentParameter.toString());
|
||||
}
|
||||
return parameters.toArray(new String[parameters.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,6 +131,14 @@ public class JLRMethodParser {
|
||||
public String getMethodName() {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public String getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public String[] getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user