diff --git a/recipes-unit-tests/src/test/java/io/quarkus/updates/core/CoreUpdate37Test.java b/recipes-unit-tests/src/test/java/io/quarkus/updates/core/CoreUpdate37Test.java
index 48e9b3d7e9..d34d139d4d 100644
--- a/recipes-unit-tests/src/test/java/io/quarkus/updates/core/CoreUpdate37Test.java
+++ b/recipes-unit-tests/src/test/java/io/quarkus/updates/core/CoreUpdate37Test.java
@@ -250,4 +250,569 @@ void testMavenPluginUpdatesDefaultGroupId() {
"""));
}
+
+ @Test
+ void testJpaModelgenNoChanges() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenOldDependency() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+ org.hibernate
+ hibernate-jpamodelgen
+ 5.4.3.Final
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenNewDependency() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+ 6.1.2.Final
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenNewDependencyManagedByQuarkusBom() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ io.quarkus
+ quarkus-bom
+ 3.6.4
+ pom
+ import
+
+
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+ 6.1.2.Final
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ io.quarkus
+ quarkus-bom
+ 3.6.4
+ pom
+ import
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenExistingConfig() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+ 6.1.2.Final
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+ none
+
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+ none
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenAnotherProcessor() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+ 6.1.2.Final
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+ none
+
+
+ another.annotation
+ processor
+
+
+
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+ none
+
+
+ another.annotation
+ processor
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenAnnotationProcessorAlreadyPresent() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+ 6.1.2.Final
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenOldJpaModelgenAnnotationProcessorAlreadyPresent() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ io.quarkus
+ quarkus-bom
+ 3.6.4
+ pom
+ import
+
+
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+ 6.1.2.Final
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ io.quarkus
+ quarkus-bom
+ 3.6.4
+ pom
+ import
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
+
+ @Test
+ void testJpaModelgenOldJpaModelgenAnnotationProcessorAlreadyPresentWithOutdatedVersion() {
+ //language=xml
+ rewriteRun(pomXml("""
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ io.quarkus
+ quarkus-bom
+ 3.6.4
+ pom
+ import
+
+
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+ 6.1.2.Final
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate
+ hibernate-jpamodelgen
+ 5.6.15.Final
+
+
+
+
+
+
+
+ """,
+ """
+
+ 4.0.0
+ io.quarkus.bot
+ release
+ 999-SNAPSHOT
+
+
+
+ io.quarkus
+ quarkus-bom
+ 3.6.4
+ pom
+ import
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.12.1
+
+
+
+ org.hibernate.orm
+ hibernate-jpamodelgen
+
+
+
+
+
+
+
+ """));
+ }
}
diff --git a/recipes/src/main/java/io/quarkus/updates/core/quarkus37/AddMavenCompilerAnnotationProcessor.java b/recipes/src/main/java/io/quarkus/updates/core/quarkus37/AddMavenCompilerAnnotationProcessor.java
new file mode 100644
index 0000000000..52b69e727f
--- /dev/null
+++ b/recipes/src/main/java/io/quarkus/updates/core/quarkus37/AddMavenCompilerAnnotationProcessor.java
@@ -0,0 +1,84 @@
+package io.quarkus.updates.core.quarkus37;
+
+import static org.openrewrite.xml.AddToTagVisitor.addToTag;
+
+import java.util.List;
+import java.util.Optional;
+
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Option;
+import org.openrewrite.Recipe;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.maven.MavenVisitor;
+import org.openrewrite.xml.tree.Xml;
+
+import lombok.EqualsAndHashCode;
+import lombok.Value;
+
+@Value
+@EqualsAndHashCode(callSuper = true)
+public class AddMavenCompilerAnnotationProcessor extends Recipe {
+
+ @Option(displayName = "Annotation processor groupId", description = "The groupId of the annotation processor.", example = "org.hibernate.orm", required = true)
+ String groupId;
+
+ @Option(displayName = "Annotation processor artifactId", description = "The artifactId of the annotation processor.", example = "hibernate-jpamodelgen", required = true)
+ String artifactId;
+
+ @Override
+ public String getDisplayName() {
+ return "Add an annotation processor to the Maven Compiler plugin configuration";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Add an annotation processor to the Maven Compiler plugin configuration.";
+ }
+
+ @Override
+ public TreeVisitor, ExecutionContext> getVisitor() {
+ return new MavenVisitor() {
+ @Override
+ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
+ Xml.Tag mavenCompilerPluginTag = (Xml.Tag) super.visitTag(tag, ctx);
+
+ if (isPluginTag("org.apache.maven.plugins", "maven-compiler-plugin")) {
+ Optional configuration = mavenCompilerPluginTag.getChild("configuration");
+
+ String annotationProcessorPath = "" + groupId + "\n" + artifactId
+ + "";
+
+ if (configuration.isPresent()) {
+ Optional annotationProcessorPathsWrapper = configuration.get()
+ .getChild("annotationProcessorPaths");
+ if (annotationProcessorPathsWrapper.isPresent()) {
+ List annotationProcessorPaths = annotationProcessorPathsWrapper.get().getChildren();
+ String childName = annotationProcessorPaths.size() > 0 ? annotationProcessorPaths.get(0).getName()
+ : "path";
+
+ if (!annotationProcessorPaths.stream()
+ .anyMatch(t -> groupId.equals(t.getChildValue("groupId").orElse(null))
+ && artifactId.equals(t.getChildValue("artifactId").orElse(null)))) {
+ mavenCompilerPluginTag = addToTag(mavenCompilerPluginTag, annotationProcessorPathsWrapper.get(),
+ Xml.Tag.build("<" + childName + ">\n" + annotationProcessorPath + "\n" + childName
+ + ">"),
+ getCursor().getParentOrThrow());
+ }
+ } else {
+ mavenCompilerPluginTag = addToTag(mavenCompilerPluginTag, configuration.get(),
+ Xml.Tag.build("\n\n" + annotationProcessorPath
+ + "\n\n"),
+ getCursor().getParentOrThrow());
+ }
+ } else {
+ mavenCompilerPluginTag = addToTag(mavenCompilerPluginTag,
+ Xml.Tag.build("\n\n\n" + annotationProcessorPath
+ + "\n\n\n"),
+ getCursor().getParentOrThrow());
+ }
+ }
+ return mavenCompilerPluginTag;
+ }
+ };
+ }
+}
diff --git a/recipes/src/main/java/io/quarkus/updates/core/quarkus37/ChangeMavenCompilerAnnotationProcessorGroupIdAndArtifactId.java b/recipes/src/main/java/io/quarkus/updates/core/quarkus37/ChangeMavenCompilerAnnotationProcessorGroupIdAndArtifactId.java
new file mode 100644
index 0000000000..eb3e5a7331
--- /dev/null
+++ b/recipes/src/main/java/io/quarkus/updates/core/quarkus37/ChangeMavenCompilerAnnotationProcessorGroupIdAndArtifactId.java
@@ -0,0 +1,220 @@
+package io.quarkus.updates.core.quarkus37;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Option;
+import org.openrewrite.Recipe;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.Validated;
+import org.openrewrite.internal.lang.Nullable;
+import org.openrewrite.maven.MavenDownloadingException;
+import org.openrewrite.maven.MavenTagInsertionComparator;
+import org.openrewrite.maven.MavenVisitor;
+import org.openrewrite.maven.table.MavenMetadataFailures;
+import org.openrewrite.maven.tree.MavenMetadata;
+import org.openrewrite.maven.tree.MavenResolutionResult;
+import org.openrewrite.maven.tree.ResolvedManagedDependency;
+import org.openrewrite.maven.tree.Scope;
+import org.openrewrite.semver.Semver;
+import org.openrewrite.semver.VersionComparator;
+import org.openrewrite.xml.AddToTagVisitor;
+import org.openrewrite.xml.ChangeTagValueVisitor;
+import org.openrewrite.xml.RemoveContentVisitor;
+import org.openrewrite.xml.tree.Xml;
+
+import lombok.EqualsAndHashCode;
+import lombok.Value;
+
+@Value
+@EqualsAndHashCode(callSuper = true)
+public class ChangeMavenCompilerAnnotationProcessorGroupIdAndArtifactId extends Recipe {
+
+ @EqualsAndHashCode.Exclude
+ MavenMetadataFailures metadataFailures = new MavenMetadataFailures(this);
+
+ @Option(displayName = "Old groupId", description = "The old groupId to replace. The groupId is the first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob expressions.", example = "org.hibernate")
+ String oldGroupId;
+
+ @Option(displayName = "Old artifactId", description = "The old artifactId to replace. The artifactId is the second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob expressions.", example = "hibernate-jpamodelgen")
+ String oldArtifactId;
+
+ @Option(displayName = "New groupId", description = "The new groupId to use. Defaults to the existing group id.", example = "org.hibernate.orm", required = false)
+ @Nullable
+ String newGroupId;
+
+ @Option(displayName = "New artifactId", description = "The new artifactId to use. Defaults to the existing artifact id.", example = "hibernate-jpamodelgen", required = false)
+ @Nullable
+ String newArtifactId;
+
+ @Option(displayName = "New version", description = "An exact version number or node-style semver selector used to select the version number.", example = "29.X", required = false)
+ @Nullable
+ String newVersion;
+
+ @Option(displayName = "Version pattern", description = "Allows version selection to be extended beyond the original Node Semver semantics. So for example,"
+ +
+ "Setting 'version' to \"25-29\" can be paired with a metadata pattern of \"-jre\" to select Guava 29.0-jre", example = "-jre", required = false)
+ @Nullable
+ String versionPattern;
+
+ @Option(displayName = "Override managed version", description = "If the new annotation processor has a managed version, this flag can be used to explicitly set the version on the annotation processor. The default for this flag is `false`.", required = false)
+ @Nullable
+ Boolean overrideManagedVersion;
+
+ @Override
+ public String getDisplayName() {
+ return "Change Maven Compiler plugin annotation processor groupId, artifactId and/or the version";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Change the groupId, artifactId and/or the version of a specified Maven Compiler plugin annotation processor.";
+ }
+
+ @Override
+ public Validated