added media types to webflux symbol and code lens logic

This commit is contained in:
Martin Lippert
2018-03-08 13:28:23 +01:00
parent 57b83da757
commit 7328932b7c
15 changed files with 345 additions and 203 deletions

View File

@@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2018 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.requestmapping;
/**
* @author Martin Lippert
*/
public enum MediaTypeMapping {
TEXT_PLAIN("text/plain"),
APPLICATION_JSON("application/json"),
APPLICATION_STREAM_JSON("application/stream+json");
private String mediaType;
private MediaTypeMapping(String mediaType) {
this.mediaType = mediaType;
}
public String getMediaType() {
return mediaType;
}
}

View File

@@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2018 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.requestmapping;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
/**
* @author Martin Lippert
*/
public class WebfluxAcceptTypeFinder extends ASTVisitor {
private String acceptType;
public WebfluxAcceptTypeFinder() {
}
public String getAcceptType() {
return acceptType;
}
@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);
}
}
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
visitChildren = false;
}
return visitChildren;
}
}

View File

@@ -0,0 +1,55 @@
/*******************************************************************************
* Copyright (c) 2018 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.requestmapping;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
/**
* @author Martin Lippert
*/
public class WebfluxContentTypeFinder extends ASTVisitor {
private String contentType;
private ASTNode root;
public WebfluxContentTypeFinder(ASTNode root) {
this.root = root;
}
public String getContentType() {
return contentType;
}
@Override
public boolean visit(MethodInvocation node) {
boolean visitChildren = true;
if (node != this.root) {
IMethodBinding methodBinding = node.resolveMethodBinding();
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);
}
}
if (WebfluxUtils.isRouteMethodInvocation(methodBinding)) {
visitChildren = false;
}
}
return visitChildren;
}
}

View File

@@ -75,8 +75,8 @@ public class WebfluxHandlerCodeLensProvider implements CodeLensProvider {
String codeLensCommand = handlerInfo.getHttpMethod() != null ? handlerInfo.getHttpMethod() + " " : "";
codeLensCommand += handlerInfo.getPath();
codeLensCommand += handlerInfo.getContentType() != null ? " Content-Type: " + handlerInfo.getContentType() : "";
codeLensCommand += handlerInfo.getAcceptType() != null ? " Accept: " + handlerInfo.getAcceptType() : "";
codeLensCommand += handlerInfo.getAcceptType() != null ? " - Accept: " + getMediaType(handlerInfo.getAcceptType()) : "";
codeLensCommand += handlerInfo.getContentType() != null ? " - Content-Type: " + getMediaType(handlerInfo.getContentType()) : "";
codeLens.setCommand(new Command(codeLensCommand, null));
@@ -88,5 +88,19 @@ 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;
}
}
}

View File

@@ -10,13 +10,10 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.requestmapping;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.QualifiedName;
/**
* @author Martin Lippert
@@ -47,7 +44,7 @@ public class WebfluxMethodFinder extends ASTVisitor {
method = name;
}
else if (name != null && WebfluxUtils.REQUEST_PREDICATE_METHOD_METHOD.equals(name)) {
method = extractMethodValue(node);
method = WebfluxUtils.extractQualifiedNameArgument(node);
}
}
@@ -58,18 +55,4 @@ public class WebfluxMethodFinder extends ASTVisitor {
return visitChildren;
}
private String extractMethodValue(MethodInvocation node) {
List<?> arguments = node.arguments();
if (arguments != null && arguments.size() > 0) {
Object object = arguments.get(0);
if (object instanceof QualifiedName) {
QualifiedName qualifiedName = (QualifiedName) object;
if (qualifiedName.getName() != null) {
return qualifiedName.getName().toString();
}
}
}
return null;
}
}

View File

@@ -41,7 +41,7 @@ public class WebfluxPathFinder extends ASTVisitor {
if (WebfluxUtils.REQUEST_PREDICATES_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if (name != null && WebfluxUtils.REQUEST_PREDICATE_ALL_PATH_METHODS.contains(name)) {
path = WebfluxUtils.extractPath(node);
path = WebfluxUtils.extractStringLiteralArgument(node);
}
}

View File

@@ -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.function.Function;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
@@ -33,6 +34,9 @@ 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
*/
@@ -87,12 +91,11 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
}
protected void extractMappingSymbol(MethodInvocation node, TextDocument doc, List<EnhancedSymbolInformation> result) {
String foundPath = extractPathFromRouterFunction(node);
String path = extractPath(node, foundPath);
String path = extractPath(node);
String httpMethod = extractMethod(node);
String contentType = null;
String acceptType = null;
String contentType = extractContentType(node);
String acceptType = extractAcceptType(node);
int methodNameStart = node.getName().getStartPosition();
int invocationStart = node.getStartPosition();
@@ -111,19 +114,102 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
}
}
private String extractPathFromRouterFunction(MethodInvocation routerInvocation) {
private String extractPath(MethodInvocation routerInvocation) {
WebfluxPathFinder pathFinder = new WebfluxPathFinder(routerInvocation);
routerInvocation.accept(pathFinder);
String path = pathFinder.getPath();
if (path == null) path = "";
return path;
return extractNestedValue(routerInvocation, path, (methodInvocationPathPrefix) -> {
IMethodBinding methodBinding = methodInvocationPathPrefix.getT1().resolveMethodBinding();
String methodName = methodBinding.getName();
if (WebfluxUtils.REQUEST_PREDICATE_PATH_METHOD.equals(methodName)) {
String additionalPath = WebfluxUtils.extractStringLiteralArgument(methodInvocationPathPrefix.getT1());
if (additionalPath != null && additionalPath.length() > 0) {
return additionalPath + methodInvocationPathPrefix.getT2();
}
}
return methodInvocationPathPrefix.getT2();
});
}
private String extractPath(ASTNode node, String path) {
private String extractMethod(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();
}
}
}
return extractNestedValue(routerInvocation, acceptType, (methodInvocationPathPrefix) -> {
IMethodBinding methodBinding = methodInvocationPathPrefix.getT1().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 methodInvocationPathPrefix.getT2();
});
}
private String extractContentType(MethodInvocation routerInvocation) {
WebfluxContentTypeFinder contentTypeFinder = new WebfluxContentTypeFinder(routerInvocation);
routerInvocation.accept(contentTypeFinder);
String contentType = contentTypeFinder.getContentType();
return extractNestedValue(routerInvocation, contentType, (methodInvocationPathPrefix) -> {
IMethodBinding methodBinding = methodInvocationPathPrefix.getT1().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 methodInvocationPathPrefix.getT2();
});
}
private String extractNestedValue(ASTNode node, String value, Function<Tuple2<MethodInvocation, String>, String> extractor) {
if (node == null || node instanceof TypeDeclaration) {
return path;
return value;
}
if (node instanceof MethodInvocation) {
@@ -132,38 +218,21 @@ public class WebfluxRouterSymbolProvider implements SymbolProvider {
if (WebfluxUtils.ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();
if ("nest".equals(name)) {
if (WebfluxUtils.REQUEST_PREDICATE_NEST_METHOD.equals(name)) {
List<?> arguments = methodInvocation.arguments();
for (Object argument : arguments) {
if (argument instanceof MethodInvocation) {
MethodInvocation nestedMethod = (MethodInvocation) argument;
IMethodBinding nestedMethodBinding = nestedMethod.resolveMethodBinding();
String nestedMethodName = nestedMethodBinding.getName();
if ("path".equals(nestedMethodName)) {
String additionalPath = WebfluxUtils.extractPath(nestedMethod);
if (additionalPath != null && additionalPath.length() > 0) {
path = additionalPath + path;
}
}
value = extractor.apply(Tuples.of(nestedMethod, value));
}
}
}
}
}
return extractPath(node.getParent(), path);
return extractNestedValue(node.getParent(), value, extractor);
}
private String extractMethod(MethodInvocation routerInvocation) {
WebfluxMethodFinder methodFinder = new WebfluxMethodFinder(routerInvocation);
routerInvocation.accept(methodFinder);
String method = methodFinder.getMethod();
return method;
}
private WebfluxHandlerInformation extractHandlerInformation(MethodInvocation node, String path, String httpMethod, String contentType, String acceptType) {
List<?> arguments = node.arguments();

View File

@@ -17,6 +17,8 @@ import java.util.Set;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.StringLiteral;
/**
@@ -30,12 +32,15 @@ public class WebfluxUtils {
public static final String REQUEST_PREDICATE_PATH_METHOD = "path";
public static final String REQUEST_PREDICATE_METHOD_METHOD = "method";
public static final String REQUEST_PREDICATE_ACCEPT_TYPE_METHOD = "accept";
public static final String REQUEST_PREDICATE_CONTENT_TYPE_METHOD = "contentType";
public static final String REQUEST_PREDICATE_NEST_METHOD = "nest";
public static final Set<String> REQUEST_PREDICATE_HTTPMETHOD_METHODS = new HashSet<>(Arrays.asList("GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
public static final Set<String> REQUEST_PREDICATE_ALL_PATH_METHODS = new HashSet<>(Arrays.asList(REQUEST_PREDICATE_PATH_METHOD, "GET", "POST", "DELETE", "PUT", "PATCH", "HEAD", "OPTIONS"));
public static String extractPath(MethodInvocation node) {
public static String extractStringLiteralArgument(MethodInvocation node) {
List<?> arguments = node.arguments();
if (arguments != null && arguments.size() > 0) {
Object object = arguments.get(0);
@@ -47,6 +52,36 @@ public class WebfluxUtils {
return null;
}
public static String extractQualifiedNameArgument(MethodInvocation node) {
List<?> arguments = node.arguments();
if (arguments != null && arguments.size() > 0) {
Object object = arguments.get(0);
if (object instanceof QualifiedName) {
QualifiedName qualifiedName = (QualifiedName) object;
if (qualifiedName.getName() != null) {
return qualifiedName.getName().toString();
}
}
}
return null;
}
public static String extractSimpleNameArgument(MethodInvocation node) {
List<?> arguments = node.arguments();
if (arguments != null && arguments.size() > 0) {
Object object = arguments.get(0);
if (object instanceof SimpleName) {
SimpleName name = (SimpleName) object;
if (name.getFullyQualifiedName() != null) {
return name.getFullyQualifiedName().toString();
}
}
}
return null;
}
public static boolean isRouteMethodInvocation(IMethodBinding methodBinding) {
if (ROUTER_FUNCTIONS_TYPE.equals(methodBinding.getDeclaringClass().getBinaryName())) {
String name = methodBinding.getName();

View File

@@ -53,10 +53,10 @@ public class WebFluxCodeLensProviderTest {
assertEquals(4, codeLenses.size());
assertTrue(containsCodeLens(codeLenses, "GET /hello", 25, 29, 25, 34));
assertTrue(containsCodeLens(codeLenses, "POST /echo", 30, 29, 30, 33));
assertTrue(containsCodeLens(codeLenses, "GET /quotes", 35, 29, 35, 41));
assertTrue(containsCodeLens(codeLenses, "GET /quotes", 41, 29, 41, 40));
assertTrue(containsCodeLens(codeLenses, "GET /hello - Accept: text/plain", 25, 29, 25, 34));
assertTrue(containsCodeLens(codeLenses, "POST /echo - Accept: text/plain - Content-Type: text/plain", 30, 29, 30, 33));
assertTrue(containsCodeLens(codeLenses, "GET /quotes - Accept: application/stream+json", 35, 29, 35, 41));
assertTrue(containsCodeLens(codeLenses, "GET /quotes - Accept: application/json", 41, 29, 41, 40));
}
private boolean containsCodeLens(List<? extends CodeLens> codeLenses, String commandTitle, int startLine, int startPosition, int endLine, int endPosition) {

View File

@@ -46,8 +46,8 @@ public class WebFluxMappingSymbolProviderTest {
String docUri = directory.toPath().resolve("src/main/java/org/test/UserController.java").toUri().toString();
List<? extends SymbolInformation> symbols = getSymbols(docUri);
assertEquals(4, symbols.size());
assertTrue(containsSymbol(symbols, "@/users", docUri, 19, 1, 19, 74));
assertTrue(containsSymbol(symbols, "@/users/{username}", docUri, 24, 1, 24, 85));
assertTrue(containsSymbol(symbols, "@/users", docUri, 13, 1, 13, 74));
assertTrue(containsSymbol(symbols, "@/users/{username}", docUri, 18, 1, 18, 85));
List<? extends Object> addons = getAdditionalInformation(docUri);
assertNull(addons);
@@ -73,15 +73,15 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals("/hello", handlerInfo1.getPath());
assertEquals("GET", handlerInfo1.getHttpMethod());
assertNull(handlerInfo1.getContentType());
assertNull(handlerInfo1.getAcceptType());
assertEquals("TEXT_PLAIN", handlerInfo1.getAcceptType());
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());
assertNull(handlerInfo2.getContentType());
assertNull(handlerInfo2.getAcceptType());
assertEquals("TEXT_PLAIN", handlerInfo2.getContentType());
assertEquals("TEXT_PLAIN", handlerInfo2.getAcceptType());
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());
@@ -89,7 +89,7 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals("/quotes", handlerInfo3.getPath());
assertEquals("GET", handlerInfo3.getHttpMethod());
assertNull(handlerInfo3.getContentType());
assertNull(handlerInfo3.getAcceptType());
assertEquals("APPLICATION_STREAM_JSON", handlerInfo3.getAcceptType());
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());
@@ -97,7 +97,7 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals("/quotes", handlerInfo4.getPath());
assertEquals("GET", handlerInfo4.getHttpMethod());
assertNull(handlerInfo4.getContentType());
assertNull(handlerInfo4.getAcceptType());
assertEquals("APPLICATION_JSON", handlerInfo4.getAcceptType());
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());
}
@@ -121,14 +121,14 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals("/person/{id}", handlerInfo1.getPath());
assertEquals("GET", handlerInfo1.getHttpMethod());
assertNull(handlerInfo1.getContentType());
assertNull(handlerInfo1.getAcceptType());
assertEquals("APPLICATION_JSON", handlerInfo1.getAcceptType());
assertEquals("org.test.PersonHandler", 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());
assertNull(handlerInfo2.getContentType());
assertEquals("APPLICATION_JSON", handlerInfo2.getContentType());
assertNull(handlerInfo2.getAcceptType());
assertEquals("org.test.PersonHandler", handlerInfo2.getHandlerClass());
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> createPerson(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo2.getHandlerMethod());
@@ -137,7 +137,7 @@ public class WebFluxMappingSymbolProviderTest {
assertEquals("/person", handlerInfo3.getPath());
assertEquals("GET", handlerInfo3.getHttpMethod());
assertNull(handlerInfo3.getContentType());
assertNull(handlerInfo3.getAcceptType());
assertEquals("APPLICATION_JSON", handlerInfo3.getAcceptType());
assertEquals("org.test.PersonHandler", handlerInfo3.getHandlerClass());
assertEquals("public Mono<org.springframework.web.reactive.function.server.ServerResponse> listPeople(org.springframework.web.reactive.function.server.ServerRequest)", handlerInfo3.getHandlerMethod());
}

View File

@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M1</version>
<version>2.0.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
@@ -35,10 +35,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
</dependencies>
<build>
@@ -50,42 +46,4 @@
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>

View File

@@ -0,0 +1,34 @@
package org.test;
import static org.springframework.http.MediaType.APPLICATION_JSON;
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 RouterExperiments {
@Bean
public RouterFunction<ServerResponse> superRoutingFunction() {
PersonHandler handler = new PersonHandler();
return nest(path("/super"),
nest(path("/something"),
nest(accept(APPLICATION_JSON),
route(GET("/{id}"), handler::getPerson)
.andRoute(method(HttpMethod.GET), handler::listPeople)
).andRoute(POST("/").and(contentType(APPLICATION_JSON)), handler::createPerson)));
}
}

View File

@@ -1,72 +0,0 @@
package org.test;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class TradingUser {
@Id
private String id;
private String userName;
private String fullName;
public TradingUser() {
}
public TradingUser(String id, String userName, String fullName) {
this.id = id;
this.userName = userName;
this.fullName = fullName;
}
public TradingUser(String userName, String fullName) {
this.userName = userName;
this.fullName = fullName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TradingUser that = (TradingUser) o;
if (!id.equals(that.id)) return false;
return userName.equals(that.userName);
}
@Override
public int hashCode() {
int result = id.hashCode();
result = 31 * result + userName.hashCode();
return result;
}
}

View File

@@ -1,11 +0,0 @@
package org.test;
import reactor.core.publisher.Mono;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
public interface TradingUserRepository extends ReactiveMongoRepository<TradingUser, String> {
Mono<TradingUser> findByUserName(String userName);
}

View File

@@ -1,30 +1,24 @@
package org.test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@RestController
public class UserController {
private final TradingUserRepository tradingUserRepository;
public UserController(TradingUserRepository tradingUserRepository) {
this.tradingUserRepository = tradingUserRepository;
}
@GetMapping(path = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<TradingUser> listUsers() {
return this.tradingUserRepository.findAll();
public Flux<Object> listUsers() {
return null;
}
@GetMapping(path = "/users/{username}", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<TradingUser> showUsers(@PathVariable String username) {
return this.tradingUserRepository.findByUserName(username);
public Mono<Object> showUsers(@PathVariable String username) {
return null;
}
}