further improvements to webflux symbol and code lens analysis, including content and accept type identification
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
@@ -19,32 +22,31 @@ import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
*/
|
||||
public class WebfluxAcceptTypeFinder extends ASTVisitor {
|
||||
|
||||
private String acceptType;
|
||||
private Set<String> acceptTypes;
|
||||
|
||||
public WebfluxAcceptTypeFinder() {
|
||||
this.acceptTypes = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public String getAcceptType() {
|
||||
return acceptType;
|
||||
public Set<String> getAcceptTypes() {
|
||||
return acceptTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visit(MethodInvocation node) {
|
||||
boolean visitChildren = true;
|
||||
|
||||
IMethodBinding methodBinding = node.resolveMethodBinding();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(name)) {
|
||||
acceptType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
String acceptType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (acceptType != null) {
|
||||
acceptTypes.add(acceptType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
|
||||
visitChildren = false;
|
||||
}
|
||||
return visitChildren;
|
||||
return !WebfluxUtils.isRouteMethodInvocation(methodBinding);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
@@ -20,15 +23,16 @@ import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
*/
|
||||
public class WebfluxContentTypeFinder extends ASTVisitor {
|
||||
|
||||
private String contentType;
|
||||
private Set<String> contentTypes;
|
||||
private ASTNode root;
|
||||
|
||||
public WebfluxContentTypeFinder(ASTNode root) {
|
||||
this.root = root;
|
||||
this.contentTypes = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
public Set<String> getContentTypes() {
|
||||
return contentTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,7 +45,10 @@ public class WebfluxContentTypeFinder extends ASTVisitor {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(name)) {
|
||||
contentType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
String contentType = WebfluxUtils.extractSimpleNameArgument(node);
|
||||
if (contentType != null) {
|
||||
contentTypes.add(contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,11 +72,16 @@ public class WebfluxHandlerCodeLensProvider implements CodeLensProvider {
|
||||
CodeLens codeLens = new CodeLens();
|
||||
codeLens.setRange(document.toRange(node.getName().getStartPosition(), node.getName().getLength()));
|
||||
|
||||
String codeLensCommand = handlerInfo.getHttpMethod() != null ? handlerInfo.getHttpMethod() + " " : "";
|
||||
String httpMethod = WebfluxUtils.getStringRep(handlerInfo.getHttpMethods(), string -> string);
|
||||
String codeLensCommand = httpMethod != null ? httpMethod + " " : "";
|
||||
|
||||
codeLensCommand += handlerInfo.getPath();
|
||||
|
||||
String acceptType = WebfluxUtils.getStringRep(handlerInfo.getAcceptTypes(), WebfluxUtils::getMediaType);
|
||||
codeLensCommand += acceptType != null ? " - Accept: " + acceptType : "";
|
||||
|
||||
codeLensCommand += handlerInfo.getAcceptType() != null ? " - Accept: " + getMediaType(handlerInfo.getAcceptType()) : "";
|
||||
codeLensCommand += handlerInfo.getContentType() != null ? " - Content-Type: " + getMediaType(handlerInfo.getContentType()) : "";
|
||||
String contentType = WebfluxUtils.getStringRep(handlerInfo.getContentTypes(), WebfluxUtils::getMediaType);
|
||||
codeLensCommand += contentType != null ? " - Content-Type: " + contentType : "";
|
||||
|
||||
codeLens.setCommand(new Command(codeLensCommand, null));
|
||||
|
||||
@@ -89,18 +94,4 @@ public class WebfluxHandlerCodeLensProvider implements CodeLensProvider {
|
||||
}
|
||||
}
|
||||
|
||||
protected String getMediaType(String handlerInfo) {
|
||||
if (handlerInfo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
MediaTypeMapping mediaType = MediaTypeMapping.valueOf(handlerInfo);
|
||||
return mediaType.getMediaType();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
return handlerInfo;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,18 +19,18 @@ public class WebfluxHandlerInformation {
|
||||
private final String handlerMethod;
|
||||
|
||||
private final String path;
|
||||
private final String httpMethod;
|
||||
private final String contentType;
|
||||
private final String acceptType;
|
||||
private final String[] httpMethods;
|
||||
private final String[] contentTypes;
|
||||
private final String[] acceptTypes;
|
||||
|
||||
public WebfluxHandlerInformation(String handlerClass, String handlerMethod, String path, String httpMethod, String contentType, String acceptType) {
|
||||
public WebfluxHandlerInformation(String handlerClass, String handlerMethod, String path, String[] httpMethods, String[] contentTypes, String[] acceptTypes) {
|
||||
this.handlerClass = handlerClass;
|
||||
this.handlerMethod = handlerMethod;
|
||||
|
||||
this.path = path;
|
||||
this.httpMethod = httpMethod;
|
||||
this.contentType = contentType;
|
||||
this.acceptType = acceptType;
|
||||
this.httpMethods = httpMethods;
|
||||
this.contentTypes = contentTypes;
|
||||
this.acceptTypes = acceptTypes;
|
||||
}
|
||||
|
||||
public String getHandlerClass() {
|
||||
@@ -45,16 +45,16 @@ public class WebfluxHandlerInformation {
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getHttpMethod() {
|
||||
return httpMethod;
|
||||
public String[] getHttpMethods() {
|
||||
return httpMethods;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
public String[] getContentTypes() {
|
||||
return contentTypes;
|
||||
}
|
||||
|
||||
public String getAcceptType() {
|
||||
return acceptType;
|
||||
public String[] getAcceptTypes() {
|
||||
return acceptTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
import org.eclipse.jdt.core.dom.ASTVisitor;
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
@@ -20,15 +23,16 @@ import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
*/
|
||||
public class WebfluxMethodFinder extends ASTVisitor {
|
||||
|
||||
private String method;
|
||||
private Set<String> methods;
|
||||
private ASTNode root;
|
||||
|
||||
public WebfluxMethodFinder(ASTNode root) {
|
||||
this.root = root;
|
||||
this.methods = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
public Set<String> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,10 +45,10 @@ public class WebfluxMethodFinder extends ASTVisitor {
|
||||
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
if (name != null && WebfluxUtils.REQUEST_PREDICATE_HTTPMETHOD_METHODS.contains(name)) {
|
||||
method = name;
|
||||
methods.add(name);
|
||||
}
|
||||
else if (name != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(name)) {
|
||||
method = WebfluxUtils.extractQualifiedNameArgument(node);
|
||||
methods.add(WebfluxUtils.extractQualifiedNameArgument(node));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ package org.springframework.ide.vscode.boot.java.requestmapping;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ASTNode;
|
||||
@@ -34,9 +35,6 @@ import org.springframework.ide.vscode.boot.java.handlers.SymbolProvider;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
/**
|
||||
* @author Martin Lippert
|
||||
*/
|
||||
@@ -92,10 +90,10 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
|
||||
protected void extractMappingSymbol(MethodInvocation node, TextDocument doc, List<EnhancedSymbolInformation> result) {
|
||||
String path = extractPath(node);
|
||||
String httpMethod = extractMethod(node);
|
||||
|
||||
String contentType = extractContentType(node);
|
||||
String acceptType = extractAcceptType(node);
|
||||
String[] httpMethods = extractMethods(node);
|
||||
String[] contentTypes = extractContentTypes(node);
|
||||
String[] acceptTypes = extractAcceptTypes(node);
|
||||
|
||||
int methodNameStart = node.getName().getStartPosition();
|
||||
int invocationStart = node.getStartPosition();
|
||||
@@ -103,9 +101,10 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
if (path != null && path.length() > 0) {
|
||||
try {
|
||||
Location location = new Location(doc.getUri(), doc.toRange(methodNameStart, node.getLength() - (methodNameStart - invocationStart)));
|
||||
String label = "@" + (path.startsWith("/") ? path : ("/" + path)) + (httpMethod == null || httpMethod.isEmpty() ? "" : " -- " + httpMethod);
|
||||
String label = "@" + (path.startsWith("/") ? path : ("/" + path));
|
||||
label += (httpMethods == null || httpMethods.length == 0 ? "" : " -- " + WebfluxUtils.getStringRep(httpMethods, string -> string));
|
||||
|
||||
WebfluxHandlerInformation handler = extractHandlerInformation(node, path, httpMethod, contentType, acceptType);
|
||||
WebfluxHandlerInformation handler = extractHandlerInformation(node, path, httpMethods, contentTypes, acceptTypes);
|
||||
|
||||
result.add(new EnhancedSymbolInformation(new SymbolInformation(label, SymbolKind.Interface, location), handler));
|
||||
} catch (BadLocationException e) {
|
||||
@@ -118,98 +117,107 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
WebfluxPathFinder pathFinder = new WebfluxPathFinder(routerInvocation);
|
||||
routerInvocation.accept(pathFinder);
|
||||
|
||||
String path = pathFinder.getPath();
|
||||
if (path == null) path = "";
|
||||
List<String> path = new ArrayList<>();
|
||||
String firstPath = pathFinder.getPath();
|
||||
if (firstPath != null) {
|
||||
path.add(firstPath);
|
||||
}
|
||||
|
||||
return extractNestedValue(routerInvocation, path, (methodInvocationPathPrefix) -> {
|
||||
IMethodBinding methodBinding = methodInvocationPathPrefix.getT1().resolveMethodBinding();
|
||||
extractNestedValue(routerInvocation, path, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_PATH_METHOD.equals(methodName)) {
|
||||
String additionalPath = WebfluxUtils.extractStringLiteralArgument(methodInvocationPathPrefix.getT1());
|
||||
String additionalPath = WebfluxUtils.extractStringLiteralArgument(methodInvocation);
|
||||
if (additionalPath != null && additionalPath.length() > 0) {
|
||||
return additionalPath + methodInvocationPathPrefix.getT2();
|
||||
return additionalPath;
|
||||
}
|
||||
}
|
||||
|
||||
return methodInvocationPathPrefix.getT2();
|
||||
return null;
|
||||
});
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
path.stream().forEach(part -> result.insert(0, part));
|
||||
|
||||
return result.toString();
|
||||
|
||||
}
|
||||
|
||||
private String extractMethod(MethodInvocation routerInvocation) {
|
||||
private String[] extractMethods(MethodInvocation routerInvocation) {
|
||||
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation);
|
||||
routerInvocation.accept(methodFinder);
|
||||
|
||||
String method = methodFinder.getMethod();
|
||||
|
||||
return extractNestedValue(routerInvocation, method, (methodInvocationPathPrefix) -> {
|
||||
IMethodBinding methodBinding = methodInvocationPathPrefix.getT1().resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(methodName)) {
|
||||
String newMethod = WebfluxUtils.extractStringLiteralArgument(methodInvocationPathPrefix.getT1());
|
||||
if (method == null) {
|
||||
return newMethod;
|
||||
}
|
||||
}
|
||||
|
||||
return methodInvocationPathPrefix.getT2();
|
||||
});
|
||||
}
|
||||
|
||||
private String extractAcceptType(MethodInvocation routerInvocation) {
|
||||
String acceptType = null;
|
||||
|
||||
WebfluxAcceptTypeFinder acceptTypeFinder = new WebfluxAcceptTypeFinder();
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(acceptTypeFinder);
|
||||
if (acceptTypeFinder.getAcceptType() != null) {
|
||||
acceptType = acceptTypeFinder.getAcceptType();
|
||||
}
|
||||
((ASTNode)argument).accept(methodFinder);
|
||||
}
|
||||
}
|
||||
|
||||
final Set<String> methods = methodFinder.getMethods();
|
||||
|
||||
extractNestedValue(routerInvocation, methods, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(methodName)) {
|
||||
return WebfluxUtils.extractStringLiteralArgument(methodInvocation);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) methods.toArray(new String[methods.size()]);
|
||||
}
|
||||
|
||||
private String[] extractAcceptTypes(MethodInvocation routerInvocation) {
|
||||
WebfluxAcceptTypeFinder typeFinder = new WebfluxAcceptTypeFinder();
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(typeFinder);
|
||||
}
|
||||
}
|
||||
|
||||
return extractNestedValue(routerInvocation, acceptType, (methodInvocationPathPrefix) -> {
|
||||
IMethodBinding methodBinding = methodInvocationPathPrefix.getT1().resolveMethodBinding();
|
||||
Set<String> acceptTypes = typeFinder.getAcceptTypes();
|
||||
|
||||
extractNestedValue(routerInvocation, acceptTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_ACCEPT_TYPE_METHOD.equals(methodName)) {
|
||||
String newAcceptType = WebfluxUtils.extractSimpleNameArgument(methodInvocationPathPrefix.getT1());
|
||||
if (newAcceptType != null) {
|
||||
return newAcceptType;
|
||||
}
|
||||
return WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
}
|
||||
|
||||
return methodInvocationPathPrefix.getT2();
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) acceptTypes.toArray(new String[acceptTypes.size()]);
|
||||
}
|
||||
|
||||
private String extractContentType(MethodInvocation routerInvocation) {
|
||||
private String[] extractContentTypes(MethodInvocation routerInvocation) {
|
||||
WebfluxContentTypeFinder contentTypeFinder = new WebfluxContentTypeFinder(routerInvocation);
|
||||
routerInvocation.accept(contentTypeFinder);
|
||||
List<?> arguments = routerInvocation.arguments();
|
||||
for (Object argument : arguments) {
|
||||
if (argument != null && argument instanceof ASTNode) {
|
||||
((ASTNode)argument).accept(contentTypeFinder);
|
||||
}
|
||||
}
|
||||
|
||||
String contentType = contentTypeFinder.getContentType();
|
||||
Set<String> contentTypes = contentTypeFinder.getContentTypes();
|
||||
|
||||
return extractNestedValue(routerInvocation, contentType, (methodInvocationPathPrefix) -> {
|
||||
IMethodBinding methodBinding = methodInvocationPathPrefix.getT1().resolveMethodBinding();
|
||||
extractNestedValue(routerInvocation, contentTypes, (methodInvocation) -> {
|
||||
IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
|
||||
String methodName = methodBinding.getName();
|
||||
|
||||
if (WebfluxUtils.REQUEST_PREDICATE_CONTENT_TYPE_METHOD.equals(methodName)) {
|
||||
String newContentType = WebfluxUtils.extractSimpleNameArgument(methodInvocationPathPrefix.getT1());
|
||||
if (contentType == null) {
|
||||
return newContentType;
|
||||
}
|
||||
return WebfluxUtils.extractSimpleNameArgument(methodInvocation);
|
||||
}
|
||||
|
||||
return methodInvocationPathPrefix.getT2();
|
||||
return null;
|
||||
});
|
||||
|
||||
return (String[]) contentTypes.toArray(new String[contentTypes.size()]);
|
||||
}
|
||||
|
||||
private String extractNestedValue(ASTNode node, String value, Function<Tuple2<MethodInvocation, String>, String> extractor) {
|
||||
private void extractNestedValue(ASTNode node, Collection<String> values, Function<MethodInvocation, String> extractor) {
|
||||
if (node == null || node instanceof TypeDeclaration) {
|
||||
return value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (node instanceof MethodInvocation) {
|
||||
@@ -223,17 +231,20 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
for (Object argument : arguments) {
|
||||
if (argument instanceof MethodInvocation) {
|
||||
MethodInvocation nestedMethod = (MethodInvocation) argument;
|
||||
value = extractor.apply(Tuples.of(nestedMethod, value));
|
||||
String value = extractor.apply(nestedMethod);
|
||||
if (value != null) {
|
||||
values.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return extractNestedValue(node.getParent(), value, extractor);
|
||||
extractNestedValue(node.getParent(), values, extractor);
|
||||
}
|
||||
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String path, String httpMethod, String contentType, String acceptType) {
|
||||
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String path, String[] httpMethods, String[] contentTypes, String[] acceptTypes) {
|
||||
List<?> arguments = node.arguments();
|
||||
|
||||
if (arguments != null) {
|
||||
@@ -249,7 +260,7 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
|
||||
String handlerMethod = methodBinding.getMethodDeclaration().toString();
|
||||
if (handlerMethod != null) handlerMethod = handlerMethod.trim();
|
||||
|
||||
return new WebfluxHandlerInformation(handlerClass, handlerMethod, path, httpMethod, contentType, acceptType);
|
||||
return new WebfluxHandlerInformation(handlerClass, handlerMethod, path, httpMethods, contentTypes, acceptTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.eclipse.jdt.core.dom.IMethodBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
@@ -80,8 +81,6 @@ public class WebfluxUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean isRouteMethodInvocation(IMethodBinding methodBinding) {
|
||||
if (ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
|
||||
String name = methodBinding.getName();
|
||||
@@ -97,8 +96,35 @@ public class WebfluxUtils {
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static String getMediaType(String constantRep) {
|
||||
if (constantRep == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
MediaTypeMapping mediaType = MediaTypeMapping.valueOf(constantRep);
|
||||
return mediaType.getMediaType();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
return constantRep;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getStringRep(String[] multipleTypes, Function<String, String> valueConverter) {
|
||||
if (multipleTypes == null || multipleTypes.length == 0) return null;
|
||||
|
||||
StringBuilder result = new StringBuilder(valueConverter.apply(multipleTypes[0]));
|
||||
for (int i = 1; i < multipleTypes.length; i++) {
|
||||
result.append(", ");
|
||||
result.append(valueConverter.apply(multipleTypes[i]));
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class WebFluxCodeLensProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoutesCodeLenses() throws Exception {
|
||||
public void testRoutesCodeLensesSimpleCase() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
@@ -59,6 +59,42 @@ public class WebFluxCodeLensProviderTest {
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /quotes - Accept: application/json", 41, 29, 41, 40));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoutesCodeLensesNestedRoutes1() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler1.java").toUri().toString();
|
||||
TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString());
|
||||
TextDocumentInfo openedDoc = harness.openDocument(doc);
|
||||
|
||||
List<? extends CodeLens> codeLenses = harness.getCodeLenses(openedDoc);
|
||||
|
||||
assertEquals(3, codeLenses.size());
|
||||
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /person/{id} - Accept: application/json", 9, 29, 9, 38));
|
||||
assertTrue(containsCodeLens(codeLenses, "POST /person/ - Content-Type: application/json", 13, 29, 13, 41));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /person - Accept: application/json", 17, 29, 17, 39));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoutesCodeLensesNestedRoutes2() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/PersonHandler2.java").toUri().toString();
|
||||
TextDocumentInfo doc = harness.getOrReadFile(new File(new URI(docUri)), LanguageId.JAVA.toString());
|
||||
TextDocumentInfo openedDoc = harness.openDocument(doc);
|
||||
|
||||
List<? extends CodeLens> codeLenses = harness.getCodeLenses(openedDoc);
|
||||
|
||||
assertEquals(3, codeLenses.size());
|
||||
|
||||
assertTrue(containsCodeLens(codeLenses, "GET /person/{id} - Accept: application/json", 9, 29, 9, 38));
|
||||
assertTrue(containsCodeLens(codeLenses, "POST / - Accept: application/json - Content-Type: application/json, application/pdf", 13, 29, 13, 41));
|
||||
assertTrue(containsCodeLens(codeLenses, "GET, HEAD /person - Accept: text/plain, application/json", 17, 29, 17, 39));
|
||||
}
|
||||
|
||||
private boolean containsCodeLens(List<? extends CodeLens> codeLenses, String commandTitle, int startLine, int startPosition, int endLine, int endPosition) {
|
||||
for (CodeLens codeLens : codeLenses) {
|
||||
Command command = codeLens.getCommand();
|
||||
|
||||
@@ -15,6 +15,7 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -71,43 +72,43 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/hello", "GET").get(0);
|
||||
assertEquals("/hello", handlerInfo1.getPath());
|
||||
assertEquals("GET", handlerInfo1.getHttpMethod());
|
||||
assertNull(handlerInfo1.getContentType());
|
||||
assertEquals("TEXT_PLAIN", handlerInfo1.getAcceptType());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo1.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo1.getContentTypes().length);
|
||||
assertEquals("[TEXT_PLAIN]", Arrays.toString(handlerInfo1.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> hello(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo1.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "/echo", "POST").get(0);
|
||||
assertEquals("/echo", handlerInfo2.getPath());
|
||||
assertEquals("POST", handlerInfo2.getHttpMethod());
|
||||
assertEquals("TEXT_PLAIN", handlerInfo2.getContentType());
|
||||
assertEquals("TEXT_PLAIN", handlerInfo2.getAcceptType());
|
||||
assertEquals("[POST]", Arrays.toString(handlerInfo2.getHttpMethods()));
|
||||
assertEquals("[TEXT_PLAIN]", Arrays.toString(handlerInfo2.getContentTypes()));
|
||||
assertEquals("[TEXT_PLAIN]", Arrays.toString(handlerInfo2.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo2.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> echo(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "/quotes", "GET").get(0);
|
||||
assertEquals("/quotes", handlerInfo3.getPath());
|
||||
assertEquals("GET", handlerInfo3.getHttpMethod());
|
||||
assertNull(handlerInfo3.getContentType());
|
||||
assertEquals("APPLICATION_STREAM_JSON", handlerInfo3.getAcceptType());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo3.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo3.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_STREAM_JSON]", Arrays.toString(handlerInfo3.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo3.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> streamQuotes(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo4 = getWebfluxHandler(addons, "/quotes", "GET").get(1);
|
||||
assertEquals("/quotes", handlerInfo4.getPath());
|
||||
assertEquals("GET", handlerInfo4.getHttpMethod());
|
||||
assertNull(handlerInfo4.getContentType());
|
||||
assertEquals("APPLICATION_JSON", handlerInfo4.getAcceptType());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo4.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo4.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo4.getAcceptTypes()));
|
||||
assertEquals("org.test.QuoteHandler", handlerInfo4.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> fetchQuotes(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo4.getHandlerMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedRoutesMappingSymbols() throws Exception {
|
||||
public void testNestedRoutesMappingSymbols1() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter.java").toUri().toString();
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter1.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(5, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/person/{id} -- GET", docUri, 27, 6, 27, 45));
|
||||
@@ -119,26 +120,66 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0);
|
||||
assertEquals("/person/{id}", handlerInfo1.getPath());
|
||||
assertEquals("GET", handlerInfo1.getHttpMethod());
|
||||
assertNull(handlerInfo1.getContentType());
|
||||
assertEquals("APPLICATION_JSON", handlerInfo1.getAcceptType());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo1.getHandlerClass());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo1.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo1.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo1.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler1", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> getPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo1.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "/person/", "POST").get(0);
|
||||
assertEquals("/person/", handlerInfo2.getPath());
|
||||
assertEquals("POST", handlerInfo2.getHttpMethod());
|
||||
assertEquals("APPLICATION_JSON", handlerInfo2.getContentType());
|
||||
assertNull(handlerInfo2.getAcceptType());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo2.getHandlerClass());
|
||||
assertEquals("[POST]", Arrays.toString(handlerInfo2.getHttpMethods()));
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo2.getContentTypes()));
|
||||
assertEquals(0, handlerInfo2.getAcceptTypes().length);
|
||||
assertEquals("org.test.PersonHandler1", handlerInfo2.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> createPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "/person", "GET").get(0);
|
||||
assertEquals("/person", handlerInfo3.getPath());
|
||||
assertEquals("GET", handlerInfo3.getHttpMethod());
|
||||
assertNull(handlerInfo3.getContentType());
|
||||
assertEquals("APPLICATION_JSON", handlerInfo3.getAcceptType());
|
||||
assertEquals("org.test.PersonHandler", handlerInfo3.getHandlerClass());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo3.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo3.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo3.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler1", handlerInfo3.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> listPeople(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNestedRoutesMappingSymbols2() throws Exception {
|
||||
harness.intialize(new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI()));
|
||||
File directory = new File(ProjectsHarness.class.getResource("/test-projects/test-webflux-project/").toURI());
|
||||
|
||||
String docUri = directory.toPath().resolve("src/main/java/org/test/NestedRouter2.java").toUri().toString();
|
||||
List<? extends SymbolInformation> symbols = getSymbols(docUri);
|
||||
assertEquals(5, symbols.size());
|
||||
assertTrue(containsSymbol(symbols, "@/person/{id} -- GET", docUri, 29, 6, 29, 45));
|
||||
assertTrue(containsSymbol(symbols, "@/ -- POST", docUri, 31, 6, 31, 117));
|
||||
assertTrue(containsSymbol(symbols, "@/person -- GET, HEAD", docUri, 30, 7, 30, 113));
|
||||
|
||||
List<? extends Object> addons = getAdditionalInformation(docUri);
|
||||
assertEquals(3, addons.size());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo1 = getWebfluxHandler(addons, "/person/{id}", "GET").get(0);
|
||||
assertEquals("/person/{id}", handlerInfo1.getPath());
|
||||
assertEquals("[GET]", Arrays.toString(handlerInfo1.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo1.getContentTypes().length);
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo1.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler2", handlerInfo1.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> getPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo1.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo2 = getWebfluxHandler(addons, "/", "POST").get(0);
|
||||
assertEquals("/", handlerInfo2.getPath());
|
||||
assertEquals("[POST]", Arrays.toString(handlerInfo2.getHttpMethods()));
|
||||
assertEquals("[APPLICATION_JSON, APPLICATION_PDF]", Arrays.toString(handlerInfo2.getContentTypes()));
|
||||
assertEquals("[APPLICATION_JSON]", Arrays.toString(handlerInfo2.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler2", handlerInfo2.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> createPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
|
||||
|
||||
WebfluxHandlerInformation handlerInfo3 = getWebfluxHandler(addons, "/person", "HEAD").get(0);
|
||||
assertEquals("/person", handlerInfo3.getPath());
|
||||
assertEquals("[GET, HEAD]", Arrays.toString(handlerInfo3.getHttpMethods()));
|
||||
assertEquals(0, handlerInfo3.getContentTypes().length);
|
||||
assertEquals("[TEXT_PLAIN, APPLICATION_JSON]", Arrays.toString(handlerInfo3.getAcceptTypes()));
|
||||
assertEquals("org.test.PersonHandler2", handlerInfo3.getHandlerClass());
|
||||
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> listPeople(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
|
||||
}
|
||||
|
||||
@@ -171,7 +212,7 @@ public class WebFluxMappingSymbolProviderTest {
|
||||
return addons.stream()
|
||||
.filter((obj) -> obj instanceof WebfluxHandlerInformation)
|
||||
.map((obj -> (WebfluxHandlerInformation) obj))
|
||||
.filter((addon) -> addon.getPath().equals(path) && addon.getHttpMethod().equals(httpMethod))
|
||||
.filter((addon) -> addon.getPath().equals(path) && Arrays.asList(addon.getHttpMethods()).contains(httpMethod))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,18 +17,17 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
@Configuration
|
||||
public class RouterExperiments {
|
||||
public class NestedRouter1 {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> superRoutingFunction() {
|
||||
PersonHandler handler = new PersonHandler();
|
||||
public RouterFunction<ServerResponse> routingFunction1() {
|
||||
PersonHandler1 handler = new PersonHandler1();
|
||||
|
||||
return nest(path("/super"),
|
||||
nest(path("/something"),
|
||||
return nest(path("/person"),
|
||||
nest(accept(APPLICATION_JSON),
|
||||
route(GET("/{id}"), handler::getPerson)
|
||||
.andRoute(method(HttpMethod.GET), handler::listPeople)
|
||||
).andRoute(POST("/").and(contentType(APPLICATION_JSON)), handler::createPerson)));
|
||||
).andRoute(POST("/").and(contentType(APPLICATION_JSON)), handler::createPerson));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.test;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON;
|
||||
import static org.springframework.http.MediaType.APPLICATION_PDF;
|
||||
import static org.springframework.http.MediaType.TEXT_PLAIN;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.contentType;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.method;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
|
||||
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
@Configuration
|
||||
public class NestedRouter2 {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> routingFunction2() {
|
||||
PersonHandler2 handler = new PersonHandler2();
|
||||
|
||||
return nest(accept(APPLICATION_JSON),
|
||||
nest(path("/person"),
|
||||
route(GET("/{id}"), handler::getPerson)
|
||||
.andRoute(method(HttpMethod.GET).and(method(HttpMethod.HEAD)).and(accept(TEXT_PLAIN)), handler::listPeople)
|
||||
).andRoute(POST("/").and(contentType(APPLICATION_JSON)).and(contentType(APPLICATION_PDF)), handler::createPerson));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,11 +17,11 @@ import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
@Configuration
|
||||
public class NestedRouter {
|
||||
public class NestedRouter3 {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> routingFunction() {
|
||||
PersonHandler handler = new PersonHandler();
|
||||
PersonHandler3 handler = new PersonHandler3();
|
||||
|
||||
return nest(path("/person"),
|
||||
nest(accept(APPLICATION_JSON),
|
||||
@@ -5,7 +5,7 @@ import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class PersonHandler {
|
||||
public class PersonHandler1 {
|
||||
|
||||
public Mono<ServerResponse> getPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.test;
|
||||
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class PersonHandler2 {
|
||||
|
||||
public Mono<ServerResponse> getPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> createPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> listPeople(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.test;
|
||||
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class PersonHandler3 {
|
||||
|
||||
public Mono<ServerResponse> getPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> createPerson(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
public Mono<ServerResponse> listPeople(ServerRequest request) {
|
||||
return ServerResponse.notFound().build();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user