pathExpressions;
+
+ @Override
+ public @NotNull String getDisplayName()
+ {
+ return "AddSpringPropertyIfClassExists";
+ }
+
+ @Override
+ public @NotNull String getDescription()
+ {
+ return "Add a spring property to the properties file if a specific class exists.";
+ }
+
+ @Override
+ public @NotNull TreeVisitor, ExecutionContext> getVisitor()
+ {
+ if(!this.doesClasspathContainClass(this.className))
+ {
+ return TreeVisitor.noop();
+ }
+ return new AddSpringProperty(
+ this.property, this.value, this.comment, this.pathExpressions
+ ).getVisitor();
+ }
+
+ private boolean doesClasspathContainClass(final String classToCheck)
+ {
+ try
+ {
+ Class.forName(classToCheck, false, this.getClass().getClassLoader());
+ return true;
+ }
+ catch(final ClassNotFoundException e)
+ {
+ return false;
+ }
+ }
+}
diff --git a/spring-data-eclipse-store-migration/src/main/resources/META-INF/rewrite/rewrite.yml b/spring-data-eclipse-store-migration/src/main/resources/META-INF/rewrite/rewrite.yml
new file mode 100644
index 0000000..5cbf598
--- /dev/null
+++ b/spring-data-eclipse-store-migration/src/main/resources/META-INF/rewrite/rewrite.yml
@@ -0,0 +1,75 @@
+---
+type: specs.openrewrite.org/v1beta/recipe
+name: software.xdev.spring.data.eclipse.store.JpaMigration
+displayName: JpaMigration
+description: Migrate from Spring Data JPA to latest Spring Data EclipseStore version.
+tags:
+ - spring-data-jpa
+ - spring-data
+ - eclipse-store
+ - eclipsestore
+recipeList:
+
+ - software.xdev.spring.data.eclipse.store.AddAnnotationToOtherAnnotation:
+ existingAnnotationType: 'org.springframework.boot.autoconfigure.SpringBootApplication'
+ annotationTypeToAdd: 'software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories'
+ classPath: 'spring-data-eclipse-store'
+ annotationTypeToAddSimpleName: 'EnableEclipseStoreRepositories'
+
+ - software.xdev.spring.data.eclipse.store.AddSpringPropertyIfClassExists:
+ className: 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration'
+ property: 'spring.autoconfigure.exclude'
+ value: 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration'
+ comment: 'This suppresses the use of JPA in the project. It is needed to let EclipseStore coexist with JPA.'
+
+ - org.openrewrite.maven.AddDependency:
+ groupId: software.xdev
+ artifactId: spring-data-eclipse-store
+ version: 1.0.2
+ acceptTransitive: true
+
+ - org.openrewrite.maven.AddPlugin:
+ groupId: org.springframework.boot
+ artifactId: spring-boot-maven-plugin
+ version: 3.2.2
+ configuration: --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED
+
+ - org.openrewrite.maven.ChangePluginConfiguration:
+ groupId: org.springframework.boot
+ artifactId: spring-boot-maven-plugin
+ configuration: --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED
+
+ - org.openrewrite.java.RemoveAnnotation:
+ # https://docs.openrewrite.org/reference/method-patterns
+ annotationPattern: '@org.springframework.data.jpa.repository.Query *(..)'
+
+ - org.openrewrite.java.RemoveAnnotation:
+ annotationPattern: '@org.springframework.data.jpa.repository.config.EnableJpaRepositories *(..)'
+
+ # Change all the spring framework repositories to specifically use EclipseStore repositories.
+
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: org.springframework.data.repository.Repository
+ newFullyQualifiedTypeName: software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStoreCustomRepository
+
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: org.springframework.data.repository.CrudRepository
+ newFullyQualifiedTypeName: software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStoreCrudRepository
+
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: org.springframework.data.repository.ListCrudRepository
+ newFullyQualifiedTypeName: software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStoreListCrudRepository
+
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: org.springframework.data.repository.PagingAndSortingRepositoryRepository
+ newFullyQualifiedTypeName: software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStorePagingAndSortingRepositoryRepository
+
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: org.springframework.data.repository.ListPagingAndSortingRepositoryRepository
+ newFullyQualifiedTypeName: software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStoreListPagingAndSortingRepositoryRepository
+
+ # Change all the JPA repositories to specifically use EclipseStore repositories.
+
+ - org.openrewrite.java.ChangeType:
+ oldFullyQualifiedTypeName: org.springframework.data.jpa.repository.JpaRepository
+ newFullyQualifiedTypeName: software.xdev.spring.data.eclipse.store.repository.interfaces.EclipseStoreRepository
diff --git a/spring-data-eclipse-store-migration/src/test/java/software/xdev/spring/data/eclipse/store/AddAnnotationToOtherAnnotationTest.java b/spring-data-eclipse-store-migration/src/test/java/software/xdev/spring/data/eclipse/store/AddAnnotationToOtherAnnotationTest.java
new file mode 100644
index 0000000..4ed5c1a
--- /dev/null
+++ b/spring-data-eclipse-store-migration/src/test/java/software/xdev/spring/data/eclipse/store/AddAnnotationToOtherAnnotationTest.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright © 2023 XDEV Software (https://xdev.software)
+ *
+ * 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
+ *
+ * http://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 software.xdev.spring.data.eclipse.store;
+
+import static org.openrewrite.java.Assertions.java;
+
+import org.junit.jupiter.api.Test;
+import org.openrewrite.java.Java17Parser;
+import org.openrewrite.test.RecipeSpec;
+import org.openrewrite.test.RewriteTest;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories;
+
+
+class AddAnnotationToOtherAnnotationTest implements RewriteTest
+{
+
+ @Override
+ public void defaults(final RecipeSpec recipeSpec)
+ {
+ recipeSpec
+ .recipe(new AddAnnotationToOtherAnnotation(
+ SpringBootApplication.class.getName(),
+ EnableEclipseStoreRepositories.class.getName(),
+ "spring-data-eclipse-store",
+ EnableEclipseStoreRepositories.class.getSimpleName()))
+ .parser(Java17Parser.builder()
+ .logCompilationWarningsAndErrors(true)
+ .classpath("spring-boot-autoconfigure", "spring-data-eclipse-store"));
+ }
+
+ @Test
+ void testSimpleSingle()
+ {
+ this.rewriteRun(
+ java(
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+ @SpringBootApplication
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """,
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+ import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories;
+
+ @EnableEclipseStoreRepositories
+ @SpringBootApplication
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void testSimpleMultiple()
+ {
+ this.rewriteRun(
+ java(
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+ @SpringBootApplication
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """,
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+ import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories;
+
+ @EnableEclipseStoreRepositories
+ @SpringBootApplication
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """
+ ),
+ java(
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+ @SpringBootApplication
+ class B
+ {
+ public B()
+ {
+ }
+ }
+ """,
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+ import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories;
+
+ @EnableEclipseStoreRepositories
+ @SpringBootApplication
+ class B
+ {
+ public B()
+ {
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void testAlreadyAdded()
+ {
+ this.rewriteRun(
+ java(
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+ import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories;
+
+ @EnableEclipseStoreRepositories
+ @SpringBootApplication
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void testSimpleNoAnnotation()
+ {
+ this.rewriteRun(
+ java(
+ """
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """
+ )
+ );
+ }
+
+ @Test
+ void testSimpleNoAnnotationAndAnnotation()
+ {
+ this.rewriteRun(
+ java(
+ """
+ class B
+ {
+ public B()
+ {
+ }
+ }
+ """
+ ),
+ java(
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+ @SpringBootApplication
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """,
+ """
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
+ import software.xdev.spring.data.eclipse.store.repository.config.EnableEclipseStoreRepositories;
+
+ @EnableEclipseStoreRepositories
+ @SpringBootApplication
+ class A
+ {
+ public A()
+ {
+ }
+ }
+ """
+ )
+ );
+ }
+}
diff --git a/spring-data-eclipse-store-migration/src/test/java/software/xdev/spring/data/eclipse/store/AddSpringPropertyIfClassExistsTest.java b/spring-data-eclipse-store-migration/src/test/java/software/xdev/spring/data/eclipse/store/AddSpringPropertyIfClassExistsTest.java
new file mode 100644
index 0000000..cf9b8f4
--- /dev/null
+++ b/spring-data-eclipse-store-migration/src/test/java/software/xdev/spring/data/eclipse/store/AddSpringPropertyIfClassExistsTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 2023 XDEV Software (https://xdev.software)
+ *
+ * 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
+ *
+ * http://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 software.xdev.spring.data.eclipse.store;
+
+import static org.openrewrite.properties.Assertions.properties;
+import static org.openrewrite.yaml.Assertions.yaml;
+
+import org.junit.jupiter.api.Test;
+import org.openrewrite.test.RecipeSpec;
+import org.openrewrite.test.RewriteTest;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
+
+
+@SuppressWarnings("checkstyle:LineLength")
+class AddSpringPropertyIfClassExistsTest implements RewriteTest
+{
+
+ @Override
+ public void defaults(final RecipeSpec recipeSpec)
+ {
+ recipeSpec
+ .recipe(new AddSpringPropertyIfClassExists(
+ HibernateJpaAutoConfiguration.class.getName(),
+ "spring.autoconfigure.exclude",
+ DataSourceAutoConfiguration.class.getName()
+ + ","
+ + DataSourceTransactionManagerAutoConfiguration.class.getName()
+ + ","
+ + HibernateJpaAutoConfiguration.class.getName(),
+ "", null));
+ }
+
+ @Test
+ void testSimpleProperties()
+ {
+ this.rewriteRun(
+ properties(
+ "",
+ """
+ spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """,
+ s -> s.path("application.properties")
+ )
+ );
+ }
+
+ @Test
+ void testSimpleYaml()
+ {
+ this.rewriteRun(
+ yaml(
+ "",
+ """
+ spring:
+ autoconfigure:
+ exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """,
+ s -> s.path("application.yml")
+ )
+ );
+ }
+
+ @Test
+ void testMultipleYamlAlsoInTestFolder()
+ {
+ this.rewriteRun(
+ yaml(
+ "",
+ """
+ spring:
+ autoconfigure:
+ exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """,
+ s -> s.path("/src/main/resources/application.yml")
+ ),
+ yaml(
+ "",
+ """
+ spring:
+ autoconfigure:
+ exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """,
+ s -> s.path("/src/test/resources/application.yml")
+ ),
+ yaml(
+ "",
+ """
+ spring:
+ autoconfigure:
+ exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """,
+ s -> s.path("application.yml")
+ ),
+ yaml(
+ "",
+ s -> s.path("no-application.yml")
+ )
+ );
+ }
+
+ @Test
+ void testWrongFileNameYaml()
+ {
+ this.rewriteRun(
+ yaml(
+ "",
+ s -> s.path("random.yml")
+ )
+ );
+ }
+
+ @Test
+ void testWrongFileNameProperties()
+ {
+ this.rewriteRun(
+ properties(
+ "",
+ s -> s.path("random.properties")
+ )
+ );
+ }
+
+ /**
+ * It's not clear if this is a desired behavior, but since the Open Rewrite Recipe
+ * {@link org.openrewrite.java.spring.AddSpringProperty} is doing this, and we are only using this recipe, this is
+ * how it works now.
+ *
+ * Might change in the future.
+ *
+ */
+ @Test
+ void testMultipleProperties()
+ {
+ this.rewriteRun(
+ properties(
+ "",
+ """
+ spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """,
+ s -> s.path("application.properties")
+ ),
+ yaml(
+ "",
+ """
+ spring:
+ autoconfigure:
+ exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """,
+ s -> s.path("application.yml")
+ )
+ );
+ }
+
+ @Test
+ void testExisting()
+ {
+ this.rewriteRun(
+ properties(
+ """
+ spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
+ """
+ )
+ );
+ }
+
+ @Test
+ void testClassNotExisting()
+ {
+ this.rewriteRun(
+ recipeSpec ->
+ recipeSpec.recipe(new AddSpringPropertyIfClassExists(
+ "not.existing.Class",
+ "spring.autoconfigure.exclude",
+ "DummyValue",
+ "",
+ null)),
+ properties(
+ "",
+ s -> s.path("application.properties")
+ )
+ );
+ }
+}
diff --git a/template-placeholder-demo/pom.xml b/template-placeholder-demo/pom.xml
deleted file mode 100644
index 1af633c..0000000
--- a/template-placeholder-demo/pom.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
- 4.0.0
-
-
- software.xdev
- template-placeholder-root
- 1.0.0-SNAPSHOT
-
-
- template-placeholder-demo
- 1.0.0-SNAPSHOT
- jar
-
-
- XDEV Software
- https://xdev.software
-
-
-
- 17
- ${javaVersion}
-
- UTF-8
- UTF-8
-
- software.xdev.Application
-
-
-
-
- software.xdev
- template-placeholder
- ${project.version}
-
-
-
-
- ${project.artifactId}
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.13.0
-
- ${maven.compiler.release}
-
- -proc:none
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 3.7.1
-
-
-
- ${mainClass}
-
-
- true
-
-
-
- jar-with-dependencies
-
- false
-
-
-
- make-assembly
- package
-
- single
-
-
-
-
-
-
-