Skip to content

Adds action to set unitName on PersistenceContext annotation to default #401

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -319,19 +319,32 @@ protected void replaceFile(Path target, Path source) {
}

protected String loadJavaFileFromSubmodule(String submodulePath, String packageName, String className) {
return loadJavaFileFromModule(submodulePath, packageName, className, "src/main/java");
}

protected String loadTestJavaFileFromSubmodule(String submodulePath, String packageName, String className) {
return loadJavaFileFromModule(submodulePath, packageName, className, "src/test/java");
}

private String loadJavaFileFromModule(String submodulePath, String packageName, String className, String sourceDir) {
try {
Path classPath = testDir.resolve(submodulePath + "src/main/java").resolve(packageName.replace(".", "/"));
Path classPath = testDir.resolve(submodulePath + sourceDir).resolve(packageName.replace(".", "/"));
Path classFile = classPath.resolve(className + ".java");
return Files.readString(classFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}


protected String loadJavaFile(String packageName, String className) {
return loadJavaFileFromSubmodule("", packageName, className);
}

protected String loadTestJavaFile(String packageName, String className) {
return loadTestJavaFileFromSubmodule("", packageName, className);
}

/**
* Starts {@code image} as Docker container exposing {@code ports} and waiting for {@code httpEndpoint} to be available.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class MigrateJpaApplicationIntegrationTest extends IntegrationTestBaseClass {

@Override
Expand All @@ -41,7 +43,47 @@ void migrateJpaApplication() {
"migrate-stateless-ejb",
"migrate-jpa-to-spring-boot"
);
// TODO: add assertions

assertThat(super.loadJavaFile("org.superbiz.injection.h3jpa", "SpringBootApp")).isNotEmpty();
assertThat(super.loadTestJavaFile("org.superbiz.injection.h3jpa", "SpringBootAppTest")).isNotEmpty();
String movies = loadJavaFile("org.superbiz.injection.h3jpa", "Movies");
assertThat(movies).contains(
"""
package org.superbiz.injection.h3jpa;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;

@Service
@Transactional
public class Movies {

@PersistenceContext(unitName = "default")
private EntityManager entityManager;

public void addMovie(Movie movie) throws Exception {
entityManager.persist(movie);
}

public void deleteMovie(Movie movie) throws Exception {
movie = entityManager.find(Movie.class, movie.getId());
entityManager.remove(movie);
}

public List<Movie> getMovies() throws Exception {
Query query = entityManager.createQuery("SELECT m from Movie as m");
return query.getResultList();
}

}
"""
);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
@Stateless
public class Movies {

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

public void addMovie(Movie movie) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,11 @@ private void initDependency(ResolvedDependency d, Map<ResolvedDependency, Path>.
if(dependencyPath != null) {
Stream.of(maps).forEach(m -> m.put(d, dependencyPath));
} else {
System.out.println(d.getGav() + " has no jars. It has type " + d.getType());
initializeDepeendencies(new HashSet<>(d.getDependencies()));
}
} else {
initializeDepeendencies(new HashSet(d.getDependencies()));
}


// Optional<Path> dependencyPath = dependencyHelper.downloadArtifact(d);
// if (dependencyPath.isPresent()) {
// Stream.of(maps).forEach(m -> m.put(d, dependencyPath.get()));
// }
}

private boolean isExternalDependency(ResolvedDependency d) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/
package org.springframework.sbm.java.impl;

import org.openrewrite.java.AddOrUpdateAnnotationAttribute;
import org.openrewrite.java.JavaParser;
import org.springframework.sbm.java.api.Annotation;
import org.springframework.sbm.java.api.Expression;
import org.springframework.sbm.java.refactoring.JavaRefactoring;
import org.springframework.sbm.support.openrewrite.java.AddOrReplaceAnnotationAttribute;
import lombok.Getter;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.tree.J;
Expand Down Expand Up @@ -79,8 +79,8 @@ public boolean hasAttribute(String attribute) {

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

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.sbm.support.openrewrite.java;
package org.openrewrite.java;

import org.openrewrite.java.AddOrUpdateAnnotationAttribute;
import org.openrewrite.java.tree.JavaType;
import org.springframework.sbm.java.OpenRewriteTestSupport;
import org.junit.jupiter.api.Test;
import org.openrewrite.ExecutionContext;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.tree.J;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class AddOrReplaceAnnotationAttributeTest {
public class AddOrUpdateAnnotationAttributeTest {


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

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

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

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

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

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

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

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

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


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2021 - 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.sbm.jee.jpa.actions;

import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.engine.recipe.AbstractAction;
import org.springframework.sbm.java.api.JavaSource;

import java.util.List;
import java.util.stream.Collectors;

/**
* @author Fabian Krüger
*/
public class RenameUnitNameOfPersistenceContextAnnotationsToDefault extends AbstractAction {

public static final String PERSISTENCE_CONTEXT = "javax.persistence.PersistenceContext";

@Override
public void apply(ProjectContext context) {
List<JavaSource> javaSources = context
.getProjectJavaSources()
.asStream()
.filter(s -> s
.getTypes()
.stream()
.flatMap(t -> t.getMembers().stream())
.anyMatch(m -> m.hasAnnotation(PERSISTENCE_CONTEXT)))
.collect(Collectors.toList());

javaSources.forEach(s -> {
s.getTypes()
.stream()
.flatMap(t -> t.getMembers().stream())
.filter(m -> m.hasAnnotation(PERSISTENCE_CONTEXT))
.map(m -> m.getAnnotation(PERSISTENCE_CONTEXT))
.findFirst()
.get()
.setAttribute("unitName", "default", String.class);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,9 @@
condition:
type: org.springframework.sbm.common.migration.conditions.TrueCondition
pattern: '/**/persistence.xml'

- type: org.springframework.sbm.jee.jpa.actions.RenameUnitNameOfPersistenceContextAnnotationsToDefault
description: Set 'unitName' attribute from @PersistenceContext annotations to 'default' when different
condition:
type: org.springframework.sbm.java.migration.conditions.HasMemberAnnotation
annotation: javax.persistence.PersistenceContext
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2021 - 2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.sbm.jee.jpa.actions;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.project.resource.TestProjectContext;

/**
* @author Fabian Krüger
*/
class RenameUnitNameOfPersistenceContextAnnotationsToDefaultTest {
@Test
void shouldRemoveUnitNameAttribute() {

String javaCode = """
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
public class Foo {
@PersistenceContext(unitName = "foo")
private EntityManager entityManager;
}
""";

ProjectContext context = TestProjectContext
.buildProjectContext()
.addJavaSource("src/main/java", javaCode)
.withBuildFileHavingDependencies("javax.persistence:javax.persistence-api:2.2", "javax.ejb:javax.ejb-api:3.2")
.build();

RenameUnitNameOfPersistenceContextAnnotationsToDefault sut = new RenameUnitNameOfPersistenceContextAnnotationsToDefault();

sut.apply(context);

String expected = """
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
public class Foo {
@PersistenceContext(unitName = "default")
private EntityManager entityManager;
}
""";


Assertions.assertThat(context.getProjectJavaSources().list().get(0).print()).isEqualTo(expected);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.springframework.sbm.jee.jpa.actions.MigratePersistenceXmlToApplicationPropertiesAction;
import freemarker.template.Configuration;
import org.junit.jupiter.api.Test;
import org.springframework.sbm.jee.jpa.actions.RenameUnitNameOfPersistenceContextAnnotationsToDefault;

import java.nio.file.Path;
import java.util.List;
Expand All @@ -53,7 +54,9 @@ void migrateJpaToSpringBootRecipe() {
RemoveDependenciesMatchingRegex.class,
AddTypeAnnotationToTypeAnnotatedWith.class,
MigrateEclipseLinkToSpringBoot.class,
DeleteFileMatchingPattern.class);
DeleteFileMatchingPattern.class,
RenameUnitNameOfPersistenceContextAnnotationsToDefault.class
);
assertThatRecipeHasCondition(recipe, FileExist.class);

// Action: migrate persistence.xml to Spring application.properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void shouldOverwriteTimeoutIfAttributeExist() {
"import javax.ejb.Stateless;\n" +
"import org.springframework.transaction.annotation.Transactional;\n" +
"@Stateless(name=\"daFoo\")\n" +
"@Transactional(timeout = 200000)\n" +
"@Transactional(timeout=200000)\n" +
"public class Foo {}"
);
}
Expand Down