Skip to content

Commit 5819247

Browse files
committed
Implement multimodule solution
1 parent 616ec24 commit 5819247

File tree

2 files changed

+110
-20
lines changed

2 files changed

+110
-20
lines changed

src/main/java/org/openrewrite/java/migrate/jakarta/HasNoJakartaNullAnnotations.java

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,21 @@
1515
*/
1616
package org.openrewrite.java.migrate.jakarta;
1717

18+
import lombok.Value;
1819
import org.jspecify.annotations.Nullable;
1920
import org.openrewrite.ExecutionContext;
2021
import org.openrewrite.ScanningRecipe;
2122
import org.openrewrite.Tree;
2223
import org.openrewrite.TreeVisitor;
23-
import org.openrewrite.java.JavaIsoVisitor;
24+
import org.openrewrite.java.marker.JavaProject;
2425
import org.openrewrite.java.search.FindAnnotations;
2526
import org.openrewrite.java.tree.J;
2627
import org.openrewrite.marker.SearchResult;
2728

28-
import java.util.concurrent.atomic.AtomicBoolean;
29+
import java.util.HashSet;
30+
import java.util.Set;
2931

30-
public class HasNoJakartaNullAnnotations extends ScanningRecipe<AtomicBoolean> {
32+
public class HasNoJakartaNullAnnotations extends ScanningRecipe<HasNoJakartaNullAnnotations.Accumulator> {
3133
@Override
3234
public String getDisplayName() {
3335
return "Project has no Jakarta null annotations";
@@ -38,38 +40,43 @@ public String getDescription() {
3840
return "Search for @Nonnull and @Nullable annotations, mark all source as found if no annotations are found.";
3941
}
4042

43+
@Value
44+
public static class Accumulator {
45+
Set<JavaProject> projectsWithDependency;
46+
}
47+
4148
@Override
42-
public AtomicBoolean getInitialValue(ExecutionContext ctx) {
43-
return new AtomicBoolean();
49+
public Accumulator getInitialValue(ExecutionContext ctx) {
50+
return new Accumulator(new HashSet<>());
4451
}
4552

4653
@Override
47-
public TreeVisitor<?, ExecutionContext> getScanner(AtomicBoolean acc) {
48-
return new JavaIsoVisitor<ExecutionContext>() {
54+
public TreeVisitor<?, ExecutionContext> getScanner(HasNoJakartaNullAnnotations.Accumulator acc) {
55+
return new TreeVisitor<Tree, ExecutionContext>() {
4956
@Override
50-
public J.CompilationUnit visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
51-
J.CompilationUnit c = super.visitCompilationUnit(cu, ctx);
52-
if (!acc.get()) {
53-
if ((!FindAnnotations.find(c, "@jakarta.annotation.Nonnull", true).isEmpty()) ||
54-
(!FindAnnotations.find(c, "@jakarta.annotation.Nullable", true).isEmpty())) {
55-
acc.set(true);
56-
}
57+
public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
58+
assert tree != null;
59+
if (tree instanceof J) {
60+
tree.getMarkers().findFirst(JavaProject.class)
61+
.filter(__ ->!FindAnnotations.find((J) tree, "@jakarta.annotation.Nonnull", true).isEmpty() ||
62+
!FindAnnotations.find((J) tree, "@jakarta.annotation.Nullable", true).isEmpty())
63+
.ifPresent(it -> acc.getProjectsWithDependency().add(it));
5764
}
58-
return cu;
65+
return tree;
5966
}
6067
};
6168
}
6269

6370
@Override
64-
public TreeVisitor<?, ExecutionContext> getVisitor(AtomicBoolean acc) {
71+
public TreeVisitor<?, ExecutionContext> getVisitor(HasNoJakartaNullAnnotations.Accumulator acc) {
6572
return new TreeVisitor<Tree, ExecutionContext>() {
6673
@Override
6774
public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
6875
assert tree != null;
69-
if (!acc.get()) {
70-
return SearchResult.found(tree, "Project has no Jakarta null annotations");
71-
}
72-
return tree;
76+
return tree.getMarkers().findFirst(JavaProject.class)
77+
.filter(it -> !acc.getProjectsWithDependency().contains(it))
78+
.map(__ -> SearchResult.found(tree, "Project has no Jakarta null annotations"))
79+
.orElse(tree);
7380
}
7481
};
7582
}

src/test/java/org/openrewrite/java/migrate/jakarta/JavaxToJakartaTest.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import org.openrewrite.test.RecipeSpec;
2525
import org.openrewrite.test.RewriteTest;
2626

27+
import static org.openrewrite.gradle.Assertions.buildGradle;
28+
import static org.openrewrite.gradle.Assertions.settingsGradle;
29+
import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi;
2730
import static org.openrewrite.java.Assertions.*;
2831
import static org.openrewrite.maven.Assertions.pomXml;
2932
import static org.openrewrite.xml.Assertions.xml;
@@ -734,6 +737,86 @@ public String safeUpperCase(@Nullable String input) {
734737
);
735738
}
736739

740+
@Test
741+
void multiProjectWithSpringBoot3StarterWebShouldRemoveJakartaDependencyWhenUsingNullableAnnotationWhenApplicable() {
742+
rewriteRun(
743+
spec -> spec.beforeRecipe(withToolingApi()).parser(JavaParser.fromJavaVersion().dependsOn(javaxServlet, jakartaAnnotation)),
744+
mavenProject("multi-project-build",
745+
//language=groovy
746+
settingsGradle("""
747+
include 'project-with-null-annotations'
748+
include 'project-without-null-annotations'
749+
"""),
750+
mavenProject("project-with-null-annotations",
751+
//language=groovy
752+
buildGradle(
753+
"""
754+
plugins {
755+
id 'java'
756+
}
757+
758+
repositories {
759+
mavenCentral()
760+
}
761+
762+
dependencies {
763+
implementation 'jakarta.annotation:jakarta.annotation-api:1.3.5'
764+
implementation 'org.springframework.boot:spring-boot-starter-web'
765+
}
766+
""",
767+
"""
768+
plugins {
769+
id 'java'
770+
}
771+
772+
repositories {
773+
mavenCentral()
774+
}
775+
776+
dependencies {
777+
implementation 'jakarta.annotation:jakarta.annotation-api:2.0.0'
778+
implementation 'org.springframework.boot:spring-boot-starter-web'
779+
}
780+
"""
781+
),
782+
srcMainJava(
783+
//language=java
784+
java(
785+
"""
786+
import jakarta.annotation.Nullable;
787+
788+
public class TestApplication {
789+
@Nullable
790+
public String safeUpperCase(@Nullable String input) {
791+
return input == null ? null : input.toUpperCase();
792+
}
793+
}
794+
"""
795+
)
796+
)
797+
),
798+
mavenProject("project-without-null-annotations",
799+
//language=groovy
800+
buildGradle(
801+
"""
802+
plugins {
803+
id 'java'
804+
}
805+
806+
repositories {
807+
mavenCentral()
808+
}
809+
810+
dependencies {
811+
implementation 'org.springframework.boot:spring-boot-starter-web'
812+
}
813+
"""
814+
)
815+
)
816+
)
817+
);
818+
}
819+
737820
@Test
738821
void upgradeAnnotationApiFromV1ToV2() {
739822
rewriteRun(

0 commit comments

Comments
 (0)