Skip to content

Commit

Permalink
Fix bean injection when bean name is different from type simple name
Browse files Browse the repository at this point in the history
  • Loading branch information
BoykoAlex committed Feb 26, 2025
1 parent 6caac67 commit 6a9c390
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2024 Broadcom, Inc.
* Copyright (c) 2017, 2025 Broadcom, 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
Expand All @@ -15,6 +15,7 @@
import java.util.List;

import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Recipe;
import org.openrewrite.Tree;
Expand Down Expand Up @@ -51,21 +52,28 @@ public String getDescription() {

@NonNull
String classFqName;

String fieldName;

transient JavaType.FullyQualified fullyQualifiedType;

@JsonCreator
public AddFieldRecipe(@NonNull @JsonProperty("fullyQualifiedClassName") String fullyQualifiedName, @NonNull @JsonProperty("classFqName") String classFqName) {
public AddFieldRecipe(
@NonNull @JsonProperty("fullyQualifiedClassName") String fullyQualifiedName,
@NonNull @JsonProperty("classFqName") String classFqName,
@Nullable @JsonProperty("fieldName") String fieldName) {
this.fullyQualifiedName = fullyQualifiedName;
fullyQualifiedType = JavaType.ShallowClass.build(fullyQualifiedName);
this.classFqName = classFqName;
this.fieldName = fieldName == null ? getFieldName(fullyQualifiedType) : fieldName;
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {

return new JavaIsoVisitor<ExecutionContext>() {

JavaType.FullyQualified fullyQualifiedType = JavaType.ShallowClass.build(fullyQualifiedName);
String fieldType = getFieldType(fullyQualifiedType);
String fieldName = getFieldName(fullyQualifiedType);

@Override
public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, ExecutionContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2024 Broadcom, Inc.
* Copyright (c) 2017, 2025 Broadcom, 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
Expand Down Expand Up @@ -289,9 +289,17 @@ public MethodDeclaration visitMethodDeclaration(MethodDeclaration method, Execut
ShallowClass type = JavaType.ShallowClass.build(methodType);
J.FieldAccess fa = new J.FieldAccess(Tree.randomId(), Space.EMPTY, Markers.EMPTY, new J.Identifier(Tree.randomId(), Space.EMPTY, Markers.EMPTY, Collections.emptyList(), "this", md.getMethodType().getDeclaringType(), null), JLeftPadded.build(createFieldNameIdentifier()), type);
Assignment assign = new J.Assignment(Tree.randomId(), Space.build("\n", Collections.emptyList()), Markers.EMPTY, fa, JLeftPadded.build(createFieldNameIdentifier()), type);
assign = autoFormat(assign, p, getCursor());
List<Statement> newStatements = new ArrayList<>(md.getBody().getStatements());
newStatements.add(assign);
md = md.withBody(autoFormat(md.getBody().withStatements(newStatements), p, getCursor()));
boolean empty = newStatements.isEmpty();
if (empty) {
newStatements.add(assign);
md = md.withBody(autoFormat(md.getBody().withStatements(newStatements), p, getCursor()));
} else {
// Prefix is off otherwise even after autoFormat
newStatements.add(assign.withPrefix(newStatements.get(newStatements.size() - 1).getPrefix()));
md = md.withBody(md.getBody().withStatements(newStatements));
}
}
return md;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2024 Broadcom, Inc.
* Copyright (c) 2017, 2025 Broadcom, 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
Expand Down Expand Up @@ -47,7 +47,7 @@ public InjectBeanCompletionRecipe(String fullyQualifiedName, String fieldName, S
@Override
public List<Recipe> getRecipeList() {
List<Recipe> list = new ArrayList<>();
list.add(new AddFieldRecipe(fullyQualifiedName, classFqName));
list.add(new AddFieldRecipe(fullyQualifiedName, classFqName, fieldName));
list.add(new ConstructorInjectionRecipe(fullyQualifiedName, fieldName, classFqName));
return list;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2024 Broadcom, Inc.
* Copyright (c) 2017, 2025 Broadcom, 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
Expand Down Expand Up @@ -28,7 +28,7 @@ public class AddFieldRecipeTest implements RewriteTest {

@Override
public void defaults(RecipeSpec spec) {
spec.recipe(new AddFieldRecipe("com.example.test.OwnerRepository", "com.example.demo.FooBar"))
spec.recipe(new AddFieldRecipe("com.example.test.OwnerRepository", "com.example.demo.FooBar", null))
.parser(JavaParser.fromJavaVersion()
.logCompilationWarningsAndErrors(true));
}
Expand Down Expand Up @@ -86,7 +86,7 @@ public void test() {
public interface OwnerRepository{}
""";

Recipe recipe = new AddFieldRecipe("com.example.demo.OwnerRepository", "com.example.demo.FooBar");
Recipe recipe = new AddFieldRecipe("com.example.demo.OwnerRepository", "com.example.demo.FooBar", null);
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr, dependsOn);
}

Expand Down Expand Up @@ -128,7 +128,7 @@ public void test() {
public interface OwnerRepository{}
""";

Recipe recipe = new AddFieldRecipe("com.example.test.OwnerRepository", "com.example.demo.FooBar");
Recipe recipe = new AddFieldRecipe("com.example.test.OwnerRepository", "com.example.demo.FooBar", null);
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr, dependsOn);
}

Expand Down Expand Up @@ -170,7 +170,7 @@ public void test() {
public interface OwnerRepository{}
""";

Recipe recipe = new AddFieldRecipe("com.example.test.Inner.OwnerRepository", "com.example.demo.FooBar");
Recipe recipe = new AddFieldRecipe("com.example.test.Inner.OwnerRepository", "com.example.demo.FooBar", null);
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr, dependsOn);
}

Expand Down Expand Up @@ -214,7 +214,7 @@ public void test() {
public interface OwnerRepository{}
""";

Recipe recipe = new AddFieldRecipe("com.example.test.OwnerRepository", "com.example.demo.FooBar$Inner");
Recipe recipe = new AddFieldRecipe("com.example.test.OwnerRepository", "com.example.demo.FooBar$Inner", null);
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr, dependsOn);
}

Expand Down Expand Up @@ -266,7 +266,7 @@ public void test1() {}
public interface OwnerRepository{}
""";

Recipe recipe = new AddFieldRecipe("com.example.test.Inner.OwnerRepository", "com.example.demo.FooBar");
Recipe recipe = new AddFieldRecipe("com.example.test.Inner.OwnerRepository", "com.example.demo.FooBar", null);
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr, dependsOn);
}

Expand Down Expand Up @@ -313,7 +313,7 @@ public void test() {
@Component
class FooBarNew {
private final Inner.OwnerRepository ownerRepository;
private final Inner.OwnerRepository ownerRepo;
public void test1() {}
Expand All @@ -325,7 +325,7 @@ public void test1() {}
public interface OwnerRepository{}
""";

Recipe recipe = new AddFieldRecipe("com.example.test.Inner.OwnerRepository", "com.example.demo.FooBarNew");
Recipe recipe = new AddFieldRecipe("com.example.test.Inner.OwnerRepository", "com.example.demo.FooBarNew", "ownerRepo");
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr, dependsOn);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2024 Broadcom, Inc.
* Copyright (c) 2017, 2025 Broadcom, 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
Expand All @@ -21,6 +21,7 @@
import org.openrewrite.SourceFile;
import org.openrewrite.internal.InMemoryLargeSourceSet;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaParser.Builder;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

Expand All @@ -32,8 +33,12 @@ public void defaults(RecipeSpec spec) {
.parser(JavaParser.fromJavaVersion().classpath("spring-beans"));
}

public static void runRecipeAndAssert(Recipe recipe, String beforeSourceStr, String expectedSourceStr, String dependsOn) {
JavaParser javaParser = JavaParser.fromJavaVersion().dependsOn(dependsOn).build();
public static void runRecipeAndAssert(Recipe recipe, String beforeSourceStr, String expectedSourceStr, String... dependsOn) {
Builder<? extends JavaParser, ?> builder = JavaParser.fromJavaVersion();
if (dependsOn.length > 0) {
builder.dependsOn(dependsOn);
}
JavaParser javaParser = builder.build();

List<SourceFile> list = javaParser.parse(beforeSourceStr).toList();
SourceFile beforeSource = list.get(0);
Expand Down Expand Up @@ -486,4 +491,42 @@ public interface OwnerRepository{}
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr, dependsOn);
}

@Test
void injectObjectFieldIntoNewConstructor() {

String beforeSourceStr = """
package com.example.demo;
public class A {
private final String s;
private final Object obj;
A(String s) {
this.s = s;
}
}
""";

String expectedSourceStr = """
package com.example.demo;
public class A {
private final String s;
private final Object obj;
A(String s, Object obj) {
this.s = s;
this.obj = obj;
}
}
""";

Recipe recipe = new ConstructorInjectionRecipe("java.lang.Object", "obj", "com.example.demo.A");
runRecipeAndAssert(recipe, beforeSourceStr, expectedSourceStr);
}

}

0 comments on commit 6a9c390

Please sign in to comment.