diff --git a/src/main/java/org/openrewrite/java/spring/trait/SpringRequestMapping.java b/src/main/java/org/openrewrite/java/spring/trait/SpringRequestMapping.java index f5bdb8ae1..26f8ffbee 100644 --- a/src/main/java/org/openrewrite/java/spring/trait/SpringRequestMapping.java +++ b/src/main/java/org/openrewrite/java/spring/trait/SpringRequestMapping.java @@ -27,9 +27,8 @@ import org.openrewrite.trait.SimpleTraitMatcher; import org.openrewrite.trait.Trait; +import java.util.Collections; import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.stream.Collectors.toList; @@ -52,23 +51,34 @@ public String getHttpMethod() { } public String getPath() { - String path = - cursor.getPathAsStream() - .filter(J.ClassDeclaration.class::isInstance) - .map(classDecl -> ((J.ClassDeclaration) classDecl).getAllAnnotations().stream() - .filter(SpringRequestMapping::hasRequestMapping) - .findAny() - .flatMap(classMapping -> new Annotated(new Cursor(null, classMapping)) - .getDefaultAttribute(null) - .map(Literal::getString)) - .orElse(null)) - .filter(Objects::nonNull) - .collect(Collectors.joining("/")) + - new Annotated(cursor) - .getDefaultAttribute(null) - .map(Literal::getString) - .orElse(""); - return path.replace("//", "/"); + List pathPrefixes = cursor.getPathAsStream() + .filter(J.ClassDeclaration.class::isInstance) + .map(J.ClassDeclaration.class::cast) + .flatMap(classDecl -> classDecl.getLeadingAnnotations().stream() + .filter(SpringRequestMapping::hasRequestMapping) + .findAny() + .flatMap(classMapping -> new Annotated(new Cursor(null, classMapping)) + .getDefaultAttribute(null) + .map(lit -> lit.getStrings().stream())) + .orElse(Stream.of(""))) + .collect(toList()); + List pathEndings = new Annotated(cursor) + .getDefaultAttribute(null) + .map(Literal::getStrings) + .orElse(Collections.emptyList()); + + StringBuilder result = new StringBuilder(); + for (int j = 0; j < pathPrefixes.size(); j++) { + for (int i = 0; i < pathEndings.size(); i++) { + String pathEnding = pathEndings.get(i); + String prefix = pathPrefixes.get(j); + result.append(prefix).append(pathEnding); + if(i < pathEndings.size() - 1 || j < pathPrefixes.size() - 1) { + result.append(", "); + } + } + } + return result.toString().replace("//", "/"); } public static class Matcher extends SimpleTraitMatcher { diff --git a/src/test/java/org/openrewrite/java/spring/framework/HttpComponentsClientHttpRequestFactoryReadTimeoutTest.java b/src/test/java/org/openrewrite/java/spring/framework/HttpComponentsClientHttpRequestFactoryReadTimeoutTest.java index a6e341560..3d8b5014f 100644 --- a/src/test/java/org/openrewrite/java/spring/framework/HttpComponentsClientHttpRequestFactoryReadTimeoutTest.java +++ b/src/test/java/org/openrewrite/java/spring/framework/HttpComponentsClientHttpRequestFactoryReadTimeoutTest.java @@ -51,12 +51,12 @@ void migrateHttpComponentsClientHttpRequestFactoryReadTimeout() { import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; - + class RestContextInitializer { RestTemplate getRestTemplate() throws Exception { Registry socketFactoryRegistry = RegistryBuilder.create().build(); PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); - + return new RestTemplateBuilder() .requestFactory(() -> { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); @@ -77,15 +77,15 @@ RestTemplate getRestTemplate() throws Exception { import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; - + import java.util.concurrent.TimeUnit; - + class RestContextInitializer { RestTemplate getRestTemplate() throws Exception { Registry socketFactoryRegistry = RegistryBuilder.create().build(); PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); poolingConnectionManager.setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(30000, TimeUnit.MILLISECONDS).build()); - + return new RestTemplateBuilder() .requestFactory(() -> { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); @@ -114,15 +114,15 @@ void migratePoolingHttpClientConnectionManagerBuilderToVariable() { import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; - + import javax.net.ssl.SSLContext; - + class RestContextInitializer { RestTemplate getRestTemplate() throws Exception { SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, (cert, authType) -> true).build(); SSLConnectionSocketFactory socketFactoryRegistry = new SSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE); PoolingHttpClientConnectionManager poolingConnectionManager = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(socketFactoryRegistry).build(); - + return new RestTemplateBuilder() .requestFactory(() -> { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); @@ -144,18 +144,18 @@ RestTemplate getRestTemplate() throws Exception { import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; - + import javax.net.ssl.SSLContext; - + import java.util.concurrent.TimeUnit; - + class RestContextInitializer { RestTemplate getRestTemplate() throws Exception { SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, (cert, authType) -> true).build(); SSLConnectionSocketFactory socketFactoryRegistry = new SSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE); PoolingHttpClientConnectionManager poolingConnectionManager = PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(socketFactoryRegistry).build(); poolingConnectionManager.setDefaultSocketConfig(SocketConfig.custom().setSoTimeout(30000, TimeUnit.MILLISECONDS).build()); - + return new RestTemplateBuilder() .requestFactory(() -> { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); @@ -183,15 +183,15 @@ void doNotMigrateWhenUsingPoolingHttpClientConnectionManagerBuilderInline() { import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; - + import javax.net.ssl.SSLContext; - + class RestContextInitializer { RestTemplate getRestTemplate() throws Exception { SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, (cert, authType) -> true).build(); SSLConnectionSocketFactory socketFactoryRegistry = new SSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE); return PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(socketFactoryRegistry).build(); - + return new RestTemplateBuilder() .requestFactory(() -> { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); @@ -211,15 +211,15 @@ RestTemplate getRestTemplate() throws Exception { import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; - + import javax.net.ssl.SSLContext; - + class RestContextInitializer { RestTemplate getRestTemplate() throws Exception { SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, (cert, authType) -> true).build(); SSLConnectionSocketFactory socketFactoryRegistry = new SSLConnectionSocketFactory(sslContext,NoopHostnameVerifier.INSTANCE); return PoolingHttpClientConnectionManagerBuilder.create().setSSLSocketFactory(socketFactoryRegistry).build(); - + return new RestTemplateBuilder() .requestFactory(() -> { HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); diff --git a/src/testWithSpringBoot_3_0/java/org/openrewrite/java/spring/search/FindApiEndpointsTest.java b/src/testWithSpringBoot_3_0/java/org/openrewrite/java/spring/search/FindApiEndpointsTest.java index 66b92f25e..19db372ae 100644 --- a/src/testWithSpringBoot_3_0/java/org/openrewrite/java/spring/search/FindApiEndpointsTest.java +++ b/src/testWithSpringBoot_3_0/java/org/openrewrite/java/spring/search/FindApiEndpointsTest.java @@ -30,18 +30,52 @@ class FindApiEndpointsTest implements RewriteTest { @Override public void defaults(RecipeSpec spec) { spec.recipe(new FindApiEndpoints()) - .parser(JavaParser.fromJavaVersion().classpath("spring-web")); + .parser(JavaParser.fromJavaVersion().classpath("spring-web", "spring-context")); } @Test @DocumentExample - void webClient() { + void withinController() { rewriteRun( //language=java java( """ + import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; + + @Controller + class PersonController { + @GetMapping("/count") + int count() { + return 42; + } + } + """, + """ + import org.springframework.stereotype.Controller; + import org.springframework.web.bind.annotation.*; + + @Controller + class PersonController { + /*~~(GET /count)~~>*/@GetMapping("/count") + int count() { + return 42; + } + } + """ + ) + ); + } + @Test + @DocumentExample + void webClient() { + rewriteRun( + //language=java + java( + """ + import org.springframework.web.bind.annotation.*; + @RequestMapping("/person") class PersonController { @GetMapping("/count") @@ -52,7 +86,7 @@ int count() { """, """ import org.springframework.web.bind.annotation.*; - + @RequestMapping("/person") class PersonController { /*~~(GET /person/count)~~>*/@GetMapping("/count") @@ -64,4 +98,35 @@ int count() { ) ); } + + @Test + void multiplePathsOneMethod() { + rewriteRun( + //language=java + java( + """ + import org.springframework.web.bind.annotation.*; + + @RequestMapping({"/person", "/people"}) + class PersonController { + @GetMapping({"/count", "/length"}) + int count() { + return 42; + } + } + """, + """ + import org.springframework.web.bind.annotation.*; + + @RequestMapping({"/person", "/people"}) + class PersonController { + /*~~(GET /person/count, /person/length, /people/count, /people/length)~~>*/@GetMapping({"/count", "/length"}) + int count() { + return 42; + } + } + """ + ) + ); + } }