Skip to content

Commit cce0b5f

Browse files
committed
Adds action to set unitName on PersistenceContext annotation to default
- Removes printout and commented out code - Adds methods to IntegrationTestBaseClass - Using OR AddOrUpdateAnnotationAttribute instead of AddOrReplaceAnnotationAttribute - Enhance integration test to check for modified unitName
1 parent 71a7494 commit cce0b5f

File tree

11 files changed

+207
-32
lines changed

11 files changed

+207
-32
lines changed

applications/spring-shell/src/test/java/org/springframework/sbm/IntegrationTestBaseClass.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,19 +319,32 @@ protected void replaceFile(Path target, Path source) {
319319
}
320320

321321
protected String loadJavaFileFromSubmodule(String submodulePath, String packageName, String className) {
322+
return loadJavaFileFromModule(submodulePath, packageName, className, "src/main/java");
323+
}
324+
325+
protected String loadTestJavaFileFromSubmodule(String submodulePath, String packageName, String className) {
326+
return loadJavaFileFromModule(submodulePath, packageName, className, "src/test/java");
327+
}
328+
329+
private String loadJavaFileFromModule(String submodulePath, String packageName, String className, String sourceDir) {
322330
try {
323-
Path classPath = testDir.resolve(submodulePath + "src/main/java").resolve(packageName.replace(".", "/"));
331+
Path classPath = testDir.resolve(submodulePath + sourceDir).resolve(packageName.replace(".", "/"));
324332
Path classFile = classPath.resolve(className + ".java");
325333
return Files.readString(classFile);
326334
} catch (IOException e) {
327335
throw new RuntimeException(e);
328336
}
329337
}
330338

339+
331340
protected String loadJavaFile(String packageName, String className) {
332341
return loadJavaFileFromSubmodule("", packageName, className);
333342
}
334343

344+
protected String loadTestJavaFile(String packageName, String className) {
345+
return loadTestJavaFileFromSubmodule("", packageName, className);
346+
}
347+
335348
/**
336349
* Starts {@code image} as Docker container exposing {@code ports} and waiting for {@code httpEndpoint} to be available.
337350
*/

applications/spring-shell/src/test/java/org/springframework/sbm/MigrateJpaApplicationIntegrationTest.java

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import org.junit.jupiter.api.Tag;
1919
import org.junit.jupiter.api.Test;
2020

21+
import static org.assertj.core.api.Assertions.assertThat;
22+
2123
public class MigrateJpaApplicationIntegrationTest extends IntegrationTestBaseClass {
2224

2325
@Override
@@ -41,7 +43,47 @@ void migrateJpaApplication() {
4143
"migrate-stateless-ejb",
4244
"migrate-jpa-to-spring-boot"
4345
);
44-
// TODO: add assertions
46+
47+
assertThat(super.loadJavaFile("org.superbiz.injection.h3jpa", "SpringBootApp")).isNotEmpty();
48+
assertThat(super.loadTestJavaFile("org.superbiz.injection.h3jpa", "SpringBootAppTest")).isNotEmpty();
49+
String movies = loadJavaFile("org.superbiz.injection.h3jpa", "Movies");
50+
assertThat(movies).contains(
51+
"""
52+
package org.superbiz.injection.h3jpa;
53+
54+
import org.springframework.stereotype.Service;
55+
import org.springframework.transaction.annotation.Transactional;
56+
57+
import javax.persistence.EntityManager;
58+
import javax.persistence.PersistenceContext;
59+
import javax.persistence.Query;
60+
import java.util.List;
61+
62+
@Service
63+
@Transactional
64+
public class Movies {
65+
66+
@PersistenceContext(unitName = "default")
67+
private EntityManager entityManager;
68+
69+
public void addMovie(Movie movie) throws Exception {
70+
entityManager.persist(movie);
71+
}
72+
73+
public void deleteMovie(Movie movie) throws Exception {
74+
movie = entityManager.find(Movie.class, movie.getId());
75+
entityManager.remove(movie);
76+
}
77+
78+
public List<Movie> getMovies() throws Exception {
79+
Query query = entityManager.createQuery("SELECT m from Movie as m");
80+
return query.getResultList();
81+
}
82+
83+
}
84+
"""
85+
);
86+
4587
}
4688

4789
}

applications/spring-shell/src/test/resources/testcode/jpa-hibernate/src/main/java/org/superbiz/injection/h3jpa/Movies.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
@Stateless
2727
public class Movies {
2828

29-
@PersistenceContext(unitName = "movie-unit" /*, type = PersistenceContextType.EXTENDED*/)
29+
@PersistenceContext(unitName = "movie-unit")
3030
private EntityManager entityManager;
3131

3232
public void addMovie(Movie movie) throws Exception {

components/sbm-core/src/main/java/org/springframework/sbm/java/impl/ClasspathRegistry.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,11 @@ private void initDependency(ResolvedDependency d, Map<ResolvedDependency, Path>.
149149
if(dependencyPath != null) {
150150
Stream.of(maps).forEach(m -> m.put(d, dependencyPath));
151151
} else {
152-
System.out.println(d.getGav() + " has no jars. It has type " + d.getType());
153152
initializeDepeendencies(new HashSet<>(d.getDependencies()));
154153
}
155154
} else {
156155
initializeDepeendencies(new HashSet(d.getDependencies()));
157156
}
158-
159-
160-
// Optional<Path> dependencyPath = dependencyHelper.downloadArtifact(d);
161-
// if (dependencyPath.isPresent()) {
162-
// Stream.of(maps).forEach(m -> m.put(d, dependencyPath.get()));
163-
// }
164157
}
165158

166159
private boolean isExternalDependency(ResolvedDependency d) {

components/sbm-core/src/main/java/org/springframework/sbm/java/impl/OpenRewriteAnnotation.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
*/
1616
package org.springframework.sbm.java.impl;
1717

18+
import org.openrewrite.java.AddOrUpdateAnnotationAttribute;
1819
import org.openrewrite.java.JavaParser;
1920
import org.springframework.sbm.java.api.Annotation;
2021
import org.springframework.sbm.java.api.Expression;
2122
import org.springframework.sbm.java.refactoring.JavaRefactoring;
22-
import org.springframework.sbm.support.openrewrite.java.AddOrReplaceAnnotationAttribute;
2323
import lombok.Getter;
2424
import org.openrewrite.internal.lang.Nullable;
2525
import org.openrewrite.java.tree.J;
@@ -79,8 +79,8 @@ public boolean hasAttribute(String attribute) {
7979

8080
@Override
8181
public void setAttribute(String attribute, Object value, Class valueType) {
82-
AddOrReplaceAnnotationAttribute visitor = new AddOrReplaceAnnotationAttribute(() -> javaParser, wrapped, attribute, value, valueType);
83-
refactoring.refactor(visitor);
82+
AddOrUpdateAnnotationAttribute recipe = new AddOrUpdateAnnotationAttribute(this.getFullyQualifiedName(), attribute, value.toString(), false);
83+
refactoring.refactor(recipe);
8484
}
8585

8686
@Override
Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,20 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package org.springframework.sbm.support.openrewrite.java;
16+
package org.openrewrite.java;
1717

18+
import org.openrewrite.java.AddOrUpdateAnnotationAttribute;
19+
import org.openrewrite.java.tree.JavaType;
1820
import org.springframework.sbm.java.OpenRewriteTestSupport;
1921
import org.junit.jupiter.api.Test;
20-
import org.openrewrite.ExecutionContext;
2122
import org.openrewrite.InMemoryExecutionContext;
22-
import org.openrewrite.java.JavaIsoVisitor;
2323
import org.openrewrite.java.tree.J;
2424

25+
import java.util.List;
26+
2527
import static org.assertj.core.api.Assertions.assertThat;
2628

27-
public class AddOrReplaceAnnotationAttributeTest {
29+
public class AddOrUpdateAnnotationAttributeTest {
2830

2931

3032
@Test
@@ -33,9 +35,9 @@ void addBooleanAttributeToAnnotationWithoutAttributes() {
3335
J.CompilationUnit compilationUnit = OpenRewriteTestSupport.createCompilationUnit(code);
3436

3537
J.Annotation annotation = compilationUnit.getClasses().get(0).getLeadingAnnotations().get(0);
36-
JavaIsoVisitor<ExecutionContext> javaIsoVisitor = new AddOrReplaceAnnotationAttribute(annotation, "forRemoval", true, Boolean.class);
38+
AddOrUpdateAnnotationAttribute javaIsoVisitor = new AddOrUpdateAnnotationAttribute(((JavaType.Class)annotation.getType()).getFullyQualifiedName(), "forRemoval", "true", true);
3739

38-
String refactoredCu = javaIsoVisitor.visit(compilationUnit, new InMemoryExecutionContext()).print();
40+
String refactoredCu = javaIsoVisitor.run(List.of(compilationUnit), new InMemoryExecutionContext()).getResults().get(0).getAfter().printAll();
3941

4042
assertThat(refactoredCu).isEqualTo("@Deprecated(forRemoval = true) public class Foo {}");
4143
}
@@ -46,8 +48,8 @@ void addStringAttributeToAnnotationWithoutAttributes() {
4648
J.CompilationUnit compilationUnit = OpenRewriteTestSupport.createCompilationUnit(code);
4749

4850
J.Annotation annotation = compilationUnit.getClasses().get(0).getLeadingAnnotations().get(0);
49-
JavaIsoVisitor<ExecutionContext> javaIsoVisitor = new AddOrReplaceAnnotationAttribute(annotation, "since", "2020", String.class);
50-
String refactoredCu = javaIsoVisitor.visit(compilationUnit, new InMemoryExecutionContext()).print();
51+
AddOrUpdateAnnotationAttribute javaIsoVisitor = new AddOrUpdateAnnotationAttribute(((JavaType.Class)annotation.getType()).getFullyQualifiedName(), "since", "2020", true);
52+
String refactoredCu = javaIsoVisitor.run(List.of(compilationUnit), new InMemoryExecutionContext()).getResults().get(0).getAfter().printAll();
5153

5254
assertThat(refactoredCu).isEqualTo("@Deprecated(since = \"2020\") public class Foo {}");
5355
}
@@ -57,8 +59,8 @@ void changeAnnotationAttributeValue() {
5759
String code = "@Deprecated(forRemoval = false) public class Foo {}";
5860
J.CompilationUnit compilationUnit = OpenRewriteTestSupport.createCompilationUnit(code);
5961
J.Annotation annotation = compilationUnit.getClasses().get(0).getLeadingAnnotations().get(0);
60-
JavaIsoVisitor<ExecutionContext> javaIsoVisitor = new AddOrReplaceAnnotationAttribute(annotation, "forRemoval", true, Boolean.class);
61-
String refactoredCu = javaIsoVisitor.visit(compilationUnit, new InMemoryExecutionContext()).print();
62+
AddOrUpdateAnnotationAttribute javaIsoVisitor = new AddOrUpdateAnnotationAttribute(((JavaType.Class)annotation.getType()).getFullyQualifiedName(), "forRemoval", "true", false);
63+
String refactoredCu = javaIsoVisitor.run(List.of(compilationUnit), new InMemoryExecutionContext()).getResults().get(0).getAfter().printAll();
6264
assertThat(refactoredCu).isEqualTo("@Deprecated(forRemoval = true) public class Foo {}");
6365
}
6466

@@ -67,8 +69,8 @@ void changeAnnotationAttributeValueOfAnnotationWithAttributes() {
6769
String code = "@Deprecated(forRemoval = false, since = \"2020\") public class Foo {}";
6870
J.CompilationUnit compilationUnit = OpenRewriteTestSupport.createCompilationUnit(code);
6971
J.Annotation annotation = compilationUnit.getClasses().get(0).getLeadingAnnotations().get(0);
70-
JavaIsoVisitor<ExecutionContext> javaIsoVisitor = new AddOrReplaceAnnotationAttribute(annotation, "forRemoval", true, Boolean.class);
71-
String refactoredCu = javaIsoVisitor.visit(compilationUnit, new InMemoryExecutionContext()).print();
72+
AddOrUpdateAnnotationAttribute javaIsoVisitor = new AddOrUpdateAnnotationAttribute(((JavaType.Class)annotation.getType()).getFullyQualifiedName(), "forRemoval", "true", false);
73+
String refactoredCu = javaIsoVisitor.run(List.of(compilationUnit), new InMemoryExecutionContext()).getResults().get(0).getAfter().printAll();
7274
assertThat(refactoredCu).isEqualTo("@Deprecated(forRemoval = true, since = \"2020\") public class Foo {}");
7375
}
7476

@@ -77,8 +79,8 @@ void changeAnnotationAttributeValueOfAnnotationWithAttributes2() {
7779
String code = "@Deprecated(since = \"2020\", forRemoval = false) public class Foo {}";
7880
J.CompilationUnit compilationUnit = OpenRewriteTestSupport.createCompilationUnit(code);
7981
J.Annotation annotation = compilationUnit.getClasses().get(0).getLeadingAnnotations().get(0);
80-
JavaIsoVisitor<ExecutionContext> javaIsoVisitor = new AddOrReplaceAnnotationAttribute(annotation, "forRemoval", true, Boolean.class);
81-
String refactoredCu = javaIsoVisitor.visit(compilationUnit, new InMemoryExecutionContext()).print();
82+
AddOrUpdateAnnotationAttribute javaIsoVisitor = new AddOrUpdateAnnotationAttribute(((JavaType.Class)annotation.getType()).getFullyQualifiedName(), "forRemoval", "true", false);
83+
String refactoredCu = javaIsoVisitor.run(List.of(compilationUnit), new InMemoryExecutionContext()).getResults().get(0).getAfter().printAll();
8284
assertThat(refactoredCu).isEqualTo("@Deprecated(since = \"2020\", forRemoval = true) public class Foo {}");
8385
}
8486

@@ -87,9 +89,9 @@ void addAttributeToAnnotationWithAttributes() {
8789
String code = "@Deprecated(forRemoval = true) public class Foo {}";
8890
J.CompilationUnit compilationUnit = OpenRewriteTestSupport.createCompilationUnit(code);
8991
J.Annotation annotation = compilationUnit.getClasses().get(0).getLeadingAnnotations().get(0);
90-
JavaIsoVisitor<ExecutionContext> javaIsoVisitor = new AddOrReplaceAnnotationAttribute(annotation, "since", "2020", String.class);
91-
String refactoredCu = javaIsoVisitor.visit(compilationUnit, new InMemoryExecutionContext()).print();
92-
assertThat(refactoredCu).isEqualTo("@Deprecated(forRemoval = true, since = \"2020\") public class Foo {}");
92+
AddOrUpdateAnnotationAttribute javaIsoVisitor = new AddOrUpdateAnnotationAttribute(((JavaType.Class)annotation.getType()).getFullyQualifiedName(), "since", "2020", false);
93+
String refactoredCu = javaIsoVisitor.run(List.of(compilationUnit), new InMemoryExecutionContext()).getResults().get(0).getAfter().printAll();
94+
assertThat(refactoredCu).isEqualTo("@Deprecated(since = \"2020\", forRemoval = true) public class Foo {}");
9395
}
9496

9597

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright 2021 - 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.sbm.jee.jpa.actions;
17+
18+
import org.springframework.sbm.engine.context.ProjectContext;
19+
import org.springframework.sbm.engine.recipe.AbstractAction;
20+
import org.springframework.sbm.java.api.JavaSource;
21+
22+
import java.util.List;
23+
import java.util.stream.Collectors;
24+
25+
/**
26+
* @author Fabian Krüger
27+
*/
28+
public class RenameUnitNameOfPersistenceContextAnnotationsToDefault extends AbstractAction {
29+
30+
public static final String PERSISTENCE_CONTEXT = "javax.persistence.PersistenceContext";
31+
32+
@Override
33+
public void apply(ProjectContext context) {
34+
List<JavaSource> javaSources = context
35+
.getProjectJavaSources()
36+
.asStream()
37+
.filter(s -> s
38+
.getTypes()
39+
.stream()
40+
.flatMap(t -> t.getMembers().stream())
41+
.anyMatch(m -> m.hasAnnotation(PERSISTENCE_CONTEXT)))
42+
.collect(Collectors.toList());
43+
44+
javaSources.forEach(s -> {
45+
s.getTypes()
46+
.stream()
47+
.flatMap(t -> t.getMembers().stream())
48+
.filter(m -> m.hasAnnotation(PERSISTENCE_CONTEXT))
49+
.map(m -> m.getAnnotation(PERSISTENCE_CONTEXT))
50+
.findFirst()
51+
.get()
52+
.setAttribute("unitName", "default", String.class);
53+
});
54+
}
55+
}

components/sbm-recipes-jee-to-boot/src/main/resources/recipes/migrate-jpa-to-spring-boot.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,9 @@
8888
condition:
8989
type: org.springframework.sbm.common.migration.conditions.TrueCondition
9090
pattern: '/**/persistence.xml'
91+
92+
- type: org.springframework.sbm.jee.jpa.actions.RenameUnitNameOfPersistenceContextAnnotationsToDefault
93+
description: Set 'unitName' attribute from @PersistenceContext annotations to 'default' when different
94+
condition:
95+
type: org.springframework.sbm.java.migration.conditions.HasMemberAnnotation
96+
annotation: javax.persistence.PersistenceContext
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2021 - 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.sbm.jee.jpa.actions;
17+
18+
import org.assertj.core.api.Assertions;
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.sbm.engine.context.ProjectContext;
21+
import org.springframework.sbm.project.resource.TestProjectContext;
22+
23+
/**
24+
* @author Fabian Krüger
25+
*/
26+
class RenameUnitNameOfPersistenceContextAnnotationsToDefaultTest {
27+
@Test
28+
void shouldRemoveUnitNameAttribute() {
29+
30+
String javaCode = """
31+
import javax.persistence.PersistenceContext;
32+
import javax.persistence.EntityManager;
33+
public class Foo {
34+
@PersistenceContext(unitName = "foo")
35+
private EntityManager entityManager;
36+
}
37+
""";
38+
39+
ProjectContext context = TestProjectContext
40+
.buildProjectContext()
41+
.addJavaSource("src/main/java", javaCode)
42+
.withBuildFileHavingDependencies("javax.persistence:javax.persistence-api:2.2", "javax.ejb:javax.ejb-api:3.2")
43+
.build();
44+
45+
RenameUnitNameOfPersistenceContextAnnotationsToDefault sut = new RenameUnitNameOfPersistenceContextAnnotationsToDefault();
46+
47+
sut.apply(context);
48+
49+
String expected = """
50+
import javax.persistence.PersistenceContext;
51+
import javax.persistence.EntityManager;
52+
public class Foo {
53+
@PersistenceContext(unitName = "default")
54+
private EntityManager entityManager;
55+
}
56+
""";
57+
58+
59+
Assertions.assertThat(context.getProjectJavaSources().list().get(0).print()).isEqualTo(expected);
60+
}
61+
}

components/sbm-recipes-jee-to-boot/src/test/java/org/springframework/sbm/jee/jpa/recipes/MigrateJpaToSpringBootRecipeTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.sbm.jee.jpa.actions.MigratePersistenceXmlToApplicationPropertiesAction;
2929
import freemarker.template.Configuration;
3030
import org.junit.jupiter.api.Test;
31+
import org.springframework.sbm.jee.jpa.actions.RenameUnitNameOfPersistenceContextAnnotationsToDefault;
3132

3233
import java.nio.file.Path;
3334
import java.util.List;
@@ -53,7 +54,9 @@ void migrateJpaToSpringBootRecipe() {
5354
RemoveDependenciesMatchingRegex.class,
5455
AddTypeAnnotationToTypeAnnotatedWith.class,
5556
MigrateEclipseLinkToSpringBoot.class,
56-
DeleteFileMatchingPattern.class);
57+
DeleteFileMatchingPattern.class,
58+
RenameUnitNameOfPersistenceContextAnnotationsToDefault.class
59+
);
5760
assertThatRecipeHasCondition(recipe, FileExist.class);
5861

5962
// Action: migrate persistence.xml to Spring application.properties

components/sbm-support-weblogic/src/test/java/org/springframework/sbm/jee/wls/actions/MigrateWlsEjbDeploymentDescriptorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void shouldOverwriteTimeoutIfAttributeExist() {
152152
"import javax.ejb.Stateless;\n" +
153153
"import org.springframework.transaction.annotation.Transactional;\n" +
154154
"@Stateless(name=\"daFoo\")\n" +
155-
"@Transactional(timeout = 200000)\n" +
155+
"@Transactional(timeout=200000)\n" +
156156
"public class Foo {}"
157157
);
158158
}

0 commit comments

Comments
 (0)