diff --git a/.github/workflows/build-sbm-revamp.yml b/.github/workflows/build-sbm-revamp.yml
index 4049b2640..30599208f 100644
--- a/.github/workflows/build-sbm-revamp.yml
+++ b/.github/workflows/build-sbm-revamp.yml
@@ -53,10 +53,10 @@ jobs:
run: mvn -DskipTests --batch-mode install --projects :sbm-support-weblogic
- name: sbm-recipes-jee-to-boot (build)
- run: mvn -DskipTests --batch-mode --projects :sbm-recipes-jee-to-boot
+ run: mvn -DskipTests --batch-mode install --projects :sbm-recipes-jee-to-boot
- name: sbm-recipes-spring-cloud (build)
- run: mvn -DskipTests --batch-mode --projects :sbm-recipes-spring-cloud
+ run: mvn -DskipTests --batch-mode install --projects :sbm-recipes-spring-cloud
- name: sbm-recipes-boot-upgrade (build)
- run: mvn -DskipTests --batch-mode --projects :sbm-recipes-boot-upgrade
\ No newline at end of file
+ run: mvn -DskipTests --batch-mode install --projects :sbm-recipes-boot-upgrade
\ No newline at end of file
diff --git a/components/recipe-test-support/pom.xml b/components/recipe-test-support/pom.xml
index c425cafca..e3f6d31d7 100644
--- a/components/recipe-test-support/pom.xml
+++ b/components/recipe-test-support/pom.xml
@@ -66,6 +66,11 @@
test-jar
compile
+
+ commons-io
+ commons-io
+ 2.13.0
+
\ No newline at end of file
diff --git a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java
index 35512fad3..3094c2a29 100644
--- a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java
+++ b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/ProjectContextFileSystemTestSupport.java
@@ -21,7 +21,6 @@
import org.springframework.core.io.Resource;
import org.springframework.sbm.engine.commands.ScanCommand;
import org.springframework.sbm.engine.context.ProjectContext;
-import org.springframework.sbm.parsers.RewriteExecutionContext;
import org.springframework.sbm.project.parser.ProjectContextInitializer;
import java.io.IOException;
diff --git a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java
index 3b868ecba..fa73e5452 100644
--- a/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java
+++ b/components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeIntegrationTestSupport.java
@@ -15,6 +15,7 @@
*/
package org.springframework.sbm.test;
+import org.apache.commons.io.FileUtils;
import org.springframework.sbm.engine.commands.ApplicableRecipeListCommand;
import org.springframework.sbm.engine.commands.ApplyCommand;
import org.springframework.sbm.engine.commands.ScanCommand;
@@ -26,7 +27,6 @@
import freemarker.template.Configuration;
import lombok.AccessLevel;
import lombok.Setter;
-import org.apache.commons.io.FileUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
diff --git a/components/sbm-core/pom.xml b/components/sbm-core/pom.xml
index 574cb33e0..8127d0e55 100644
--- a/components/sbm-core/pom.xml
+++ b/components/sbm-core/pom.xml
@@ -173,7 +173,13 @@
tests
test
-
+
+ commons-io
+ commons-io
+ 2.13.0
+ test
+
+
com.fasterxml.jackson.dataformat
jackson-dataformat-xml
2.14.1
diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/java/impl/DependencyChangeHandler.java b/components/sbm-core/src/main/java/org/springframework/sbm/java/impl/DependencyChangeHandler.java
index 5c6dae61a..d676a9891 100644
--- a/components/sbm-core/src/main/java/org/springframework/sbm/java/impl/DependencyChangeHandler.java
+++ b/components/sbm-core/src/main/java/org/springframework/sbm/java/impl/DependencyChangeHandler.java
@@ -35,7 +35,6 @@
import org.springframework.sbm.engine.context.ProjectContextHolder;
import org.springframework.sbm.java.api.JavaSource;
import org.springframework.sbm.parsers.JavaParserBuilder;
-import org.springframework.sbm.parsers.SortedProjects;
import org.springframework.sbm.parsers.SourceFileParser;
import org.springframework.sbm.utils.JavaHelper;
import org.springframework.stereotype.Component;
@@ -43,7 +42,6 @@
import java.io.ByteArrayInputStream;
import java.nio.file.Path;
import java.util.*;
-import java.util.stream.Stream;
/**
* @author Fabian Krüger
diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java
index 3b3e9378c..48ea62a2c 100644
--- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java
+++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/MavenProjectParser.java
@@ -18,37 +18,18 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.openrewrite.ExecutionContext;
-import org.openrewrite.Parser;
import org.openrewrite.SourceFile;
-import org.openrewrite.internal.ListUtils;
-import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.JavaParser;
-import org.openrewrite.java.marker.JavaSourceSet;
-import org.openrewrite.java.tree.J;
-import org.openrewrite.marker.GitProvenance;
-import org.openrewrite.marker.Marker;
-import org.openrewrite.marker.ci.BuildEnvironment;
-import org.openrewrite.maven.MavenExecutionContextView;
-import org.openrewrite.maven.MavenSettings;
-import org.openrewrite.maven.tree.*;
import org.openrewrite.maven.utilities.MavenArtifactDownloader;
-import org.openrewrite.xml.tree.Xml;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.io.Resource;
-import org.springframework.sbm.build.impl.MavenBuildFileUtil;
import org.springframework.sbm.build.impl.RewriteMavenParser;
-import org.springframework.sbm.engine.events.*;
-import org.springframework.sbm.parsers.RewriteMavenProjectParser;
import org.springframework.sbm.parsers.RewriteProjectParser;
import org.springframework.sbm.scopes.ProjectMetadata;
import org.springframework.stereotype.Component;
-import java.io.IOException;
-import java.io.InputStream;
import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.List;
/**
* Parse a Maven project on disk into a list of {@link org.openrewrite.SourceFile} including
diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/java/impl/ProjectJavaSourcesImplTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/java/impl/ProjectJavaSourcesImplTest.java
index 1b09ba9dc..3b421dc5a 100644
--- a/components/sbm-core/src/test/java/org/springframework/sbm/java/impl/ProjectJavaSourcesImplTest.java
+++ b/components/sbm-core/src/test/java/org/springframework/sbm/java/impl/ProjectJavaSourcesImplTest.java
@@ -20,7 +20,6 @@
import org.springframework.beans.factory.UnsatisfiedDependencyException;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.java.api.JavaSourceAndType;
-import org.springframework.sbm.parsers.MavenExecutionResultException;
import org.springframework.sbm.project.resource.TestProjectContext;
import java.util.List;
diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java
index 81d0424a9..52b130190 100644
--- a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java
+++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java
@@ -16,7 +16,6 @@
package org.springframework.sbm.project.resource;
import freemarker.template.Configuration;
-import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.jetbrains.annotations.NotNull;
import org.openrewrite.ExecutionContext;
@@ -31,7 +30,6 @@
import org.springframework.sbm.build.impl.OpenRewriteMavenBuildFile;
import org.springframework.sbm.engine.context.ProjectContext;
import org.springframework.sbm.engine.context.ProjectContextSerializer;
-import org.springframework.sbm.java.impl.RewriteJavaParser;
import org.springframework.sbm.java.util.JavaSourceUtil;
import org.springframework.sbm.project.TestDummyResource;
import org.springframework.sbm.project.parser.DependencyHelper;
@@ -190,7 +188,7 @@ private static Path createProjectRoot() {
Path sbm = tempDirectory.resolve("sbm");
// FileUtils.cleanDirectory(sbm.toFile());
Path randDir = sbm.resolve(RandomStringUtils.randomAlphanumeric(5));
- FileUtils.forceMkdir(randDir.toFile());
+ Files.createDirectories(randDir);
return randDir;
} catch (IOException e) {
throw new RuntimeException(e);
@@ -596,9 +594,12 @@ public ProjectContext build() {
executionContext);
*/
- // Writing to filesystem and parsing again changes th eresource order
+ // Writing to filesystem and parsing again changes the resource order
try {
- FileUtils.cleanDirectory(projectRoot.toFile());
+ Files.walk(projectRoot)
+ .sorted(Comparator.reverseOrder())
+ .map(Path::toFile)
+ .forEach(File::delete);
} catch (IOException e) {
throw new RuntimeException(e);
}
diff --git a/components/sbm-openrewrite/pom.xml b/components/sbm-openrewrite/pom.xml
index f99e326eb..f7107386b 100644
--- a/components/sbm-openrewrite/pom.xml
+++ b/components/sbm-openrewrite/pom.xml
@@ -37,6 +37,21 @@
sbm-support-rewrite
0.1.0-SNAPSHOT
+
+ org.openrewrite
+ rewrite-java-17
+ ${openrewrite.version}
+
+
+ org.rocksdb
+ rocksdbjni
+ 8.3.2
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.3.1
+
org.projectlombok
lombok
diff --git a/components/sbm-recipes-jee-to-boot/pom.xml b/components/sbm-recipes-jee-to-boot/pom.xml
index 2ce02fa4b..b892d94e9 100644
--- a/components/sbm-recipes-jee-to-boot/pom.xml
+++ b/components/sbm-recipes-jee-to-boot/pom.xml
@@ -44,6 +44,11 @@
sbm-support-jee
0.15.2-SNAPSHOT
+
+ commons-io
+ commons-io
+ 2.13.0
+
diff --git a/components/test-helper/pom.xml b/components/test-helper/pom.xml
index a3da7b87b..53089f1d9 100644
--- a/components/test-helper/pom.xml
+++ b/components/test-helper/pom.xml
@@ -40,12 +40,6 @@
spring-core
-
- org.apache.maven.resolver
- maven-resolver-spi
- 1.9.15
-
-
org.jboss.shrinkwrap.resolver
@@ -77,11 +71,17 @@
shrinkwrap-resolver-impl-maven-archive
${shrinkwrap.resolvers.version}
+
+
+
+
+
+
+
- org.jboss.shrinkwrap.resolver
- shrinkwrap-resolver-bom
- ${shrinkwrap.resolvers.version}
- pom
+ org.apache.maven.resolver
+ maven-resolver-spi
+ 1.9.15
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 72c1e5190..28f1cf545 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,26 +64,26 @@
-
- org.apache.maven.wagon
- wagon-http
- 3.5.3
-
-
- org.apache.maven.resolver
- maven-resolver-transport-http
- 1.9.14
-
-
- org.apache.maven.resolver
- maven-resolver-api
- 1.9.14
-
-
- org.apache.maven.resolver
- maven-resolver-impl
- 1.9.14
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
org.projectlombok
@@ -131,11 +131,12 @@
-
- org.apache.maven.shared
- maven-invoker
- ${maven-invoker.version}
-
+
+
+
+
+
+
org.openrewrite
rewrite-core
diff --git a/sbm-support-rewrite/pom.xml b/sbm-support-rewrite/pom.xml
index c34d8072b..47d1535fb 100644
--- a/sbm-support-rewrite/pom.xml
+++ b/sbm-support-rewrite/pom.xml
@@ -142,60 +142,71 @@
${rewrite.version}
- org.openrewrite.maven
- rewrite-maven-plugin
- ${rewrite-maven-plugin.version}
+ org.openrewrite
+ rewrite-properties
+ ${rewrite.version}
org.projectlombok
lombok
provided
+
+ org.apache.maven
+ maven-model
+ 3.9.1
+
+
+
+ org.openrewrite.maven
+ rewrite-maven-plugin
+ ${rewrite-maven-plugin.version}
+ test
+
org.apache.maven.wagon
wagon-http
${maven-wagon-http.version}
+ test
org.apache.maven.resolver
maven-resolver-transport-wagon
${maven-resolver.version}
+ test
org.apache.maven.resolver
maven-resolver-connector-basic
${maven-resolver.version}
+ test
org.apache.maven.resolver
maven-resolver-impl
${maven-resolver.version}
+ test
org.apache.maven
maven-resolver-provider
${maven.version}
+ test
org.apache.maven
maven-compat
${maven.version}
+ test
-
- org.apache.maven
- maven-embedder
- ${maven.version}
-
-
- org.sonatype.plexus
- plexus-cipher
-
-
-
+
+
+
org.codehaus.plexus
plexus-cipher
${plexus-cypher.version}
+ test
org.apache.maven.shared
@@ -207,6 +218,7 @@
javax.xml.bind
jaxb-api
${jaxb-api.version}
+ test
org.springframework.boot
@@ -219,6 +231,31 @@
${junit-pioneer.version}
test
+
+
+
+
+ org.codehaus.plexus
+ plexus-sec-dispatcher
+ 2.0
+
+
+
+ org.apache.maven
+ maven-embedder
+ ${maven.version}
+
+
+ org.sonatype.plexus
+ plexus-cipher
+
+
+
+
+ commons-cli
+ commons-cli
+ 1.4
+
@@ -377,37 +414,6 @@ limitations under the License.
-
- org.codehaus.mojo
- flatten-maven-plugin
- 1.4.1
-
-
- flatten
- process-resources
-
- flatten
-
-
- true
- oss
-
- remove
- remove
- remove
- remove
-
-
-
-
- flatten-clean
- clean
-
- clean
-
-
-
-
org.apache.maven.plugins
maven-release-plugin
@@ -432,37 +438,6 @@ limitations under the License.
-
- org.codehaus.mojo
- flatten-maven-plugin
- 1.4.1
-
-
- flatten
- process-resources
-
- flatten
-
-
- true
- oss
-
- remove
- remove
- remove
- remove
-
-
-
-
- flatten-clean
- clean
-
- clean
-
-
-
-
org.apache.maven.plugins
maven-release-plugin
@@ -474,37 +449,6 @@ limitations under the License.
true
-
- org.codehaus.mojo
- flatten-maven-plugin
- 1.4.1
-
-
- flatten
- process-resources
-
- flatten
-
-
- true
- oss
-
- remove
- remove
- remove
- remove
-
-
-
-
- flatten-clean
- clean
-
- clean
-
-
-
-
org.apache.maven.plugins
maven-release-plugin
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/BuildFileParser.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/BuildFileParser.java
index 0239cd850..cd11195b4 100644
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/BuildFileParser.java
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/BuildFileParser.java
@@ -17,20 +17,14 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.maven.execution.MavenSession;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Parser;
import org.openrewrite.SourceFile;
import org.openrewrite.marker.Marker;
-import org.openrewrite.maven.MavenExecutionContextView;
-import org.openrewrite.maven.MavenMojoProjectParser;
import org.openrewrite.maven.MavenParser;
-import org.openrewrite.maven.cache.InMemoryMavenPomCache;
-import org.openrewrite.maven.cache.MavenPomCache;
import org.openrewrite.xml.tree.Xml;
import org.springframework.core.io.Resource;
import org.springframework.sbm.utils.ResourceUtil;
-import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.nio.file.Path;
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/HelperWithoutAGoodName.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/HelperWithoutAGoodName.java
new file mode 100644
index 000000000..d6503c22a
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/HelperWithoutAGoodName.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Parser;
+import org.openrewrite.SourceFile;
+import org.openrewrite.Tree;
+import org.openrewrite.internal.lang.Nullable;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.java.internal.JavaTypeCache;
+import org.openrewrite.java.marker.JavaSourceSet;
+import org.openrewrite.marker.Generated;
+import org.openrewrite.marker.Marker;
+import org.openrewrite.marker.Markers;
+import org.openrewrite.xml.tree.Xml;
+import org.springframework.core.io.Resource;
+import org.springframework.sbm.utils.ResourceUtil;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.function.UnaryOperator;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author Fabian Krüger
+ */
+@Slf4j
+public class HelperWithoutAGoodName {
+ /**
+ * {@link MavenMojoProjectParser#addProvenance(Path, List, Collection)}
+ */
+ public UnaryOperator addProvenance(Path baseDir, List provenance, @Nullable Collection generatedSources) {
+// MavenMojoProjectParser mavenMojoProjectParser = createMavenMojoProjectParser(baseDir);
+// Method method = ReflectionUtils.findMethod(MavenMojoProjectParser.class, "addProvenance", Path.class, List.class, Collection.class);
+// ReflectionUtils.makeAccessible(method);
+// if(method == null) {
+// throw new IllegalStateException("Could not find method '%s' on %s while trying to call it.".formatted("addProvenance", MavenMojoProjectParser.class.getName()));
+// }
+// Object result = ReflectionUtils.invokeMethod(method, mavenMojoProjectParser, baseDir, provenance, generatedSources);
+// return (UnaryOperator) result;
+ return (s) -> {
+ Markers markers = s.getMarkers();
+
+ Marker marker;
+ for (Iterator var5 = provenance.iterator(); var5.hasNext(); markers = markers.addIfAbsent(marker)) {
+ marker = (Marker) var5.next();
+ }
+
+ if (generatedSources != null && generatedSources.contains(baseDir.resolve(s.getSourcePath()))) {
+ markers = markers.addIfAbsent(new Generated(Tree.randomId()));
+ }
+
+ return (T) s.withMarkers(markers);
+ };
+ }
+
+ /**
+ * process sources in src/main/java of current module.
+ */
+ public List processMainSources(
+ Path baseDir,
+ List resources,
+ Xml.Document moduleBuildFile,
+ JavaParser.Builder extends JavaParser, ?> javaParserBuilder,
+ RewriteResourceParser rp,
+ List provenanceMarkers,
+ Set alreadyParsed,
+ ExecutionContext executionContext,
+ SbmMavenProject currentProject
+ ) {
+ log.info("Processing main sources in module '%s'".formatted(currentProject.getProjectId()));
+ // FIXME: 945
+ // Some annotation processors output generated sources to the /target directory. These are added for parsing but
+ // should be filtered out of the final SourceFile list.
+
+ List mainJavaSources = new ArrayList<>();
+ List javaSourcesInTarget = currentProject.getJavaSourcesInTarget(); // listJavaSources(resources, currentProject.getBasedir().resolve(currentProject.getBuildDirectory()));
+ List javaSourcesInMain = currentProject.getMainJavaSources(); // listJavaSources(resources, currentProject.getBasedir().resolve(currentProject.getSourceDirectory()));
+ mainJavaSources.addAll(javaSourcesInTarget);
+ mainJavaSources.addAll(javaSourcesInMain);
+
+ log.info("[%s] Parsing source files".formatted(currentProject));
+
+ // FIXME 945 classpath
+ // - Resolve dependencies to non-reactor projects from Maven repository
+ // - Resolve dependencies to reactor projects by providing the sources
+ // javaParserBuilder.classpath(byte[])
+
+ // we're processing a module here. The classpath of the module consists of all declared dependencies and their transitive dependencies too.
+ // For dependencies to projects that belong to the current rector...
+ // They'd either need to be built with Maven before to guarantee that the jars are installed to local Maven repo.
+ // Or, the classpath must be created from the sources of the project.
+
+
+ List dependencies = currentProject.getCompileClasspathElements();
+
+ javaParserBuilder.classpath(dependencies);
+
+ JavaTypeCache typeCache = new JavaTypeCache();
+ javaParserBuilder.typeCache(typeCache);
+
+ Iterable inputs = mainJavaSources.stream()
+ .map(r -> new Parser.Input(ResourceUtil.getPath(r), () -> ResourceUtil.getInputStream(r)))
+ .toList();
+
+ Stream extends SourceFile> cus = Stream.of(javaParserBuilder)
+ .map(JavaParser.Builder::build)
+ .flatMap(parser -> parser.parseInputs(inputs, baseDir, executionContext))
+ .peek(s -> alreadyParsed.add(baseDir.resolve(s.getSourcePath())));
+
+ List mainProjectProvenance = new ArrayList<>(provenanceMarkers);
+ mainProjectProvenance.add(sourceSet("main", dependencies, typeCache));
+
+ // FIXME: 945 Why target and not all main?
+ List parsedJavaPaths = mainJavaSources.stream().map(ResourceUtil::getPath).toList();
+ Stream parsedJava = cus.map(addProvenance(baseDir, mainProjectProvenance, parsedJavaPaths));
+ log.debug("[%s] Scanned %d java source files in main scope.".formatted(currentProject, mainJavaSources.size()));
+
+ //Filter out any generated source files from the returned list, as we do not want to apply the recipe to the
+ //generated files.
+ Path buildDirectory = Paths.get(currentProject.getBuildDirectory());
+ List sourceFiles = parsedJava
+ .filter(s -> !s.getSourcePath().startsWith(buildDirectory))
+ .collect(Collectors.toCollection(ArrayList::new));
+
+ int sourcesParsedBefore = alreadyParsed.size();
+ alreadyParsed.addAll(parsedJavaPaths);
+ List parsedResourceFiles = rp.parse(currentProject.getModulePath().resolve("src/main/resources"), resources, alreadyParsed)
+ .map(addProvenance(baseDir, mainProjectProvenance, null))
+ .toList();
+
+ log.debug("[%s] Scanned %d resource files in main scope.".formatted(currentProject, (alreadyParsed.size() - sourcesParsedBefore)));
+ // Any resources parsed from "main/resources" should also have the main source set added to them.
+ sourceFiles.addAll(parsedResourceFiles);
+ return sourceFiles;
+ }
+
+ @NotNull
+ private static JavaSourceSet sourceSet(String name, List dependencies, JavaTypeCache typeCache) {
+ return JavaSourceSet.build(name, dependencies, typeCache, false);
+ }
+
+
+ /**
+ * Calls {@link MavenMojoProjectParser#processTestSources(SbmMavenProject, JavaParser.Builder, ResourceParser, List, Set, ExecutionContext)}
+ */
+ public List processTestSources(
+ Path baseDir,
+ Xml.Document moduleBuildFile,
+ JavaParser.Builder extends JavaParser, ?> javaParserBuilder,
+ RewriteResourceParser rp,
+ List provenanceMarkers,
+ Set alreadyParsed,
+ ExecutionContext executionContext,
+ SbmMavenProject currentProject,
+ List resources
+ ) {
+ log.info("Processing test sources in module '%s'".formatted(currentProject.getProjectId()));
+
+ List testDependencies = currentProject.getTestClasspathElements();
+
+ javaParserBuilder.classpath(testDependencies);
+ JavaTypeCache typeCache = new JavaTypeCache();
+ javaParserBuilder.typeCache(typeCache);
+
+ List testJavaSources = listJavaSources(resources, currentProject.getBasedir().resolve(currentProject.getTestSourceDirectory()));
+ alreadyParsed.addAll(testJavaSources.stream().map(ResourceUtil::getPath).toList());
+
+ Iterable inputs = testJavaSources.stream()
+ .map(r -> new Parser.Input(ResourceUtil.getPath(r), () -> ResourceUtil.getInputStream(r)))
+ .toList();
+
+ Stream extends SourceFile> cus = Stream.of(javaParserBuilder)
+ .map(JavaParser.Builder::build)
+ .flatMap(parser -> parser.parseInputs(inputs, baseDir, executionContext));
+
+ List markers = new ArrayList<>(provenanceMarkers);
+ markers.add(sourceSet("test", testDependencies, typeCache));
+
+ Stream parsedJava = cus.map(addProvenance(baseDir, markers, null));
+
+ log.debug("[%s] Scanned %d java source files in test scope.".formatted(currentProject, testJavaSources.size()));
+ Stream sourceFiles = parsedJava;
+
+ // Any resources parsed from "test/resources" should also have the test source set added to them.
+ int sourcesParsedBefore = alreadyParsed.size();
+ Stream parsedResourceFiles = rp.parse(currentProject.getBasedir().resolve("src/test/resources"), resources, alreadyParsed)
+ .map(addProvenance(baseDir, markers, null));
+ log.debug("[%s] Scanned %d resource files in test scope.".formatted(currentProject, (alreadyParsed.size() - sourcesParsedBefore)));
+ sourceFiles = Stream.concat(sourceFiles, parsedResourceFiles);
+ List result = sourceFiles.toList();
+ return result;
+ }
+
+
+ // FIXME: 945 take Java sources from resources
+ private static List listJavaSources(List resources, Path sourceDirectory) {
+ return resources.stream()
+ .filter(whenIn(sourceDirectory))
+ .filter(whenFileNameEndsWithJava())
+ .toList();
+ }
+
+ @NotNull
+ private static Predicate whenFileNameEndsWithJava() {
+ return p -> ResourceUtil.getPath(p).getFileName().toString().endsWith(".java");
+ }
+
+ @NotNull
+ private static Predicate whenIn(Path sourceDirectory) {
+ return r -> ResourceUtil.getPath(r).toString().startsWith(sourceDirectory.toString());
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenConfigFileParser.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenConfigFileParser.java
index 2d2137b73..74f54743c 100644
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenConfigFileParser.java
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenConfigFileParser.java
@@ -18,7 +18,6 @@
import org.apache.commons.cli.*;
import org.apache.maven.cli.CleanArgument;
import org.jetbrains.annotations.NotNull;
-import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenMojoProjectParserPrivateMethods.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenMojoProjectParserPrivateMethods.java
deleted file mode 100644
index 4fabc7610..000000000
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenMojoProjectParserPrivateMethods.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2021 - 2023 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.parsers;
-
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.rtinfo.internal.DefaultRuntimeInformation;
-import org.apache.maven.settings.crypto.DefaultSettingsDecrypter;
-import org.jetbrains.annotations.NotNull;
-import org.openrewrite.ExecutionContext;
-import org.openrewrite.SourceFile;
-import org.openrewrite.internal.lang.Nullable;
-import org.openrewrite.java.JavaParser;
-import org.openrewrite.marker.Marker;
-import org.openrewrite.maven.MavenMojoProjectParser;
-import org.openrewrite.maven.ResourceParser;
-import org.openrewrite.maven.tree.ResolvedDependency;
-import org.openrewrite.maven.utilities.MavenArtifactDownloader;
-import org.openrewrite.xml.tree.Xml;
-import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
-import org.sonatype.plexus.components.cipher.PlexusCipherException;
-import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
-import org.springframework.util.ReflectionUtils;
-
-import java.lang.reflect.Method;
-import java.nio.file.Path;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.UnaryOperator;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * @author Fabian Krüger
- */
-@Slf4j
-@RequiredArgsConstructor
-class MavenMojoProjectParserPrivateMethods {
-
- private final MavenMojoProjectParserFactory mavenMojoProjectParserFactory;
- private final MavenArtifactDownloader artifactDownloader;
-
- /**
- * Calls {@link MavenMojoProjectParser#processMainSources(MavenProject, JavaParser.Builder, ResourceParser, List, Set, ExecutionContext)}
- */
- public List processMainSources(Path baseDir, Xml.Document moduleBuildFile, JavaParser.Builder extends JavaParser, ?> javaParserBuilder, ResourceParser rp, List provenanceMarkers, Set alreadyParsed, ExecutionContext executionContext, MavenProject mavenProject) {
- return invokeProcessMethod(baseDir, mavenProject, moduleBuildFile, javaParserBuilder, rp, provenanceMarkers, alreadyParsed, executionContext, "processMainSources");
- }
-
- /**
- * Calls {@link MavenMojoProjectParser#processTestSources(MavenProject, JavaParser.Builder, ResourceParser, List, Set, ExecutionContext)}
- */
- public List processTestSources(Path baseDir, Xml.Document moduleBuildFile, JavaParser.Builder extends JavaParser,?> javaParserBuilder, ResourceParser rp, List provenanceMarkers, Set alreadyParsed, ExecutionContext executionContext, MavenProject mavenProject) {
- return invokeProcessMethod(baseDir, mavenProject, moduleBuildFile, javaParserBuilder, rp, provenanceMarkers, alreadyParsed, executionContext, "processTestSources");
- }
-
- /**
- * See {@link MavenMojoProjectParser#processMainSources(MavenProject, JavaParser.Builder, ResourceParser, List, Set, ExecutionContext)}
- */
- @NotNull
- private List invokeProcessMethod(
- Path baseDir,
- MavenProject mavenProject, Xml.Document moduleBuildFile,
- JavaParser.Builder extends JavaParser, ?> javaParserBuilder,
- ResourceParser rp,
- List provenanceMarkers,
- Set alreadyParsed,
- ExecutionContext executionContext,
- String methodName
- ) {
- MavenMojoProjectParser mavenMojoProjectParser = createMavenMojoProjectParser(baseDir);
- Method method = ReflectionUtils.findMethod(
- MavenMojoProjectParser.class,
- methodName,
- MavenProject.class,
- JavaParser.Builder.class,
- ResourceParser.class,
- List.class,
- Set.class,
- ExecutionContext.class);
- ReflectionUtils.makeAccessible(method);
- if (method == null) {
- throw new IllegalStateException("Could not find method '%s' on %s while trying to call it.".formatted(methodName, MavenMojoProjectParser.class.getName()));
- }
- log.debug("Starting reflective call to %s.%s()".formatted(mavenMojoProjectParser.getClass().getName(), method.getName()));
- Object result = ReflectionUtils.invokeMethod(method, mavenMojoProjectParser,
- mavenProject,
- javaParserBuilder,
- rp,
- provenanceMarkers,
- alreadyParsed,
- executionContext
- );
- if (result instanceof Stream) {
- List sourceFiles = ((Stream) result).toList();
- return sourceFiles;
- } else {
- throw new RuntimeException("Could not cast result returned from MavenMojoParser#methodName to Stream.");
- }
- }
-
-
- /**
- * {@link MavenMojoProjectParser#addProvenance(Path, List, Collection)}
- */
- public UnaryOperator addProvenance(Path baseDir, List provenance, @Nullable Collection generatedSources) {
- MavenMojoProjectParser mavenMojoProjectParser = createMavenMojoProjectParser(baseDir);
- Method method = ReflectionUtils.findMethod(MavenMojoProjectParser.class, "addProvenance", Path.class, List.class, Collection.class);
- ReflectionUtils.makeAccessible(method);
- if(method == null) {
- throw new IllegalStateException("Could not find method '%s' on %s while trying to call it.".formatted("addProvenance", MavenMojoProjectParser.class.getName()));
- }
- Object result = ReflectionUtils.invokeMethod(method, mavenMojoProjectParser, baseDir, provenance, generatedSources);
- return (UnaryOperator) result;
- }
-
- private MavenMojoProjectParser createMavenMojoProjectParser(Path baseDir) {
- try {
- return mavenMojoProjectParserFactory.create(baseDir, new DefaultRuntimeInformation(), new DefaultSettingsDecrypter(new DefaultSecDispatcher(new DefaultPlexusCipher())));
- } catch (PlexusCipherException e) {
- throw new RuntimeException(e);
- }
- }
-
- private List downloadArtifacts(List dependencies) {
-
-// eventPublisher.publishEvent(new StartDownloadingDependenciesEvent(dependencies.size()));
-
-
- List paths = dependencies
- .stream()
- .filter(d -> d.getRepository() != null)
-// .peek(d -> eventPublisher.publishEvent(new StartDownloadingDependencyEvent(d.getRequested())))
-// .parallel()
- .map(artifactDownloader::downloadArtifact)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
-
-// eventPublisher.publishEvent(new FinishedDownloadingDependencies());
-
- return paths;
- }
-}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenProjectAnalyzer.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenProjectAnalyzer.java
new file mode 100644
index 000000000..bf8da395a
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenProjectAnalyzer.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+import org.apache.maven.model.*;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.openrewrite.maven.utilities.MavenArtifactDownloader;
+import org.springframework.core.io.Resource;
+import org.springframework.sbm.utils.ResourceUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * Implements the ordering of Maven (reactor) build projects.
+ * See Reactor Sorting
+ *
+ * @author Fabian Krüger
+ */
+public class MavenProjectAnalyzer {
+
+ private static final String POM_XML = "pom.xml";
+ private static final MavenXpp3Reader XPP_3_READER = new MavenXpp3Reader();
+ private final MavenArtifactDownloader rewriteMavenArtifactDownloader;
+
+ public MavenProjectAnalyzer(MavenArtifactDownloader rewriteMavenArtifactDownloader) {
+ this.rewriteMavenArtifactDownloader = rewriteMavenArtifactDownloader;
+ }
+
+ public List getSortedProjects(Path baseDir, List resources) {
+
+ List allPomFiles = resources.stream().filter(r -> ResourceUtil.getPath(r).getFileName().toString().equals(POM_XML)).toList();
+
+ if (allPomFiles.isEmpty()) {
+ throw new IllegalArgumentException("The provided resources did not contain any 'pom.xml' file.");
+ }
+
+ Resource rootPom = allPomFiles.stream().filter(r -> ResourceUtil.getPath(r).toString().equals(baseDir.resolve(POM_XML).normalize().toString())).findFirst().orElseThrow(() -> new IllegalArgumentException("The provided resources do not contain a root 'pom.xml' file."));
+ Model rootPomModel = new Model(rootPom);
+
+ if (isSingleModuleProject(rootPomModel)) {
+ return List.of(new SbmMavenProject(baseDir, rootPom, rootPomModel, rewriteMavenArtifactDownloader, resources));
+ }
+ List reactorModels = new ArrayList<>();
+ recursivelyFindReactorModules(baseDir, null, reactorModels, allPomFiles, rootPomModel);
+ List sortedModels = sortModels(reactorModels);
+ return map(baseDir, resources, sortedModels);
+ }
+
+ private List map(Path baseDir, List resources, List sortedModels) {
+ List sbmMavenProjects = new ArrayList<>();
+ sortedModels
+ .stream()
+ .filter(Objects::nonNull)
+ .forEach(m -> {
+ String projectDir = baseDir.resolve(m.getProjectDirectory().toString()).normalize().toString();
+ List filteredResources = resources.stream().filter(r -> ResourceUtil.getPath(r).toString().startsWith(projectDir)).toList();
+ sbmMavenProjects.add(new SbmMavenProject(baseDir, m.getResource(), m, rewriteMavenArtifactDownloader, filteredResources));
+ });
+ // set all non parent poms as collected projects for root parent pom
+ List collected = new ArrayList<>(sbmMavenProjects);
+ collected.remove(0);
+ sbmMavenProjects.get(0).setCollectedProjects(collected);
+ return sbmMavenProjects;
+ }
+
+ private List recursivelyFindReactorModules(Path baseDir, String path, List reactorModels, List allPomFiles, Model pomModel) {
+ // TODO: verify given module is root pom
+ if(pomModel != null) {
+ reactorModels.add(pomModel);
+ } else {
+ throw new IllegalStateException("PomModel was null.");
+ }
+
+ List moduleNames = pomModel.getModules();
+
+ moduleNames.stream()
+ .forEach(moduleName -> {
+
+ String modulePathSegment = path == null ? moduleName : path + "/" + moduleName;
+
+ allPomFiles.stream()
+ .filter(resource -> {
+ String modulePath = baseDir.resolve(modulePathSegment).resolve(POM_XML).toAbsolutePath().normalize().toString();
+ String resourcePath = ResourceUtil.getPath(resource).toAbsolutePath().normalize().toString();
+ return resourcePath.equals(modulePath);
+ })
+ .map(Model::new)
+ .forEach(m -> recursivelyFindReactorModules(baseDir, modulePathSegment, reactorModels, allPomFiles, m).stream());
+ });
+ return reactorModels;
+ }
+
+ public List sortModels(List reactorModels) {
+ List sortedModels = new ArrayList<>();
+ Map gaToModelMap = reactorModels.stream()
+ .collect(Collectors.toMap(
+ m ->{
+ return (m.getGroupId() == null ? (m.getParent() == null ? null : m.getParent().getGroupId()) : m.getGroupId()) + ":" + m.getArtifactId();
+ } ,
+ m -> m
+ ));
+
+ Map> dependsOn = new HashMap<>();
+
+ for (Model m : reactorModels) {
+ addToDependants(m, dependsOn, null);
+ if (hasParent(m)) {
+ String parentGa = m.getParent().getGroupId() + ":" + m.getParent().getArtifactId();
+ Model parentModel = gaToModelMap.get(parentGa);
+ addToDependants(m, dependsOn, parentModel);
+ }
+ for (Dependency d : m.getDependencies()) {
+ String dependencyGa = getGav(d);
+ if (gaToModelMap.containsKey(dependencyGa)) {
+ Model dependencyModel = gaToModelMap.get(dependencyGa);
+ addToDependants(m, dependsOn, dependencyModel);
+ }
+ }
+ if (m.getBuild() != null && m.getBuild().getPluginsAsMap() != null && !m.getBuild().getPluginsAsMap().isEmpty()) {
+ for (String pluginName : m.getBuild().getPluginsAsMap().keySet()) {
+ // TODO: find plugin dependencies
+ }
+ }
+ }
+
+ ArrayList>> entries = new ArrayList<>(dependsOn.entrySet());
+
+ // sort entries by number of values
+ entries.stream()
+ .sorted((e1, e2) -> {
+ int compare = Integer.compare(e1.getValue().size(), e2.getValue().size());
+ if(compare != 0) {
+ return compare;
+ } else {
+ // with same number of dependencies order by dependant
+ if(e1.getValue().contains(e2.getKey())) {
+ return 1;
+ } else if(e2.getValue().contains(e1.getKey())) {
+ return -1;
+ } else {
+ // default is order as given by reactorModels
+ return Integer.compare(reactorModels.indexOf(e1.getKey()), reactorModels.indexOf(e2.getKey()));
+ }
+ }
+ })
+ .forEach(e -> sortedModels.add(e.getKey()));
+ return sortedModels;
+ }
+
+ private void addToDependants(Model model, Map> dependsOn, Model dependantModel) {
+ if (!dependsOn.containsKey(model)) {
+ dependsOn.put(model, new ArrayList<>());
+ }
+ if (dependantModel != null) {
+ dependsOn.get(model).add(dependantModel);
+ }
+ }
+
+ private boolean hasParent(Model m) {
+ return m.getParent() != null;
+ }
+
+ private String getGav(Dependency d) {
+ return d.getGroupId() + ":" + d.getArtifactId();
+ }
+
+ private static boolean isSingleModuleProject(Model rootPomModel) {
+ return !rootPomModel.getPackaging().equals("pom");
+ }
+
+ public ParserContext createParserContext(Path baseDir, List resources) {
+ List sortedProjectsList = getSortedProjects(baseDir, resources);
+ ParserContext parserContext = new ParserContext(resources, sortedProjectsList);
+ return parserContext;
+ }
+
+ static class Model extends org.apache.maven.model.Model {
+ private final Resource resource;
+ private final org.apache.maven.model.Model delegate;
+
+ public Model(Resource resource) {
+ this.resource = resource;
+ try {
+ this.delegate = XPP_3_READER.read(ResourceUtil.getInputStream(resource));
+ this.delegate.setPomFile(resource.getFile());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return (delegate.getGroupId() == null ? delegate.getParent().getGroupId() : delegate.getGroupId()) + ":" + delegate.getArtifactId();
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ @Override
+ public String getArtifactId() {
+ return delegate.getArtifactId();
+ }
+
+ @Override
+ public Build getBuild() {
+ return delegate.getBuild();
+ }
+
+ @Override
+ public String getChildProjectUrlInheritAppendPath() {
+ return delegate.getChildProjectUrlInheritAppendPath();
+ }
+
+ @Override
+ public CiManagement getCiManagement() {
+ return delegate.getCiManagement();
+ }
+
+ @Override
+ public List getContributors() {
+ return delegate.getContributors();
+ }
+
+ @Override
+ public String getDescription() {
+ return delegate.getDescription();
+ }
+
+ @Override
+ public List getDevelopers() {
+ return delegate.getDevelopers();
+ }
+
+ @Override
+ public String getGroupId() {
+ return delegate.getGroupId();
+ }
+
+ @Override
+ public String getInceptionYear() {
+ return delegate.getInceptionYear();
+ }
+
+ @Override
+ public IssueManagement getIssueManagement() {
+ return delegate.getIssueManagement();
+ }
+
+ @Override
+ public List getLicenses() {
+ return delegate.getLicenses();
+ }
+
+ @Override
+ public List getMailingLists() {
+ return delegate.getMailingLists();
+ }
+
+ @Override
+ public String getModelEncoding() {
+ return delegate.getModelEncoding();
+ }
+
+ @Override
+ public String getModelVersion() {
+ return delegate.getModelVersion();
+ }
+
+ @Override
+ public String getName() {
+ return delegate.getName();
+ }
+
+ @Override
+ public Organization getOrganization() {
+ return delegate.getOrganization();
+ }
+
+ @Override
+ public String getPackaging() {
+ return delegate.getPackaging();
+ }
+
+ @Override
+ public Parent getParent() {
+ return delegate.getParent();
+ }
+
+ @Override
+ public Prerequisites getPrerequisites() {
+ return delegate.getPrerequisites();
+ }
+
+ @Override
+ public List getProfiles() {
+ return delegate.getProfiles();
+ }
+
+ @Override
+ public Scm getScm() {
+ return delegate.getScm();
+ }
+
+ @Override
+ public String getUrl() {
+ return delegate.getUrl();
+ }
+
+ @Override
+ public String getVersion() {
+ return delegate.getVersion();
+ }
+
+ @Override
+ public File getPomFile() {
+ return delegate.getPomFile();
+ }
+
+ @Override
+ public File getProjectDirectory() {
+ return delegate.getPomFile().toPath().getParent().toFile();
+ }
+
+ @Override
+ public String getId() {
+ return delegate.getId();
+ }
+
+ @Override
+ public List getDependencies() {
+ return delegate.getDependencies();
+ }
+
+ @Override
+ public DependencyManagement getDependencyManagement() {
+ return delegate.getDependencyManagement();
+ }
+
+ @Override
+ public DistributionManagement getDistributionManagement() {
+ return delegate.getDistributionManagement();
+ }
+
+ @Override
+ public InputLocation getLocation(Object key) {
+ return delegate.getLocation(key);
+ }
+
+ @Override
+ public List getModules() {
+ return delegate.getModules();
+ }
+
+ @Override
+ public List getPluginRepositories() {
+ return delegate.getPluginRepositories();
+ }
+
+ @Override
+ public Properties getProperties() {
+ return delegate.getProperties();
+ }
+
+ @Override
+ public Reporting getReporting() {
+ return delegate.getReporting();
+ }
+
+ @Override
+ public Object getReports() {
+ return delegate.getReports();
+ }
+
+ @Override
+ public List getRepositories() {
+ return delegate.getRepositories();
+ }
+
+
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenProvenanceMarkerFactory.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenProvenanceMarkerFactory.java
new file mode 100644
index 000000000..13b20c9d0
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenProvenanceMarkerFactory.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.openrewrite.Tree;
+import org.openrewrite.internal.StringUtils;
+import org.openrewrite.internal.lang.Nullable;
+import org.openrewrite.java.marker.JavaProject;
+import org.openrewrite.java.marker.JavaVersion;
+import org.openrewrite.marker.*;
+import org.openrewrite.marker.ci.BuildEnvironment;
+
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+
+/**
+ * @author Fabian Krüger
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class MavenProvenanceMarkerFactory {
+
+ public List generateProvenance(Path baseDir, SbmMavenProject mavenProject) {
+ MavenRuntimeInformation runtime = mavenProject.getMavenRuntimeInformation();
+ BuildTool buildTool = new BuildTool(Tree.randomId(), BuildTool.Type.Maven, runtime.getMavenVersion());
+
+ String javaRuntimeVersion = System.getProperty("java.specification.version");
+ String javaVendor = System.getProperty("java.vm.vendor");
+ String sourceCompatibility = null;
+ String targetCompatibility = null;
+ Plugin compilerPlugin = mavenProject.getPlugin("org.apache.maven.plugins:maven-compiler-plugin");
+ if (compilerPlugin != null && compilerPlugin.getConfiguration() instanceof Xpp3Dom) {
+ Xpp3Dom dom = (Xpp3Dom)compilerPlugin.getConfiguration();
+ Xpp3Dom release = dom.getChild("release");
+ if (release != null && StringUtils.isNotEmpty(release.getValue()) && !release.getValue().contains("${")) {
+ sourceCompatibility = release.getValue();
+ targetCompatibility = release.getValue();
+ } else {
+ Xpp3Dom source = dom.getChild("source");
+ if (source != null && StringUtils.isNotEmpty(source.getValue()) && !source.getValue().contains("${")) {
+ sourceCompatibility = source.getValue();
+ }
+
+ Xpp3Dom target = dom.getChild("target");
+ if (target != null && StringUtils.isNotEmpty(target.getValue()) && !target.getValue().contains("${")) {
+ targetCompatibility = target.getValue();
+ }
+ }
+ }
+
+ if (sourceCompatibility == null || targetCompatibility == null) {
+ String propertiesReleaseCompatibility = (String)mavenProject.getProperties().get("maven.compiler.release");
+ if (propertiesReleaseCompatibility != null) {
+ sourceCompatibility = propertiesReleaseCompatibility;
+ targetCompatibility = propertiesReleaseCompatibility;
+ } else {
+ String propertiesSourceCompatibility = (String)mavenProject.getProperties().get("maven.compiler.source");
+ if (sourceCompatibility == null && propertiesSourceCompatibility != null) {
+ sourceCompatibility = propertiesSourceCompatibility;
+ }
+
+ String propertiesTargetCompatibility = (String)mavenProject.getProperties().get("maven.compiler.target");
+ if (targetCompatibility == null && propertiesTargetCompatibility != null) {
+ targetCompatibility = propertiesTargetCompatibility;
+ }
+ }
+ }
+
+ if (sourceCompatibility == null) {
+ sourceCompatibility = javaRuntimeVersion;
+ }
+
+ if (targetCompatibility == null) {
+ targetCompatibility = sourceCompatibility;
+ }
+
+ BuildEnvironment buildEnvironment = BuildEnvironment.build(System::getenv);
+ return (List) Stream.of(buildEnvironment, this.gitProvenance(baseDir, buildEnvironment), OperatingSystemProvenance.current(), buildTool, new JavaVersion(Tree.randomId(), javaRuntimeVersion, javaVendor, sourceCompatibility, targetCompatibility), new JavaProject(Tree.randomId(), mavenProject.getName(), new JavaProject.Publication(mavenProject.getGroupId(), mavenProject.getArtifactId(), mavenProject.getVersion()))).filter(Objects::nonNull).collect(Collectors.toList());
+ }
+
+ private @Nullable GitProvenance gitProvenance(Path baseDir, @Nullable BuildEnvironment buildEnvironment) {
+ try {
+ return GitProvenance.fromProjectDirectory(baseDir, buildEnvironment);
+ } catch (Exception var4) {
+ log.debug("Unable to determine git provenance", var4);
+ return null;
+ }
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenRuntimeInformation.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenRuntimeInformation.java
new file mode 100644
index 000000000..e53792103
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenRuntimeInformation.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+/**
+ * @author Fabian Krüger
+ */
+public class MavenRuntimeInformation {
+ public String getMavenVersion() {
+ // FIXME: 945 implement this
+ return "3.9.1";
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ParserContext.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ParserContext.java
new file mode 100644
index 000000000..6fa977e03
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ParserContext.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.springframework.core.io.Resource;
+import org.springframework.sbm.utils.ResourceUtil;
+
+import java.util.List;
+
+/**
+ * @author Fabian Krüger
+ */
+@RequiredArgsConstructor
+public class ParserContext {
+
+ @Getter
+ private final List resources;
+ @Getter
+ private final List sortedProjects;
+
+ public List getActiveProfiles() {
+ // FIXME: Add support for Maven profiles
+ return List.of("default");
+ }
+
+ public Resource getMatchingBuildFileResource(SbmMavenProject pom) {
+ return resources.stream()
+ .filter(r -> ResourceUtil.getPath(r).toString().equals(pom.getPomFilePath().toString()))
+ .findFirst()
+ .orElseThrow(() -> new IllegalStateException("Could not find a resource in the list of resources that matches the path of SbmMavenProject '%s'".formatted(pom.getPomFile().toString())));
+ }
+
+ public List getBuildFileResources() {
+ return sortedProjects.stream()
+ .map(p -> p.getPomFile())
+ .toList();
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ParserProperties.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ParserProperties.java
index fe16054c2..97461a3d9 100644
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ParserProperties.java
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ParserProperties.java
@@ -81,6 +81,6 @@ public class ParserProperties {
/**
* Comma-separated list of patterns used to create PathMatcher to exclude paths from being parsed.
*/
- private Set ignoredPathPatterns = new HashSet<>();
+ private Set ignoredPathPatterns = Set.of("**/target/**", "target/**");
}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProjectId.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProjectId.java
new file mode 100644
index 000000000..7ecce0a2b
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProjectId.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+import java.util.Objects;
+
+/**
+ * @author Fabian Krüger
+ */
+public record ProjectId(String groupId, String artifactId) {
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ProjectId projectId = (ProjectId) o;
+ return Objects.equals(groupId, projectId.groupId) && Objects.equals(artifactId, projectId.artifactId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(groupId, artifactId);
+ }
+
+ @Override
+ public String toString() {
+ return groupId + ":" + artifactId;
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProvenanceMarkerFactory.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProvenanceMarkerFactory.java
index 9820fac68..5fbaebaf6 100644
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProvenanceMarkerFactory.java
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProvenanceMarkerFactory.java
@@ -16,15 +16,9 @@
package org.springframework.sbm.parsers;
import lombok.RequiredArgsConstructor;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.rtinfo.RuntimeInformation;
-import org.apache.maven.rtinfo.internal.DefaultRuntimeInformation;
-import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.openrewrite.marker.Marker;
-import org.openrewrite.maven.MavenMojoProjectParser;
import org.springframework.core.io.Resource;
import org.springframework.sbm.utils.ResourceUtil;
-import org.springframework.stereotype.Component;
import java.nio.file.Path;
import java.util.*;
@@ -35,25 +29,22 @@
@RequiredArgsConstructor
class ProvenanceMarkerFactory {
- private final MavenMojoProjectParserFactory mavenMojoProjectParserFactory;
+ private final MavenProvenanceMarkerFactory markerFactory;
/**
* Reuses {@link MavenMojoProjectParser#generateProvenance(MavenProject)} to create {@link Marker}s for pom files in
- * provided {@code pomFileResources}.
+ * provided {@code parserContext}.
*
* @return the map of pom.xml {@link Resource}s and their {@link Marker}s.
*/
- public Map> generateProvenanceMarkers(Path baseDir, SortedProjects pomFileResources) {
+ public Map> generateProvenanceMarkers(Path baseDir, ParserContext parserContext) {
- RuntimeInformation runtimeInformation = new DefaultRuntimeInformation();
- SettingsDecrypter settingsDecrypter = null;
-
- MavenMojoProjectParser helper = mavenMojoProjectParserFactory.create(baseDir, runtimeInformation, settingsDecrypter);
Map> result = new HashMap<>();
- pomFileResources.getSortedProjects().forEach(mavenProject -> {
- List markers = helper.generateProvenance(mavenProject);
- Resource resource = pomFileResources.getMatchingBuildFileResource(mavenProject);
+ parserContext.getSortedProjects().forEach(mavenProject -> {
+
+ List markers = markerFactory.generateProvenance(baseDir, mavenProject);
+ Resource resource = parserContext.getMatchingBuildFileResource(mavenProject);
Path path = ResourceUtil.getPath(resource);
result.put(path, markers);
});
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteParserConfiguration.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteParserConfiguration.java
index b173406ed..82f8bf20f 100644
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteParserConfiguration.java
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteParserConfiguration.java
@@ -29,7 +29,6 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.sbm.boot.autoconfigure.ParserPropertiesPostProcessor;
-import org.springframework.sbm.boot.autoconfigure.ScannerConfiguration;
import org.springframework.sbm.parsers.events.RewriteParsingEventListenerAdapter;
import org.springframework.sbm.scopes.ProjectMetadata;
import org.springframework.sbm.scopes.ScanScope;
@@ -56,34 +55,19 @@ public class RewriteParserConfiguration {
@Autowired
private ParserProperties parserProperties;
- @Bean
- MavenPlexusContainer plexusContainer() {
- return new MavenPlexusContainer();
- }
-
- @Bean
- MavenConfigFileParser configFileParser() {
- return new MavenConfigFileParser();
- }
-
- @Bean
- MavenExecutionRequestFactory requestFactory(MavenConfigFileParser configFileParser) {
- return new MavenExecutionRequestFactory(configFileParser);
- }
+// @Bean
+// ProvenanceMarkerFactory provenanceMarkerFactory(MavenMojoProjectParserFactory projectParserFactory) {
+// return new ProvenanceMarkerFactory(projectParserFactory);
+// }
@Bean
- MavenExecutor mavenExecutor(MavenExecutionRequestFactory requestFactory, MavenPlexusContainer plexusContainer) {
- return new MavenExecutor(requestFactory, plexusContainer);
+ MavenProvenanceMarkerFactory mavenProvenanceMarkerFactory() {
+ return new MavenProvenanceMarkerFactory();
}
@Bean
- MavenMojoProjectParserFactory projectParserFactory() {
- return new MavenMojoProjectParserFactory(parserProperties);
- }
-
- @Bean
- ProvenanceMarkerFactory provenanceMarkerFactory(MavenMojoProjectParserFactory projectParserFactory) {
- return new ProvenanceMarkerFactory(projectParserFactory);
+ ProvenanceMarkerFactory provenanceMarkerFactory(MavenProvenanceMarkerFactory mavenPovenanceMarkerFactory) {
+ return new ProvenanceMarkerFactory(mavenPovenanceMarkerFactory);
}
@Bean
@@ -97,10 +81,6 @@ BuildFileParser buildFileParser() {
return new BuildFileParser();
}
- @Bean
- MavenModelReader modelReader() {
- return new MavenModelReader();
- }
@Bean
@ConditionalOnMissingBean(MavenArtifactCache.class)
@@ -121,13 +101,13 @@ RewriteMavenArtifactDownloader artifactDownloader(MavenArtifactCache mavenArtifa
}
@Bean
- MavenMojoProjectParserPrivateMethods mavenMojoProjectParserPrivateMethods(MavenMojoProjectParserFactory parserFactory, MavenArtifactDownloader artifactDownloader) {
- return new MavenMojoProjectParserPrivateMethods(parserFactory, artifactDownloader);
+ HelperWithoutAGoodName helperWithoutAGoodName() {
+ return new HelperWithoutAGoodName();
}
@Bean
- SourceFileParser sourceFileParser(MavenModelReader modelReader, MavenMojoProjectParserPrivateMethods mavenMojoProjectParserPrivateMethods, JavaParserBuilder javaParserBuilder) {
- return new SourceFileParser(parserProperties, mavenMojoProjectParserPrivateMethods, javaParserBuilder);
+ SourceFileParser sourceFileParser(JavaParserBuilder javaParserBuilder, HelperWithoutAGoodName helperWithoutAGoodName) {
+ return new SourceFileParser(parserProperties, helperWithoutAGoodName);
}
@Bean
@@ -141,21 +121,26 @@ ParsingEventListener parsingEventListener(ApplicationEventPublisher eventPublish
return new RewriteParsingEventListenerAdapter(eventPublisher);
}
+ // FIXME: 945
+// @Bean
+// RewriteMavenProjectParser rewriteMavenProjectParser(MavenPlexusContainer plexusContainer, ParsingEventListener parsingListener, MavenExecutor mavenExecutor, MavenMojoProjectParserFactory projectParserFactory, ScanScope scanScope, ConfigurableListableBeanFactory beanFactory, ExecutionContext executionContext) {
+// return new RewriteMavenProjectParser(
+// plexusContainer,
+// parsingListener,
+// mavenExecutor,
+// projectParserFactory,
+// scanScope,
+// beanFactory,
+// executionContext);
+// }
+
@Bean
- RewriteMavenProjectParser rewriteMavenProjectParser(MavenPlexusContainer plexusContainer, ParsingEventListener parsingListener, MavenExecutor mavenExecutor, MavenMojoProjectParserFactory projectParserFactory, ScanScope scanScope, ConfigurableListableBeanFactory beanFactory, ExecutionContext executionContext) {
- return new RewriteMavenProjectParser(
- plexusContainer,
- parsingListener,
- mavenExecutor,
- projectParserFactory,
- scanScope,
- beanFactory,
- executionContext);
+ MavenProjectAnalyzer mavenProjectAnalyzer(MavenArtifactDownloader artifactDownloader) {
+ return new MavenProjectAnalyzer(artifactDownloader);
}
@Bean
RewriteProjectParser rewriteProjectParser(
- MavenExecutor mavenExecutor,
ProvenanceMarkerFactory provenanceMarkerFactory,
BuildFileParser buildFileParser,
SourceFileParser sourceFileParser,
@@ -166,9 +151,9 @@ RewriteProjectParser rewriteProjectParser(
ScanScope scanScope,
ConfigurableListableBeanFactory beanFactory,
ProjectScanner projectScanner,
- ExecutionContext executionContext) {
+ ExecutionContext executionContext,
+ MavenProjectAnalyzer mavenProjectAnalyzer) {
return new RewriteProjectParser(
- mavenExecutor,
provenanceMarkerFactory,
buildFileParser,
sourceFileParser,
@@ -179,7 +164,8 @@ RewriteProjectParser rewriteProjectParser(
scanScope,
beanFactory,
projectScanner,
- executionContext);
+ executionContext,
+ mavenProjectAnalyzer);
}
@Bean
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteProjectParser.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteProjectParser.java
index 684e99d0c..1a4881906 100644
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteProjectParser.java
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteProjectParser.java
@@ -17,18 +17,12 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.maven.execution.MavenSession;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.project.MavenProject;
+import org.jetbrains.annotations.NotNull;
import org.openrewrite.ExecutionContext;
-import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.SourceFile;
import org.openrewrite.marker.Marker;
-import org.openrewrite.maven.AbstractRewriteMojo;
import org.openrewrite.maven.MavenExecutionContextView;
-import org.openrewrite.maven.MavenMojoProjectParser;
-import org.openrewrite.maven.tree.MavenRepository;
+import org.openrewrite.maven.tree.*;
import org.openrewrite.style.NamedStyles;
import org.openrewrite.tree.ParsingEventListener;
import org.openrewrite.tree.ParsingExecutionContextView;
@@ -40,14 +34,13 @@
import org.springframework.sbm.parsers.events.StartedParsingProjectEvent;
import org.springframework.sbm.scopes.ScanScope;
import org.springframework.sbm.utils.ResourceUtil;
-import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.*;
-import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
@@ -70,16 +63,13 @@
* }
*
*
- * @see RewriteMavenProjectParser
- * @see org.springframework.sbm.recipes.RewriteRecipeDiscovery
- *
* @author Fabian Krüger
+ * @see org.springframework.sbm.recipes.RewriteRecipeDiscovery
*/
@Slf4j
@RequiredArgsConstructor
public class RewriteProjectParser {
- private final MavenExecutor mavenExecutor;
private final ProvenanceMarkerFactory provenanceMarkerFactory;
private final BuildFileParser buildFileParser;
private final SourceFileParser sourceFileParser;
@@ -91,10 +81,10 @@ public class RewriteProjectParser {
private final ConfigurableListableBeanFactory beanFactory;
private final ProjectScanner scanner;
private final ExecutionContext executionContext;
+ private final MavenProjectAnalyzer mavenProjectAnalyzer;
public RewriteProjectParsingResult parse(Path baseDir) {
- Set ignorePatterns = parserProperties.getIgnoredPathPatterns();
List resources = scanner.scan(baseDir);
return this.parse(baseDir, resources, executionContext);
}
@@ -116,16 +106,12 @@ public RewriteProjectParsingResult parse(Path baseDir) {
* Parse resources
* processMainSources()
* processTestSources()
- *
- * @see MavenMojoProjectParser#listSourceFiles(MavenProject, List, ExecutionContext)
*/
public RewriteProjectParsingResult parse(Path givenBaseDir, List resources, ExecutionContext executionContext) {
scanScope.clear(beanFactory);
- if (!givenBaseDir.isAbsolute()) {
- givenBaseDir = givenBaseDir.toAbsolutePath().normalize();
- }
- final Path baseDir = givenBaseDir;
+ final Path baseDir = normalizePath(givenBaseDir);
+
// FIXME: ... WARN 30694 --- [ main] .m.p.i.DeprecatedCoreExpressionValidator : Parameter 'local' is deprecated core expression; Avoid use of ArtifactRepository type. If you need access to local repository, switch to '${repositorySystemSession}' expression and get LRM from it instead.
MavenExecutionContextView.view(executionContext).setLocalRepository(new MavenRepository("local", "file://" + Path.of(System.getProperty("user.home")).resolve(".m2/repository"), null, null, false, null, null, null));
eventPublisher.publishEvent(new StartedParsingProjectEvent(resources));
@@ -137,82 +123,54 @@ public RewriteProjectParsingResult parse(Path givenBaseDir, List resou
// TODO: where to retrieve styles from? --> see AbstractRewriteMojo#getActiveStyles() & AbstractRewriteMojo#loadStyles()
List styles = List.of();
- AtomicReference atomicReference = new AtomicReference<>();
-
- withMavenSession(baseDir, mavenSession -> {
- // Get the ordered list of projects
- List sortedProjectsList = mavenSession.getProjectDependencyGraph().getSortedProjects();
- // SortedProjects makes downstream components independent of Maven classes
- SortedProjects mavenInfos = new SortedProjects(resources, sortedProjectsList, List.of("default"));
+ // Get the ordered list of projects
+ ParserContext parserContext = mavenProjectAnalyzer.createParserContext(baseDir, resources);
+ // SortedProjects makes downstream components independent of Maven classes
+ // TODO: 945 Is SortedProjects still required?
// List sortedBuildFileResources = buildFileParser.filterAndSortBuildFiles(resources);
- // generate provenance
- Map> provenanceMarkers = provenanceMarkerFactory.generateProvenanceMarkers(baseDir, mavenInfos);
+ // generate provenance
+ Map> provenanceMarkers = provenanceMarkerFactory.generateProvenanceMarkers(baseDir, parserContext);
- // 127: parse build files
- Map resourceToDocumentMap = buildFileParser.parseBuildFiles(baseDir, mavenInfos.getResources(), mavenInfos.getActiveProfiles(), executionContext, parserProperties.isSkipMavenParsing(), provenanceMarkers);
+ // 127: parse build files
+ Map resourceToDocumentMap = buildFileParser.parseBuildFiles(baseDir, parserContext.getBuildFileResources(), parserContext.getActiveProfiles(), executionContext, parserProperties.isSkipMavenParsing(), provenanceMarkers);
- List parsedAndSortedBuildFileDocuments = mavenInfos.getResources().stream()
- .map(r -> resourceToDocumentMap.get(ResourceUtil.getPath(r)))
- .map(SourceFile.class::cast)
- .toList();
+ List parsedAndSortedBuildFileDocuments = parserContext.getBuildFileResources().stream()
+ .map(r -> resourceToDocumentMap.get(ResourceUtil.getPath(r)))
+ .map(SourceFile.class::cast)
+ // FIXME: 945 ugly hack
+ .peek(sourceFile -> addSourceFileToModel(baseDir, parserContext.getSortedProjects(), sourceFile))
+ .toList();
- // 128 : 131
- log.trace("Start to parse %d source files in %d modules".formatted(resources.size() + resourceToDocumentMap.size(), resourceToDocumentMap.size()));
- List list = sourceFileParser.parseOtherSourceFiles(baseDir, mavenInfos, resourceToDocumentMap, mavenInfos.getResources(), provenanceMarkers, styles, executionContext);
+ log.trace("Start to parse %d source files in %d modules".formatted(resources.size() + resourceToDocumentMap.size(), resourceToDocumentMap.size()));
+ List list = sourceFileParser.parseOtherSourceFiles(baseDir, parserContext, resourceToDocumentMap, resources, provenanceMarkers, styles, executionContext);
// List sourceFilesWithoutPoms = sourceFilesStream.filter(sf -> resourceToDocumentMap.keySet().contains(baseDir.resolve(sf.getSourcePath()).toAbsolutePath().normalize())).toList();
- List resultingList = new ArrayList<>(); // sourceFilesStream2.toList();
- resultingList.addAll(parsedAndSortedBuildFileDocuments);
- resultingList.addAll(list);
- List sourceFiles = styleDetector.sourcesWithAutoDetectedStyles(resultingList.stream());
-
- eventPublisher.publishEvent(new SuccessfullyParsedProjectEvent(sourceFiles));
-
- atomicReference.set(new RewriteProjectParsingResult(sourceFiles, executionContext));
- });
-
- return atomicReference.get();
- }
-
- private void withMavenSession(Path baseDir, Consumer consumer) {
- List goals = List.of("clean", "package");
- log.debug("Successfully finished goals %s".formatted(goals));
- mavenExecutor.onProjectSucceededEvent(baseDir, goals, event -> consumer.accept(event.getSession()));
- }
+ List resultingList = new ArrayList<>(); // sourceFilesStream2.toList();
+ resultingList.addAll(parsedAndSortedBuildFileDocuments);
+ resultingList.addAll(list);
+ List sourceFiles = styleDetector.sourcesWithAutoDetectedStyles(resultingList.stream());
- @org.jetbrains.annotations.Nullable
- private static List autoDetectStyles(Stream sourceFilesStream) {
- RewriteMojo dummyRewriteMojo = new RewriteMojo();
- Method sourcesWithAutoDetectedStylesMethod = ReflectionUtils.findMethod(RewriteMojo.class, "sourcesWithAutoDetectedStyles");
- ReflectionUtils.makeAccessible(sourcesWithAutoDetectedStylesMethod);
- Object o = ReflectionUtils.invokeMethod(sourcesWithAutoDetectedStylesMethod, dummyRewriteMojo, sourceFilesStream);
- List sourceFiles = (List) o;
- return sourceFiles;
- }
+ eventPublisher.publishEvent(new SuccessfullyParsedProjectEvent(sourceFiles));
-// private Stream parseToAst(Path baseDir, List resources, List styles, ExecutionContext executionContext) throws DependencyResolutionRequiredException, MojoExecutionException {
-// MavenProject mavenProject = createFakeMavenProjectForProvenance(baseDir, resources, executionContext);
-// return super.listSourceFiles(mavenProject, styles, executionContext);
-// }
+ return new RewriteProjectParsingResult(sourceFiles, executionContext);
+// });
- private MavenProject createFakeMavenProjectForProvenance(Path baseDir, List resources, ExecutionContext executionContext) {
- MavenProject mavenProject = new MavenProject();
- // Plugin compilerPlugin = mavenProject.getPlugin("org.apache.maven.plugins:maven-compiler-plugin");
- mavenProject.setPluginArtifacts(Set.of());
- return mavenProject;
}
- /**
- * Extending {@code AbstractRewriteMojo} to open up protected method for reuse
- */
- static class RewriteMojo extends AbstractRewriteMojo {
-
- @Override
- public void execute() throws MojoExecutionException, MojoFailureException {
-
+ @NotNull
+ private static Path normalizePath(Path givenBaseDir) {
+ if (!givenBaseDir.isAbsolute()) {
+ givenBaseDir = givenBaseDir.toAbsolutePath().normalize();
}
+ final Path baseDir = givenBaseDir;
+ return baseDir;
}
+ private static void addSourceFileToModel(Path baseDir, List sortedProjectsList, SourceFile s) {
+ sortedProjectsList.stream()
+ .filter(p -> ResourceUtil.getPath(p.getPomFile()).toString().equals(baseDir.resolve(s.getSourcePath()).toString()))
+ .forEach(p -> p.setSourceFile(s));
+ }
}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteResourceParser.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteResourceParser.java
new file mode 100644
index 000000000..20fbebfd0
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/RewriteResourceParser.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Parser;
+import org.openrewrite.SourceFile;
+import org.openrewrite.hcl.HclParser;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.json.JsonParser;
+import org.openrewrite.properties.PropertiesParser;
+import org.openrewrite.protobuf.ProtoParser;
+import org.openrewrite.quark.QuarkParser;
+import org.openrewrite.text.PlainTextParser;
+import org.openrewrite.xml.XmlParser;
+import org.openrewrite.yaml.YamlParser;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+import org.springframework.sbm.utils.ResourceUtil;
+
+import java.nio.file.*;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Code from https://github.com/fabapp2/rewrite-maven-plugin/blob/83d184ea9ffe3046429f16c91aa56a9610bae832/src/main/java/org/openrewrite/maven/ResourceParser.java
+ * The motivation was to decouple the parser from file access.
+ */
+@Slf4j
+public class RewriteResourceParser {
+ private static final Set DEFAULT_IGNORED_DIRECTORIES = new HashSet<>(Arrays.asList("build", "target", "out", ".sonar", ".gradle", ".idea", ".project", "node_modules", ".git", ".metadata", ".DS_Store"));
+
+ private final Path baseDir;
+ private final Collection exclusions;
+ private final int sizeThresholdMb;
+ private final Collection excludedDirectories;
+ private final Collection plainTextMasks;
+
+ /**
+ * Sometimes java files will exist in the src/main/resources directory. For example, Drools:
+ */
+ private final JavaParser.Builder extends JavaParser, ?> javaParserBuilder;
+ private final ExecutionContext executionContext;
+
+ public RewriteResourceParser(
+ Path baseDir,
+ Collection exclusions,
+ Collection plainTextMasks,
+ int sizeThresholdMb,
+ Collection excludedDirectories,
+ JavaParser.Builder extends JavaParser, ?> javaParserBuilder,
+ ExecutionContext executionContext
+ ) {
+ this.baseDir = baseDir;
+ this.javaParserBuilder = javaParserBuilder;
+ this.executionContext = executionContext;
+ this.exclusions = pathMatchers(baseDir, exclusions);
+ this.sizeThresholdMb = sizeThresholdMb;
+ this.excludedDirectories = excludedDirectories;
+ this.plainTextMasks = pathMatchers(baseDir, plainTextMasks);
+ }
+
+ private Collection pathMatchers(Path basePath, Collection pathExpressions) {
+ return pathExpressions.stream()
+ .map(o -> basePath.getFileSystem().getPathMatcher("glob:" + o))
+ .collect(Collectors.toList());
+ }
+
+ public Stream parse(Path searchDir, List resources, Set alreadyParsed) {
+ // TODO: 945 remove/clean this up
+ List resourcesLeft = resources.stream()
+ .filter(r -> alreadyParsed.stream().noneMatch(path -> ResourceUtil.getPath(r).toString().startsWith(path.toString())))
+ .toList();
+ return this.parseSourceFiles(searchDir, resourcesLeft, alreadyParsed, executionContext);
+
+
+//
+// Stream sourceFiles = Stream.empty();
+// if (!searchDir.toFile().exists()) {
+// return sourceFiles;
+// } else {
+// Consumer errorConsumer = (t) -> {
+// this.logger.debug("Error parsing", t);
+// };
+// InMemoryExecutionContext ctx = new InMemoryExecutionContext(errorConsumer);
+//
+// try {
+// sourceFiles = Stream.concat(sourceFiles, this.parseSourceFiles(searchDir, alreadyParsed, ctx));
+// return sourceFiles;
+// } catch (IOException var7) {
+// this.logger.error(var7.getMessage(), var7);
+// throw new UncheckedIOException(var7);
+// }
+// }
+ }
+
+ @SuppressWarnings({"DuplicatedCode", "unchecked"})
+ public Stream parseSourceFiles(
+ Path searchDir,
+ List resources,
+ Set alreadyParsed,
+ ExecutionContext ctx) {
+
+ List resourcesLeft = new ArrayList<>();
+ List quarkPaths = new ArrayList<>();
+ List plainTextPaths = new ArrayList<>();
+
+ List filteredResources = resources
+ .stream()
+ .filter(r -> ResourceUtil.getPath(r).toString().startsWith(searchDir.toString()))
+ .toList();
+
+ filteredResources.forEach(resource -> {
+ Path file = ResourceUtil.getPath(resource);
+ Path dir = file.getParent();
+ if (isExcluded(dir) || isIgnoredDirectory(searchDir, dir) || excludedDirectories.contains(dir) || alreadyParsed.contains(new FileSystemResource(dir)) || alreadyParsed.contains(resource)) {
+ return;
+ } else {
+ // FIXME: 945 only check threshold if value > 0 is given
+ long fileSize = ResourceUtil.contentLength(resource);
+ if (isOverSizeThreshold(fileSize)) {
+ log.info("Parsing as quark " + file + " as its size " + fileSize / (1024L * 1024L) +
+ "Mb exceeds size threshold " + sizeThresholdMb + "Mb");
+ quarkPaths.add(file);
+ } else if (isParsedAsPlainText(file)) {
+ plainTextPaths.add(file);
+ } else {
+ resourcesLeft.add(file);
+ }
+ }
+ });
+
+ Stream sourceFiles = Stream.empty();
+
+ JavaParser javaParser = javaParserBuilder.build();
+ List javaPaths = new ArrayList<>();
+
+ JsonParser jsonParser = new JsonParser();
+ List jsonPaths = new ArrayList<>();
+
+ XmlParser xmlParser = new XmlParser();
+ List xmlPaths = new ArrayList<>();
+
+ YamlParser yamlParser = new YamlParser();
+ List yamlPaths = new ArrayList<>();
+
+ PropertiesParser propertiesParser = new PropertiesParser();
+ List propertiesPaths = new ArrayList<>();
+
+ ProtoParser protoParser = new ProtoParser();
+ List protoPaths = new ArrayList<>();
+
+ // Python currently not supported
+// PythonParser pythonParser = PythonParser.builder().build();
+// List pythonPaths = new ArrayList<>();
+
+ HclParser hclParser = HclParser.builder().build();
+ List hclPaths = new ArrayList<>();
+
+ PlainTextParser plainTextParser = new PlainTextParser();
+
+ QuarkParser quarkParser = new QuarkParser();
+
+ filteredResources
+ .forEach(resource -> {
+ // See https://github.com/quarkusio/quarkus/blob/main/devtools/project-core-extension-codestarts/src/main/resources/codestarts/quarkus/extension-codestarts/resteasy-reactive-codestart/java/src/main/java/org/acme/%7Bresource.class-name%7D.tpl.qute.java
+ // for an example of why we don't want qute files be parsed as java
+ Path path = ResourceUtil.getPath(resource);
+// if (javaParser.accept(path) && !path.toString().endsWith(".qute.java")) {
+// javaPaths.add(path);
+// }
+ if (jsonParser.accept(path)) {
+ jsonPaths.add(path);
+ } else if (xmlParser.accept(path)) {
+ xmlPaths.add(path);
+ } else if (yamlParser.accept(path)) {
+ yamlPaths.add(path);
+ } else if (propertiesParser.accept(path)) {
+ propertiesPaths.add(path);
+ } else if (protoParser.accept(path)) {
+ protoPaths.add(path);
+ } /*else if(pythonParser.accept(path)) {
+ pythonPaths.add(path);
+ }*/ else if (hclParser.accept(path)) {
+ hclPaths.add(path);
+ } else if (quarkParser.accept(path)) {
+ quarkPaths.add(path);
+ }
+ });
+
+ Map pathToResource = filteredResources.stream().collect(Collectors.toMap(r -> ResourceUtil.getPath(r), r -> r));
+
+ if (!javaPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, javaPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) javaParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(javaPaths);
+ }
+
+ if (!jsonPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, jsonPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) jsonParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(jsonPaths);
+ }
+
+ if (!xmlPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, xmlPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) xmlParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(xmlPaths);
+ }
+
+ if (!yamlPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, yamlPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) yamlParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(yamlPaths);
+ }
+
+ if (!propertiesPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, propertiesPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) propertiesParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(propertiesPaths);
+ }
+
+ if (!protoPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, protoPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) protoParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(protoPaths);
+ }
+
+// if (!pythonPaths.isEmpty()) {
+// List inputs = getInputs(pathToResource, pythonPaths);
+// sourceFiles = Stream.concat(sourceFiles, (Stream) pythonParser.parseInputs(inputs, baseDir, ctx));
+// alreadyParsed.addAll(pythonPaths);
+// }
+
+ if (!hclPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, hclPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) hclParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(hclPaths);
+ }
+
+ if (!plainTextPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, plainTextPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) plainTextParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(plainTextPaths);
+ }
+
+ if (!quarkPaths.isEmpty()) {
+ List inputs = getInputs(pathToResource, quarkPaths);
+ sourceFiles = Stream.concat(sourceFiles, (Stream) quarkParser.parseInputs(inputs, baseDir, ctx));
+ alreadyParsed.addAll(quarkPaths);
+ }
+
+ return sourceFiles;
+ }
+
+ @NotNull
+ private static List getInputs(Map pathResourceMap, List paths) {
+ return paths.stream()
+ .map(path -> new Parser.Input(path, () -> ResourceUtil.getInputStream(pathResourceMap.get(path)))).toList();
+ }
+
+ private boolean isOverSizeThreshold(long fileSize) {
+ return sizeThresholdMb > 0 && fileSize > sizeThresholdMb * 1024L * 1024L;
+ }
+
+ private boolean isExcluded(Path path) {
+ if (!exclusions.isEmpty()) {
+ for (PathMatcher excluded : exclusions) {
+ if (excluded.matches(baseDir.relativize(path))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isParsedAsPlainText(Path path) {
+ if (!plainTextMasks.isEmpty()) {
+ Path computed = baseDir.relativize(path);
+ if (!computed.startsWith("/")) {
+ computed = Paths.get("/").resolve(computed);
+ }
+ for (PathMatcher matcher : plainTextMasks) {
+ if (matcher.matches(computed)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isIgnoredDirectory(Path searchDir, Path path) {
+ for (Path pathSegment : searchDir.relativize(path)) {
+ if (DEFAULT_IGNORED_DIRECTORIES.contains(pathSegment.toString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SbmMavenProject.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SbmMavenProject.java
new file mode 100644
index 000000000..0debaebb9
--- /dev/null
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SbmMavenProject.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2021 - 2023 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.parsers;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.jetbrains.annotations.NotNull;
+import org.openrewrite.SourceFile;
+import org.openrewrite.maven.tree.*;
+import org.openrewrite.maven.utilities.MavenArtifactDownloader;
+import org.springframework.core.io.Resource;
+import org.springframework.sbm.utils.ResourceUtil;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.function.Predicate;
+
+
+@Getter
+@Setter
+/**
+ * @author Fabian Krüger
+ */
+public class SbmMavenProject {
+
+ private final Path projectRoot;
+ private final Resource pomFile;
+ // FIXME: 945 temporary method, model should nopt come from Maven
+ private final Model pomModel;
+ private List collectedProjects = new ArrayList<>();
+ private SourceFile sourceFile;
+ private final MavenArtifactDownloader rewriteMavenArtifactDownloader;
+ private final List resources;
+ private ProjectId projectId;
+
+ public SbmMavenProject(Path projectRoot, Resource pomFile, Model pomModel, MavenArtifactDownloader rewriteMavenArtifactDownloader, List resources) {
+ this.projectRoot = projectRoot;
+ this.pomFile = pomFile;
+ this.pomModel = pomModel;
+ this.rewriteMavenArtifactDownloader = rewriteMavenArtifactDownloader;
+ this.resources = resources;
+ projectId = new ProjectId(getGroupId(), getArtifactId());
+ }
+
+ public File getFile() {
+ return ResourceUtil.getPath(pomFile).toFile();
+ }
+
+ public Path getBasedir() {
+ // TODO: 945 Check if this is correct
+ return pomFile == null ? null : ResourceUtil.getPath(pomFile).getParent();
+ }
+
+ public void setCollectedProjects(List collected) {
+ this.collectedProjects = collected;
+ }
+
+ public List getCollectedProjects() {
+ return collectedProjects;
+ }
+
+ public Resource getResource() {
+ return pomFile;
+ }
+
+ public Path getModuleDir() {
+ if(getBasedir() == null) {
+ return null;
+ } else if(projectRoot.relativize(ResourceUtil.getPath(pomFile)).toString().equals("pom.xml")){
+ return Path.of("");
+ } else {
+ return projectRoot.relativize(ResourceUtil.getPath(pomFile)).getParent();
+ }
+ }
+
+
+ public String getGroupIdAndArtifactId() {
+ return this.pomModel.getGroupId() + ":" + pomModel.getArtifactId();
+ }
+
+ public Path getPomFilePath() {
+ return ResourceUtil.getPath(pomFile);
+ }
+
+ public Plugin getPlugin(String s) {
+ return pomModel.getBuild() == null ? null : pomModel.getBuild().getPluginsAsMap().get(s);
+ }
+
+ public Properties getProperties() {
+ return pomModel.getProperties();
+ }
+
+ public MavenRuntimeInformation getMavenRuntimeInformation() {
+ // FIXME: 945 implement this
+ return new MavenRuntimeInformation();
+ }
+
+ public String getName() {
+ return pomModel.getName();
+ }
+
+ public String getGroupId() {
+ return pomModel.getGroupId() == null ? pomModel.getParent().getGroupId() : pomModel.getGroupId();
+ }
+
+ public String getArtifactId() {
+ return pomModel.getArtifactId();
+ }
+
+ public String getVersion() {
+ return pomModel.getVersion();
+ }
+
+ @Override
+ public String toString() {
+ String groupId = pomModel.getGroupId() == null ? pomModel.getParent().getGroupId() : pomModel.getGroupId();
+ return groupId + ":" + pomModel.getArtifactId();
+ }
+
+ public String getBuildDirectory() {
+ String s = pomModel.getBuild() != null ? pomModel.getBuild().getDirectory() : null;
+ return s == null ? ResourceUtil.getPath(pomFile).getParent().resolve("target").toAbsolutePath().normalize().toString() : s;
+ }
+
+ public String getSourceDirectory() {
+ String s = pomModel.getBuild() != null ? pomModel.getBuild().getSourceDirectory() : null;
+ return s == null ? ResourceUtil.getPath(pomFile).getParent().resolve("src/main/java").toAbsolutePath().normalize().toString() : s;
+ }
+
+ public List getCompileClasspathElements() {
+ Scope scope = Scope.Compile;
+ return getClasspathElements(scope);
+ }
+
+ public List getTestClasspathElements() {
+ return getClasspathElements(Scope.Test);
+ }
+
+ @NotNull
+ private List getClasspathElements(Scope scope) {
+ MavenResolutionResult pom = getSourceFile().getMarkers().findFirst(MavenResolutionResult.class).get();
+ List resolvedDependencies = pom.getDependencies().get(scope);
+ if(resolvedDependencies != null) {
+ return resolvedDependencies
+ // FIXME: 945 - deal with dependencies to projects in reactor
+ //
+ .stream()
+ .filter(rd -> rd.getRepository() != null)
+ .map(rd -> rewriteMavenArtifactDownloader.downloadArtifact(rd))
+ .filter(Objects::nonNull)
+ .distinct()
+ .toList();
+ } else {
+ return new ArrayList<>();
+ }
+ }
+
+ public String getTestSourceDirectory() {
+ String s = pomModel.getBuild() != null ? pomModel.getBuild().getSourceDirectory() : null;
+ return s == null ? ResourceUtil.getPath(pomFile).getParent().resolve("src/test/java").toAbsolutePath().normalize().toString() : s;
+ }
+
+ public void setSourceFile(SourceFile sourceFile) {
+ this.sourceFile = sourceFile;
+ }
+
+ private static List listJavaSources(List resources, Path sourceDirectory) {
+ return resources.stream()
+ .filter(whenIn(sourceDirectory))
+ .filter(whenFileNameEndsWithJava())
+ .toList();
+ }
+
+ @NotNull
+ private static Predicate whenFileNameEndsWithJava() {
+ return p -> ResourceUtil.getPath(p).getFileName().toString().endsWith(".java");
+ }
+
+ @NotNull
+ private static Predicate whenIn(Path sourceDirectory) {
+ return r -> ResourceUtil.getPath(r).toString().startsWith(sourceDirectory.toString());
+ }
+
+
+ public List getJavaSourcesInTarget() {
+ return listJavaSources(getResources(), getBasedir().resolve(getBuildDirectory()));
+ }
+
+ private List getResources() {
+ return this.resources;
+ }
+
+ public List getMainJavaSources() {
+ return listJavaSources(resources, getProjectRoot().resolve(getModuleDir()).resolve("src/main/java"));
+ }
+
+ public Path getModulePath() {
+ return projectRoot.resolve(getModuleDir());
+ }
+
+ public ProjectId getProjectId() {
+ return projectId;
+ }
+}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SortedProjects.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SortedProjects.java
deleted file mode 100644
index 1174809f0..000000000
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SortedProjects.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2021 - 2023 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.parsers;
-
-import lombok.Getter;
-import org.apache.maven.model.Model;
-import org.apache.maven.project.MavenProject;
-import org.springframework.core.io.Resource;
-import org.springframework.sbm.utils.ResourceUtil;
-
-import java.io.File;
-import java.nio.file.Path;
-import java.util.List;
-
-/**
- * Helper class
- *
- * TODO: Make class independant to Maven and find better name.
- * TODO: Can this class be used to transport build information from Maven and Gradle to reuse functionality?
- *
- * @author Fabian Krüger
- */
-public class SortedProjects {
- private final List resources;
- @Getter
- private final List sortedProjects;
- @Getter
- private final List activeProfiles;
-
-
-
- // FIXME: The relation between resource and project is brittle, if it's really needed we should validate in constructor
- public SortedProjects(List given, List allProjects, List activeProfiles) {
- this.resources = given;
- this.sortedProjects = allProjects;
- this.activeProfiles = activeProfiles;
- }
-
- public List getResources() {
- return sortedProjects
- .stream()
- .map(MavenProject::getFile)
- .map(File::toPath)
- .map(m -> this.findResourceWithPath(m, resources))
- .toList();
- }
-
- private Resource findResourceWithPath(Path m, List resources) {
- return resources.stream()
- .filter(r -> ResourceUtil.getPath(r).equals(m))
- .findFirst()
- .orElseThrow(() -> new IllegalStateException("Could not find a resource in the list of resources that matches the path of pom '%s'".formatted(m.toString())));
- }
-
- public Resource getMatchingBuildFileResource(MavenProject pom) {
- return resources.stream()
- .filter(r -> ResourceUtil.getPath(r).equals(pom.getFile().toPath()))
- .findFirst()
- .orElseThrow(() -> new IllegalStateException("Could not find a resource in the list of resources that matches the path of MavenProject '%s'".formatted(pom.getFile().getPath().toString())));
- }
-
- private List readActiveProfiles(Model topLevelModel) {
- return activeProfiles;
- }
-
- public MavenProject getMavenProject(Resource r) {
- Path path = ResourceUtil.getPath(r);
- return sortedProjects.stream()
- .filter(p -> p.getFile().getPath().toString().equals(path.toString()))
- .findFirst()
- .orElseThrow(() -> new IllegalArgumentException("Could not find MavenProject for given resource '%s'".formatted(path)));
- }
-}
diff --git a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SourceFileParser.java b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SourceFileParser.java
index 757b64688..eccdcbd7b 100644
--- a/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SourceFileParser.java
+++ b/sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/SourceFileParser.java
@@ -17,13 +17,10 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.maven.project.MavenProject;
import org.openrewrite.ExecutionContext;
import org.openrewrite.SourceFile;
import org.openrewrite.java.JavaParser;
import org.openrewrite.marker.Marker;
-import org.openrewrite.maven.MavenMojoProjectParser;
-import org.openrewrite.maven.ResourceParser;
import org.openrewrite.style.NamedStyles;
import org.openrewrite.xml.tree.Xml;
import org.springframework.core.io.Resource;
@@ -44,12 +41,11 @@
public class SourceFileParser {
private final ParserProperties parserProperties;
- private final MavenMojoProjectParserPrivateMethods mavenMojoProjectParserPrivateMethods;
- private final JavaParserBuilder javaParserBuilder;
+ private final HelperWithoutAGoodName mavenMojoProjectParserPrivateMethods;
public List parseOtherSourceFiles(
Path baseDir,
- SortedProjects mavenProject,
+ ParserContext parserContext,
Map pathToDocumentMap,
List resources,
Map> provenanceMarkers,
@@ -58,12 +54,12 @@ public List parseOtherSourceFiles(
Set parsedSourceFiles = new LinkedHashSet<>();
- mavenProject.getSortedProjects().forEach(currentMavenProject -> {
- Resource moduleBuildFileResource = mavenProject.getMatchingBuildFileResource(currentMavenProject);
+ parserContext.getSortedProjects().forEach(currentMavenProject -> {
+ Resource moduleBuildFileResource = parserContext.getMatchingBuildFileResource(currentMavenProject);
Xml.Document moduleBuildFile = pathToDocumentMap.get(ResourceUtil.getPath(moduleBuildFileResource));
List markers = provenanceMarkers.get(ResourceUtil.getPath(moduleBuildFileResource));
if(markers == null || markers.isEmpty()) {
- log.warn("Could not find provenance markers for resource '%s'".formatted(mavenProject.getMatchingBuildFileResource(currentMavenProject)));
+ log.warn("Could not find provenance markers for resource '%s'".formatted(parserContext.getMatchingBuildFileResource(currentMavenProject)));
}
List sourceFiles = parseModuleSourceFiles(resources, currentMavenProject, moduleBuildFile, markers, styles, executionContext, baseDir);
parsedSourceFiles.addAll(sourceFiles);
@@ -72,18 +68,16 @@ public List parseOtherSourceFiles(
return new ArrayList<>(parsedSourceFiles);
}
- /**
- * {@link org.openrewrite.maven.MavenMojoProjectParser#listSourceFiles(MavenProject, Xml.Document, List, List, ExecutionContext)}
- */
private List parseModuleSourceFiles(
List resources,
- MavenProject mavenProject,
+ SbmMavenProject currentProject,
Xml.Document moduleBuildFile,
List provenanceMarkers,
List styles,
ExecutionContext executionContext,
Path baseDir)
{
+
List sourceFiles = new ArrayList<>();
// 146:149: get source encoding from maven
// TDOD:
@@ -97,36 +91,38 @@ private List parseModuleSourceFiles(
.styles(styles)
.logCompilationWarningsAndErrors(false);
- Path buildFilePath = mavenProject.getBasedir().toPath().resolve(moduleBuildFile.getSourcePath());
+ Path buildFilePath = currentProject.getBasedir().resolve(moduleBuildFile.getSourcePath());
+ log.info("Parsing module " + buildFilePath);
// these paths will be ignored by ResourceParser
- Set skipResourceScanDirs = pathsToOtherMavenProjects(mavenProject, buildFilePath);
- ResourceParser rp = new ResourceParser(
+ Set skipResourceScanDirs = pathsToOtherMavenProjects(currentProject, buildFilePath);
+ // FIXME: Why is skipResourceScanDirs required at all? Shouldn't the module know it's resources
+ RewriteResourceParser rp = new RewriteResourceParser(
baseDir,
- new Slf4jToMavenLoggerAdapter(log),
parserProperties.getIgnoredPathPatterns(),
parserProperties.getPlainTextMasks(),
parserProperties.getSizeThresholdMb(),
skipResourceScanDirs,
- javaParserBuilder.clone()
- );
+ javaParserBuilder.clone(),
+ executionContext);
// 155:156: parse main and test sources
Set alreadyParsed = new HashSet<>();
- alreadyParsed.add(baseDir.resolve(moduleBuildFile.getSourcePath()));
- List mainSources = parseMainSources(baseDir, mavenProject, moduleBuildFile, javaParserBuilder.clone(), rp, provenanceMarkers, alreadyParsed, executionContext);
- List testSources = parseTestSources(baseDir, mavenProject, moduleBuildFile, javaParserBuilder.clone(), rp, provenanceMarkers, alreadyParsed, executionContext);
-
+ Path moduleBuildFilePath = baseDir.resolve(moduleBuildFile.getSourcePath());
+ alreadyParsed.add(moduleBuildFilePath);
alreadyParsed.addAll(skipResourceScanDirs);
- // 171:175
- Stream parsedResourceFiles = rp.parse(baseDir.resolve(moduleBuildFile.getSourcePath()).getParent(), alreadyParsed )
+ List mainSources = parseMainSources(baseDir, currentProject, moduleBuildFile, resources, javaParserBuilder.clone(), rp, provenanceMarkers, alreadyParsed, executionContext);
+ List testSources = parseTestSources(baseDir, currentProject, moduleBuildFile, javaParserBuilder.clone(), rp, provenanceMarkers, alreadyParsed, executionContext, resources);
+ // Collect the dirs of modules parsed in previous steps
+
+ // parse other project resources
+ Stream parsedResourceFiles = rp.parse(moduleBuildFilePath.getParent(), resources, alreadyParsed)
// FIXME: handle generated sources
.map(mavenMojoProjectParserPrivateMethods.addProvenance(baseDir, provenanceMarkers, null));
-
// 157:169
- List resourceSourceFiles = mergeAndFilterExcluded(baseDir, parserProperties.getIgnoredPathPatterns(), mainSources, testSources);
+ List mainAndTestSources = mergeAndFilterExcluded(baseDir, parserProperties.getIgnoredPathPatterns(), mainSources, testSources);
List resourceFilesList = parsedResourceFiles.toList();
+ sourceFiles.addAll(mainAndTestSources);
sourceFiles.addAll(resourceFilesList);
- sourceFiles.addAll(resourceSourceFiles);
return sourceFiles;
}
@@ -149,21 +145,20 @@ private static boolean isNotExcluded(Path baseDir, List exclusions,
.noneMatch(pm -> pm.matches(baseDir.resolve(s.getSourcePath()).toAbsolutePath().normalize()));
}
- private List parseTestSources(Path baseDir, MavenProject mavenProject, Xml.Document moduleBuildFile, JavaParser.Builder extends JavaParser, ?> javaParserBuilder, ResourceParser rp, List provenanceMarkers, Set alreadyParsed, ExecutionContext executionContext) {
- return mavenMojoProjectParserPrivateMethods.processTestSources(baseDir, moduleBuildFile, javaParserBuilder, rp, provenanceMarkers, alreadyParsed, executionContext, mavenProject);
+ private List parseTestSources(Path baseDir, SbmMavenProject sbmMavenProject, Xml.Document moduleBuildFile, JavaParser.Builder extends JavaParser, ?> javaParserBuilder, RewriteResourceParser rp, List provenanceMarkers, Set alreadyParsed, ExecutionContext executionContext, List resources) {
+ return mavenMojoProjectParserPrivateMethods.processTestSources(baseDir, moduleBuildFile, javaParserBuilder, rp, provenanceMarkers, alreadyParsed, executionContext, sbmMavenProject, resources);
}
/**
- * {@link MavenMojoProjectParser#processMainSources(MavenProject, JavaParser.Builder, ResourceParser, List, Set, ExecutionContext)}
*/
- private List parseMainSources(Path baseDir, MavenProject mavenProject, Xml.Document moduleBuildFile, JavaParser.Builder extends JavaParser, ?> javaParserBuilder, ResourceParser rp, List provenanceMarkers, Set