diff --git a/src/main/java/org/openrewrite/java/spring/RenameBean.java b/src/main/java/org/openrewrite/java/spring/RenameBean.java index 84ed34f0a..69a4b59ac 100644 --- a/src/main/java/org/openrewrite/java/spring/RenameBean.java +++ b/src/main/java/org/openrewrite/java/spring/RenameBean.java @@ -27,7 +27,11 @@ import org.openrewrite.java.search.DeclaresType; import org.openrewrite.java.search.FindAnnotations; import org.openrewrite.java.search.UsesType; -import org.openrewrite.java.tree.*; +import org.openrewrite.java.service.AnnotationService; +import org.openrewrite.java.tree.Expression; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.JavaType; +import org.openrewrite.java.tree.TypeUtils; import java.util.*; @@ -35,7 +39,7 @@ @EqualsAndHashCode(callSuper = false) @Value -public class RenameBean extends Recipe { +public class RenameBean extends ScanningRecipe>> { @Option(required = false, example = "foo.MyType") @Nullable @@ -74,90 +78,66 @@ public String getDescription() { return "Renames a Spring bean, both declaration and references."; } - /** - * @param methodDeclaration, which may or may not declare a bean - * @param newName, for the potential bean - * @return a recipe for this methodDeclaration if it declares a bean, or null if it does not declare a bean - */ - public static @Nullable RenameBean fromDeclaration(J.MethodDeclaration methodDeclaration, String newName) { - return methodDeclaration.getMethodType() == null ? null : - fromDeclaration(methodDeclaration, newName, methodDeclaration.getMethodType().getReturnType().toString()); + @Override + public List> getInitialValue(ExecutionContext ctx) { + return new ArrayList<>(); } - /** - * @param methodDeclaration, which may or may not declare a bean - * @param newName, for the potential bean - * @param type, to override the type field on the returned RenameBean instance - * @return a recipe for this methodDeclaration if it declares a bean, or null if it does not declare a bean - */ - public static @Nullable RenameBean fromDeclaration(J.MethodDeclaration methodDeclaration, String newName, @Nullable String type) { - BeanSearchResult beanSearchResult = isBean(methodDeclaration.getAllAnnotations(), BEAN_METHOD_ANNOTATIONS); - if (!beanSearchResult.isBean || methodDeclaration.getMethodType() == null) { - return null; - } - String beanName = - beanSearchResult.beanName != null ? beanSearchResult.beanName : methodDeclaration.getSimpleName(); - return beanName.equals(newName) ? null : new RenameBean(type, beanName, newName); - } + @Override + public TreeVisitor getScanner(List> acc) { - /** - * @param classDeclaration, which may or may not declare a bean - * @param newName, for the potential bean - * @return a recipe for this classDeclaration if it declares a bean, or null if it does not declare a bean - */ - public static @Nullable RenameBean fromDeclaration(J.ClassDeclaration classDeclaration, String newName) { - return classDeclaration.getType() == null ? null : - fromDeclaration(classDeclaration, newName, classDeclaration.getType().toString()); - } + return Preconditions.check(precondition(), new JavaIsoVisitor() { + @Override + public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, ExecutionContext ctx) { + J.MethodDeclaration m = super.visitMethodDeclaration(method, ctx); - /** - * @param classDeclaration, which may or may not declare a bean - * @param newName, for the potential bean - * @param type, to override the type field on the returned RenameBean instance - * @return a recipe for this classDeclaration if it declares a bean, or null if it does not declare a bean - */ - public static @Nullable RenameBean fromDeclaration(J.ClassDeclaration classDeclaration, String newName, @Nullable String type) { - BeanSearchResult beanSearchResult = isBean(classDeclaration.getAllAnnotations(), BEAN_TYPE_ANNOTATIONS); - if (!beanSearchResult.isBean || classDeclaration.getType() == null) { - return null; - } - String beanName = - beanSearchResult.beanName != null ? beanSearchResult.beanName : classDeclaration.getSimpleName(); - return beanName.equals(newName) ? null : new RenameBean(type, beanName, newName); + // handle beans named via methods + List allAnnotations = service(AnnotationService.class).getAllAnnotations(getCursor()); + Expression beanNameExpression = getBeanNameExpression(allAnnotations, BEAN_METHOD_ANNOTATIONS); + if (beanNameExpression == null && isRelevantType(m.getMethodType().getReturnType()) && m.getSimpleName().equals(oldName)) { + acc.add(new ChangeMethodName(methodPattern(m), newName, true, false).getVisitor()); + } + + // handle annotation renames + acc.add(renameBeanAnnotations(BEAN_METHOD_ANNOTATIONS)); + return m; + } + + @Override + public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) { + J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx); + + List allAnnotations = service(AnnotationService.class).getAllAnnotations(getCursor()); + Expression beanNameExpression = getBeanNameExpression(allAnnotations, BEAN_TYPE_ANNOTATIONS); + + // handle bean named via class name + if (beanNameExpression == null && isRelevantType(cd.getType()) && StringUtils.uncapitalize(cd.getSimpleName()).equals(oldName)) { + String newFullyQualifiedTypeName = cd.getType().getFullyQualifiedName() + .replaceAll("^((.+\\.)*)[^.]+$", "$1" + StringUtils.capitalize(newName)); + acc.add(new ChangeType(cd.getType().getFullyQualifiedName(), newFullyQualifiedTypeName, false).getVisitor()); + acc.add(new ChangeType(cd.getType().getFullyQualifiedName() + "Test", newFullyQualifiedTypeName + "Test", false).getVisitor()); + } + + // handle annotation renames + acc.add(renameBeanAnnotations(BEAN_TYPE_ANNOTATIONS)); + + return cd; + } + }); } - private static BeanSearchResult isBean(Collection annotations, Set types) { - for (J.Annotation annotation : annotations) { - if (anyAnnotationMatches(annotation, types)) { - if (annotation.getArguments() != null && !annotation.getArguments().isEmpty()) { - for (Expression expr : annotation.getArguments()) { - if (expr instanceof J.Literal) { - return new BeanSearchResult(true, (String) ((J.Literal) expr).getValue()); - } - J.Assignment beanNameAssignment = asBeanNameAssignment(expr); - if (beanNameAssignment != null) { - Expression assignmentExpr = beanNameAssignment.getAssignment(); - if (assignmentExpr instanceof J.Literal) { - return new BeanSearchResult(true, (String) ((J.Literal) assignmentExpr).getValue()); - } else if (assignmentExpr instanceof J.NewArray) { - List initializers = ((J.NewArray) assignmentExpr).getInitializer(); - if (initializers != null) { - for (Expression initExpr : initializers) { - // if multiple aliases, just take the first one - if (initExpr instanceof J.Literal) { - return new BeanSearchResult(true, - (String) ((J.Literal) initExpr).getValue()); - } - } - } - } - } - } + @Override + public TreeVisitor getVisitor(List> acc) { + return new JavaIsoVisitor() { + @Override + public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) { + J.CompilationUnit newCu = super.visitCompilationUnit(cu, ctx); + for (TreeVisitor visitor : acc) { + newCu = (J.CompilationUnit) visitor.visit(newCu, ctx); } - return new BeanSearchResult(true, null); + return newCu; } - } - return new BeanSearchResult(false, null); + }; } private static boolean anyAnnotationMatches(J.Annotation type, Set types) { @@ -190,111 +170,61 @@ private TreeVisitor precondition() { Preconditions.or(new UsesType<>(type, false), new DeclaresType<>(type)); } - @Override - public TreeVisitor getVisitor() { - return Preconditions.check(precondition(), new JavaIsoVisitor() { - @Override - public J.MethodDeclaration visitMethodDeclaration(J.MethodDeclaration method, - ExecutionContext ctx) { - J.MethodDeclaration m = super.visitMethodDeclaration(method, ctx); - - // handle bean declarations - if (m.getMethodType() != null && isRelevantType(m.getMethodType().getReturnType())) { - boolean maybeRenameMethodDeclaration = maybeRenameBean(m.getAllAnnotations(), - BEAN_METHOD_ANNOTATIONS); - if (maybeRenameMethodDeclaration && m.getSimpleName().equals(oldName)) { - doAfterVisit(new ChangeMethodName(methodPattern(m), newName, false, false).getVisitor()); + private @Nullable Expression getBeanNameExpression(Collection annotations, Set types) { + for (J.Annotation annotation : annotations) { + if (anyAnnotationMatches(annotation, types)) { + if (annotation.getArguments() != null && !annotation.getArguments().isEmpty()) { + for (Expression expr : annotation.getArguments()) { + if (expr instanceof J.Literal) { + return expr; + } + J.Assignment beanNameAssignment = asBeanNameAssignment(expr); + if (beanNameAssignment != null) { + return beanNameAssignment; + } } } - - // handle bean references (method params) - for (Statement statement : m.getParameters()) { - renameMatchingQualifierAnnotations(statement); - } - - return m; } + } + return null; + } - @Override - public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, - ExecutionContext ctx) { - J.ClassDeclaration cd = super.visitClassDeclaration(classDecl, ctx); - - // handle bean declarations - if (cd.getType() != null && isRelevantType(cd.getType())) { - boolean maybeRenameClass = maybeRenameBean(cd.getAllAnnotations(), BEAN_TYPE_ANNOTATIONS); - if (maybeRenameClass && StringUtils.uncapitalize(cd.getSimpleName()).equals(oldName)) { - String newFullyQualifiedTypeName = cd.getType().getFullyQualifiedName() - .replaceAll("^((.+\\.)*)[^.]+$", "$1" + StringUtils.capitalize(newName)); - doAfterVisit(new ChangeType(cd.getType().getFullyQualifiedName(), newFullyQualifiedTypeName, false).getVisitor()); + private TreeVisitor renameBeanAnnotations(Set types) { + return new JavaIsoVisitor() { + private boolean annotationParentMatchesBeanType() { + if (getCursor().getParent() != null) { + Object annotationParent = getCursor().getParent().getValue(); + + if (annotationParent instanceof J.MethodDeclaration) { + return isRelevantType(((J.MethodDeclaration) annotationParent).getMethodType().getReturnType()); + } else if (annotationParent instanceof J.ClassDeclaration) { + return isRelevantType(((J.ClassDeclaration) annotationParent).getType()); + } else if (annotationParent instanceof J.VariableDeclarations) { + return isRelevantType(((J.VariableDeclarations) annotationParent).getType()); } } - - // handle bean references (fields) - for (Statement statement : cd.getBody().getStatements()) { - renameMatchingQualifierAnnotations(statement); - } - - return cd; + return false; } - private void renameMatchingQualifierAnnotations(Statement statement) { - if (statement instanceof J.VariableDeclarations) { - J.VariableDeclarations varDecls = (J.VariableDeclarations) statement; - for (J.VariableDeclarations.NamedVariable namedVar : varDecls.getVariables()) { - if (isRelevantType(namedVar.getType())) { - maybeRenameBean(varDecls.getAllAnnotations(), JUST_QUALIFIER); - break; - } - } - } - } + @Override + public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) { + Expression beanNameExpression = getBeanNameExpression(Collections.singleton(annotation), types); - /** - * Checks for presence of a bean-like annotation in the list of annotations, - * and queues up a visitor to change that annotation's arguments if they match the oldName. - * - * @return true in the specific case where there are bean-like annotations, - * but they don't determine the name of the bean, and therefore the J element itself should be renamed - */ - private boolean maybeRenameBean(Collection annotations, Set types) { - J.Annotation beanAnnotation = null; - J.Literal literalBeanName = null; - J.Assignment beanNameAssignment = null; - outer: - for (J.Annotation annotation : annotations) { - if (anyAnnotationMatches(annotation, types)) { - beanAnnotation = annotation; - if (beanAnnotation.getArguments() != null && !beanAnnotation.getArguments().isEmpty()) { - for (Expression expr : beanAnnotation.getArguments()) { - if (expr instanceof J.Literal) { - literalBeanName = (J.Literal) expr; - break outer; - } - beanNameAssignment = asBeanNameAssignment(expr); - if (beanNameAssignment != null) { - break outer; - } - } - } - } - } - if (beanAnnotation != null) { - if (literalBeanName != null) { - if (oldName.equals(literalBeanName.getValue())) { - doAfterVisit(renameBeanAnnotationValue(beanAnnotation)); + if (beanNameExpression != null && annotationParentMatchesBeanType()) { + if (beanNameExpression instanceof J.Literal) { + if (oldName.equals(((J.Literal) beanNameExpression).getValue())) { + doAfterVisit(renameBeanAnnotationValue(annotation)); } - } else if (beanNameAssignment != null) { + } else if (beanNameExpression instanceof J.Assignment) { + J.Assignment beanNameAssignment = (J.Assignment) beanNameExpression; if (contains(beanNameAssignment.getAssignment(), oldName)) { - doAfterVisit(renameBeanAnnotationValue(beanAnnotation, beanNameAssignment)); + doAfterVisit(renameBeanAnnotationValue(annotation, beanNameAssignment)); } - } else { - return true; } } - return false; + return super.visitAnnotation(annotation, ctx); } - }); + }; } private static J.@Nullable Assignment asBeanNameAssignment(Expression argumentExpression) { @@ -310,8 +240,8 @@ private boolean maybeRenameBean(Collection annotations, Set renameBeanAnnotationValue(J.Annotation beanAnnotation, - J.Assignment beanNameAssignment) { + private TreeVisitor renameBeanAnnotationValue( + J.Annotation beanAnnotation, J.Assignment beanNameAssignment) { return new JavaIsoVisitor() { @Override public J.Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) { diff --git a/src/test/java/org/openrewrite/java/spring/RenameBeanTest.java b/src/test/java/org/openrewrite/java/spring/RenameBeanTest.java index 0024c1422..c423df152 100644 --- a/src/test/java/org/openrewrite/java/spring/RenameBeanTest.java +++ b/src/test/java/org/openrewrite/java/spring/RenameBeanTest.java @@ -33,15 +33,17 @@ public void defaults(RecipeSpec spec) { .parser( JavaParser.fromJavaVersion() .logCompilationWarningsAndErrors(true) + //language=java .dependsOn( """ - package sample; - class MyType {} - """, """ - package sample; - @interface MyAnnotation { - String value() default ""; - } + package sample; + class MyType {} + """, + """ + package sample; + @interface MyAnnotation { + String value() default ""; + } """ ) .classpathFromResources(new InMemoryExecutionContext(), "spring-context-6.+", "spring-beans-6.+") @@ -57,32 +59,34 @@ class BeanMethods { @Test void impliedName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - public MyType foo() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - public MyType bar() { - return new MyType(); - } - } + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + public MyType foo() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + public MyType bar() { + return new MyType(); + } + } + """ ) ); } @@ -91,32 +95,34 @@ public MyType bar() { void impliedNameNullType() { rewriteRun( spec -> spec.recipe(new RenameBean(null, "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - public MyType foo() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - public MyType bar() { - return new MyType(); - } - } + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + public MyType foo() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + public MyType bar() { + return new MyType(); + } + } + """ ) ); } @@ -124,32 +130,34 @@ public MyType bar() { @Test void explicitNameValueParam() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean(value = "foo") - public MyType beanMethod() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean(value = "bar") - public MyType beanMethod() { - return new MyType(); - } - } + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean(value = "foo") + public MyType beanMethod() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean(value = "bar") + public MyType beanMethod() { + return new MyType(); + } + } + """ ) ); } @@ -157,32 +165,34 @@ public MyType beanMethod() { @Test void explicitName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean("foo") - public MyType beanMethod() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean("bar") - public MyType beanMethod() { - return new MyType(); - } - } + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean("foo") + public MyType beanMethod() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean("bar") + public MyType beanMethod() { + return new MyType(); + } + } + """ ) ); } @@ -190,32 +200,34 @@ public MyType beanMethod() { @Test void explicitNameNameParam() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean(name = "foo") - public MyType beanMethod() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean(name = "bar") - public MyType beanMethod() { - return new MyType(); - } - } + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean(name = "foo") + public MyType beanMethod() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean(name = "bar") + public MyType beanMethod() { + return new MyType(); + } + } + """ ) ); } @@ -223,32 +235,34 @@ public MyType beanMethod() { @Test void explicitNameMultiNameParam() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean(name = { "foo", "somethingElse" }) - public MyType beanMethod() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean(name = { "bar", "somethingElse" }) - public MyType beanMethod() { - return new MyType(); - } - } + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean(name = { "foo", "somethingElse" }) + public MyType beanMethod() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean(name = { "bar", "somethingElse" }) + public MyType beanMethod() { + return new MyType(); + } + } + """ ) ); } @@ -256,36 +270,38 @@ public MyType beanMethod() { @Test void qualifierName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - @Qualifier("foo") - public MyType myType() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - @Qualifier("bar") - public MyType myType() { - return new MyType(); - } - } + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + @Qualifier("foo") + public MyType myType() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + @Qualifier("bar") + public MyType myType() { + return new MyType(); + } + } + """ ) ); } @@ -294,36 +310,38 @@ public MyType myType() { void qualifierNameNullType() { rewriteRun( spec -> spec.recipe(new RenameBean(null, "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - @Qualifier("foo") - public MyType myType() { - return new MyType(); - } - } - """, """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - @Qualifier("bar") - public MyType myType() { - return new MyType(); - } - } + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + @Qualifier("foo") + public MyType myType() { + return new MyType(); + } + } + """, """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + @Qualifier("bar") + public MyType myType() { + return new MyType(); + } + } + """ ) ); } @@ -331,22 +349,23 @@ public MyType myType() { @Test void wrongQualifierName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - @Qualifier("fooz") - public MyType myType() { - return new MyType(); - } - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + @Qualifier("fooz") + public MyType myType() { + return new MyType(); + } + } + """ ) ); } @@ -354,20 +373,21 @@ public MyType myType() { @Test void wrongBeanName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean({ "fooz" }) - public MyType myType() { - return new MyType(); - } - } - """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean({ "fooz" }) + public MyType myType() { + return new MyType(); + } + } + """ ) ); } @@ -375,20 +395,21 @@ public MyType myType() { @Test void wrongImpliedName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - public MyType myType() { - return new MyType(); - } - } - """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + public MyType myType() { + return new MyType(); + } + } + """ ) ); } @@ -396,20 +417,21 @@ public MyType myType() { @Test void wrongType() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean - public String foo() { - return ""; - } - } - """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean + public String foo() { + return ""; + } + } + """ ) ); } @@ -417,20 +439,21 @@ public String foo() { @Test void wrongTypeWithExplicitName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import sample.MyType; - - class A { - @Bean("foo") - public String myBean() { - return ""; - } - } - """ + package sample; + + import org.springframework.context.annotation.Bean; + import sample.MyType; + + class A { + @Bean("foo") + public String myBean() { + return ""; + } + } + """ ) ); } @@ -438,20 +461,21 @@ public String myBean() { @Test void wrongAnnotation() { rewriteRun( + //language=java java( """ - package sample; - - import sample.MyAnnotation; - import sample.MyType; - - class A { - @MyAnnotation - public String foo() { - return ""; - } - } - """ + package sample; + + import sample.MyAnnotation; + import sample.MyType; + + class A { + @MyAnnotation + public String foo() { + return ""; + } + } + """ ) ); } @@ -465,26 +489,28 @@ class BeanClasses { void impliedName() { rewriteRun( spec -> spec.recipe(new RenameBean("sample.Foo", "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class Foo { - } - """, """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class Bar { - } + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class Foo { + } + """, """ + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class Bar { + } + """ ) ); } @@ -493,26 +519,28 @@ class Bar { void impliedNameNullType() { rewriteRun( spec -> spec.recipe(new RenameBean(null, "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class Foo { - } - """, """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class Bar { - } + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class Foo { + } + """, """ + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class Bar { + } + """ ) ); } @@ -521,26 +549,28 @@ class Bar { void explicitName() { rewriteRun( spec -> spec.recipe(new RenameBean("sample.Foo", "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration("foo") - class Foo { - } - """, """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration("bar") - class Foo { - } + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration("foo") + class Foo { + } + """, """ + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration("bar") + class Foo { + } + """ ) ); } @@ -549,26 +579,28 @@ class Foo { void explicitNameNullType() { rewriteRun( spec -> spec.recipe(new RenameBean(null, "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration("foo") - class Foo { - } - """, """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration("bar") - class Foo { - } + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration("foo") + class Foo { + } + """, """ + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration("bar") + class Foo { + } + """ ) ); } @@ -577,30 +609,32 @@ class Foo { void qualifierName() { rewriteRun( spec -> spec.recipe(new RenameBean("sample.Foo", "fooz", "barz")), + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - @Qualifier("fooz") - class Foo { - } - """, """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - @Qualifier("barz") - class Foo { - } + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + @Qualifier("fooz") + class Foo { + } + """, """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + @Qualifier("barz") + class Foo { + } + """ ) ); } @@ -609,19 +643,20 @@ class Foo { void wrongQualifierName() { rewriteRun( spec -> spec.recipe(new RenameBean("sample.Foo", "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - @Qualifier("fooz") - class Foo { - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + @Qualifier("fooz") + class Foo { + } + """ ) ); } @@ -630,18 +665,19 @@ class Foo { void wrongType() { rewriteRun( spec -> spec.recipe(new RenameBean("sample.Foo", "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration("foo") - class A { - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration("foo") + class A { + } + """ ) ); } @@ -650,18 +686,19 @@ class A { void wrongAnnotation() { rewriteRun( spec -> spec.recipe(new RenameBean("sample.Foo", "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import sample.MyAnnotation; - import sample.MyType; - - @MyAnnotation("foo") - class A { - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import sample.MyAnnotation; + import sample.MyType; + + @MyAnnotation("foo") + class A { + } + """ ) ); } @@ -675,38 +712,40 @@ class Usages { @Test void parameterUsage() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Bean - public String myBean(@Qualifier("foo") MyType myType) { - return ""; - } - } - """, """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Bean - public String myBean(@Qualifier("bar") MyType myType) { - return ""; - } - } + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Bean + public String myBean(@Qualifier("foo") MyType myType) { + return ""; + } + } + """, """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Bean + public String myBean(@Qualifier("bar") MyType myType) { + return ""; + } + } + """ ) ); } @@ -715,38 +754,40 @@ public String myBean(@Qualifier("bar") MyType myType) { void parameterUsageNullType() { rewriteRun( spec -> spec.recipe(new RenameBean(null, "foo", "bar")), + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Bean - public String myBean(@Qualifier("foo") MyType myType) { - return ""; - } - } - """, """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Bean - public String myBean(@Qualifier("bar") MyType myType) { - return ""; - } - } + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Bean + public String myBean(@Qualifier("foo") MyType myType) { + return ""; + } + } + """, """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Bean + public String myBean(@Qualifier("bar") MyType myType) { + return ""; + } + } + """ ) ); } @@ -754,23 +795,24 @@ public String myBean(@Qualifier("bar") MyType myType) { @Test void parameterWrongType() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Bean - public String myBean(@Qualifier("foo") String myString) { - return ""; - } - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Bean + public String myBean(@Qualifier("foo") String myString) { + return ""; + } + } + """ ) ); } @@ -778,23 +820,24 @@ public String myBean(@Qualifier("foo") String myString) { @Test void parameterWrongName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Bean - public String myBean(@Qualifier("fooz") MyType myType) { - return ""; - } - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Bean + public String myBean(@Qualifier("fooz") MyType myType) { + return ""; + } + } + """ ) ); } @@ -802,22 +845,23 @@ public String myBean(@Qualifier("fooz") MyType myType) { @Test void parameterNoName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Bean; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Bean - public String myBean(MyType myType) { - return ""; - } - } - """ + package sample; + + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Bean + public String myBean(MyType myType) { + return ""; + } + } + """ ) ); } @@ -825,32 +869,34 @@ public String myBean(MyType myType) { @Test void fieldUsage() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Qualifier("foo") - private MyType myType; - } - """, """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Qualifier("bar") - private MyType myType; - } + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Qualifier("foo") + private MyType myType; + } + """, """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Qualifier("bar") + private MyType myType; + } + """ ) ); } @@ -858,20 +904,21 @@ class A { @Test void fieldWrongType() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Qualifier("foo") - private String myString; - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Qualifier("foo") + private String myString; + } + """ ) ); } @@ -879,20 +926,21 @@ class A { @Test void fieldWrongName() { rewriteRun( + //language=java java( """ - package sample; - - import org.springframework.beans.factory.annotation.Qualifier; - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - @Qualifier("fooz") - private MyType myTye; - } - """ + package sample; + + import org.springframework.beans.factory.annotation.Qualifier; + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + @Qualifier("fooz") + private MyType myTye; + } + """ ) ); } @@ -900,18 +948,141 @@ class A { @Test void fieldNoName() { rewriteRun( + //language=java + java( + """ + package sample; + + import org.springframework.context.annotation.Configuration; + import sample.MyType; + + @Configuration + class A { + private MyType myTye; + } + """ + ) + ); + } + + @Test + void renamesMethodDeclarationAndUsageInOtherFile() { + rewriteRun( + spec -> spec.recipe(new RenameBean(null, "beanMethod", "newBeanMethod")), + //language=java + java( + """ + package sample; + + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + + @Configuration + public class TestConfiguration { + + @Bean + public void beanMethod() { + } + } + """, + """ + package sample; + + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + + @Configuration + public class TestConfiguration { + + @Bean + public void newBeanMethod() { + } + } + """ + ), + //language=java + java( + """ + package sample; + + public class TestClass { + + TestConfiguration testConfig; + + void testMethod() { + testConfig.beanMethod(); + } + } + """, + """ + package sample; + + public class TestClass { + + TestConfiguration testConfig; + + void testMethod() { + testConfig.newBeanMethod(); + } + } + """ + ) + ); + } + + @Test + void renamesClassBeanUsagesInOtherFiles() { + rewriteRun( + spec -> spec.recipe(new RenameBean(null, "testConfiguration", "newTestConfiguration")), + //language=java java( """ - package sample; - - import org.springframework.context.annotation.Configuration; - import sample.MyType; - - @Configuration - class A { - private MyType myTye; - } + package sample; + + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + + @Configuration + public class TestConfiguration { + } + """, """ + package sample; + + import org.springframework.context.annotation.Bean; + import org.springframework.context.annotation.Configuration; + + @Configuration + public class NewTestConfiguration { + } + """ + ), + //language=java + java( + """ + package sample; + + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.stereotype.Service; + + @Service + public class MyClass { + @Autowired + TestConfiguration testConfig; + } + """, + """ + package sample; + + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.stereotype.Service; + + @Service + public class MyClass { + @Autowired + NewTestConfiguration testConfig; + } + """ ) ); }