parserInputProvider) {
- this.mavenParser = mavenParserBuilder.build();
- this.javaParserBuilder = javaParserBuilder;
- this.ctx = ctx;
- this.parserInputProvider = parserInputProvider;
- }
-
- /**
- * Given a root path to a maven project, this parser will parse the maven project (including submodules)
- * and return a list of ALL source files for all maven modules under the root path.
- *
- * Notes About Provenance Information:
- *
- * There are always three markers applied to each source file and there can potentially be up to five provenance
- * markers in total:
- *
- * BuildTool - What build tool was used to compile the source file (This will always be Maven)
- * JavaVersion - What Java version/vendor was used when compiling the source file.
- * JavaProject - For each maven module/sub-module, the same JavaProject will be associated with ALL source files
- * belonging to that module.
- *
- * Optional:
- *
- * GitProvenance - If the entire project exists in the context of a git repository, all source files (for all modules) will have the same GitProvenance.
- * JavaSourceSet - All Java source files and all resource files that exist in src/main or src/test will have a JavaSourceSet marker assigned to them.
- *
- *
- * @param projectDirectory A path to the root folder containing a meven project.
- * @return A list of source files that have been parsed from the root folder
- */
- public List parse(Path projectDirectory, List dependencies) {
- List mavens = mavenParser.parseInputs(getMavenPoms(projectDirectory, ctx, parserInputProvider), projectDirectory, ctx);
- List sorted = sort(mavens);
-
- // Filter out pom files inside target folders. (Naive implementation.)
- mavens = sorted.stream().filter(m -> !isInsideBuildFolderOfOtherMavenProjects(sorted, m)).collect(Collectors.toList());
-
- JavaParser javaParser = javaParserBuilder.build();
-
- logger.info("The order in which projects are being parsed is:");
- for (Xml.Document maven : mavens) {
- logger.info(" {}:{}", getModel(maven).getGroupId(), getModel(maven).getArtifactId());
- }
-
- List sourceFiles = new ArrayList<>();
- for (Xml.Document maven : mavens) {
- List projectProvenance = getJavaProvenance(maven, projectDirectory);
- sourceFiles.add(addProjectProvenance(maven, projectProvenance));
-
-// List dependencies = downloadArtifacts(getResolvedPom(maven).getDependencies().get(Scope.Compile));
- javaParser.setClasspath(dependencies);
- List mainJavaSources = ListUtils.map(javaParser.parseInputs(
- getJavaSources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, ctx), addProvenance(projectProvenance));
- JavaSourceSet mainSourceSet = ORAstUtils.addJavaSourceSet(mainJavaSources, MAIN, dependencies);
- sourceFiles.addAll(mainJavaSources);
- //Resources in the src/main should also have the main source set attached to them.
- parseResources(getResources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, sourceFiles, projectProvenance, mainSourceSet);
-
-// List testDependencies = downloadArtifacts(maven.getModel().getDependencies(Scope.Test));
-// javaParser.setClasspath(testDependencies);
- List testJavaSources = ListUtils.map(javaParser.parseInputs(
- getTestJavaSources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, ctx), addProvenance(projectProvenance));
- JavaSourceSet testSourceSet = ORAstUtils.addJavaSourceSet(testJavaSources, TEST, dependencies);
- sourceFiles.addAll(testJavaSources);
- //Resources in the src/test should also have the test source set attached to them.
- parseResources(getTestResources(getModel(maven).getRequested(), projectDirectory, ctx, parserInputProvider), projectDirectory, sourceFiles, projectProvenance, testSourceSet);
- }
-
- return sourceFiles;
- }
-
- private List getJavaProvenance(Xml.Document maven, Path projectDirectory) {
- ResolvedPom mavenModel = getModel(maven);
- String javaRuntimeVersion = System.getProperty("java.runtime.version");
- String javaVendor = System.getProperty("java.vm.vendor");
- String sourceCompatibility = javaRuntimeVersion;
- String targetCompatibility = javaRuntimeVersion;
- String propertiesSourceCompatibility = mavenModel.getValue(mavenModel.getValue("maven.compiler.source"));
- if (propertiesSourceCompatibility != null) {
- sourceCompatibility = propertiesSourceCompatibility;
- }
- String propertiesTargetCompatibility = mavenModel.getValue(mavenModel.getValue("maven.compiler.target"));
- if (propertiesTargetCompatibility != null) {
- targetCompatibility = propertiesTargetCompatibility;
- }
-
- Path wrapperPropertiesPath = projectDirectory.resolve(".mvn/wrapper/maven-wrapper.properties");
- String mavenVersion = "3.6";
- if (Files.exists(wrapperPropertiesPath)) {
- try {
- Properties wrapperProperties = new Properties();
- wrapperProperties.load(new FileReader(wrapperPropertiesPath.toFile()));
- String distributionUrl = (String) wrapperProperties.get("distributionUrl");
- if (distributionUrl != null) {
- Matcher wrapperVersionMatcher = mavenWrapperVersionPattern.matcher(distributionUrl);
- if (wrapperVersionMatcher.matches()) {
- mavenVersion = wrapperVersionMatcher.group(1);
- }
- }
- } catch (IOException e) {
- ctx.getOnError().accept(e);
- }
- }
-
- return Arrays.asList(
- new BuildTool(randomId(), BuildTool.Type.Maven, mavenVersion),
- new JavaVersion(randomId(), javaRuntimeVersion, javaVendor, sourceCompatibility, targetCompatibility),
- new JavaProject(randomId(), mavenModel.getRequested().getName(), new JavaProject.Publication(
- mavenModel.getGroupId(),
- mavenModel.getArtifactId(),
- mavenModel.getVersion()
- ))
- );
- }
-
- private void parseResources(List resources, Path projectDirectory, List sourceFiles, List projectProvenance, JavaSourceSet sourceSet) {
- List provenance = new ArrayList<>(projectProvenance);
- provenance.add(sourceSet);
-
- sourceFiles.addAll(ListUtils.map(new XmlParser().parseInputs(
- resources.stream()
- .filter(p -> p.getPath().getFileName().toString().endsWith(".xml") ||
- p.getPath().getFileName().toString().endsWith(".wsdl") ||
- p.getPath().getFileName().toString().endsWith(".xhtml") ||
- p.getPath().getFileName().toString().endsWith(".xsd") ||
- p.getPath().getFileName().toString().endsWith(".xsl") ||
- p.getPath().getFileName().toString().endsWith(".xslt"))
- .collect(Collectors.toList()),
- projectDirectory,
- ctx
- ), addProvenance(provenance)));
-
- sourceFiles.addAll(ListUtils.map(new YamlParser().parseInputs(
- resources.stream()
- .filter(p -> p.getPath().getFileName().toString().endsWith(".yml") || p.getPath().getFileName().toString().endsWith(".yaml"))
- .collect(Collectors.toList()),
- projectDirectory,
- ctx
- ), addProvenance(provenance)));
-
- sourceFiles.addAll(ListUtils.map(new PropertiesParser().parseInputs(
- resources.stream()
- .filter(p -> p.getPath().getFileName().toString().endsWith(".properties"))
- .collect(Collectors.toList()),
- projectDirectory,
- ctx
- ), addProvenance(provenance)));
-
- sourceFiles.addAll(ListUtils.map(new PlainTextParser().parseInputs(
- resources.stream()
- .filter(p -> p.getPath().getFileName().toString().endsWith(".factories"))
- .collect(Collectors.toList()),
- projectDirectory,
- ctx
- ), addProvenance(provenance)));
- }
-
- private S addProjectProvenance(S s, List projectProvenance) {
- for (Marker marker : projectProvenance) {
- s = s.withMarkers(s.getMarkers().addIfAbsent(marker));
- }
- return s;
- }
-
- private UnaryOperator addProvenance(List projectProvenance) {
- return s -> {
- s = addProjectProvenance(s, projectProvenance);
- return s;
- };
- }
-
-// private List downloadArtifacts(Set dependencies) {
-// return dependencies.stream()
-// .filter(d -> d.getRepository() != null)
-// .map(artifactDownloader::downloadArtifact)
-// .filter(Objects::nonNull)
-// .collect(Collectors.toList());
-// }
-
- public static List sort(List mavens) {
- // the value is the set of maven projects that depend on the key
- Map> byDependedOn = new HashMap<>();
-
- for (Xml.Document maven : mavens) {
- byDependedOn.computeIfAbsent(maven, m -> new HashSet<>());
- for (Dependency dependency : getModel(maven).getRequested().getDependencies()) {
- for (Xml.Document test : mavens) {
- if (getModel(test).getGroupId().equals(dependency.getGroupId()) &&
- getModel(test).getArtifactId().equals(dependency.getArtifactId())) {
- byDependedOn.computeIfAbsent(maven, m -> new HashSet<>()).add(test);
- }
- }
- }
- }
-
- List sorted = new ArrayList<>(mavens.size());
- next:
- while (!byDependedOn.isEmpty()) {
- for (Map.Entry> mavenAndDependencies : byDependedOn.entrySet()) {
- if (mavenAndDependencies.getValue().isEmpty()) {
- Xml.Document maven = mavenAndDependencies.getKey();
- byDependedOn.remove(maven);
- sorted.add(maven);
- for (Set dependencies : byDependedOn.values()) {
- dependencies.remove(maven);
- }
- continue next;
- }
- }
- }
-
- return sorted;
- }
-
- private static boolean isInsideBuildFolderOfOtherMavenProjects(List all, Xml.Document current) {
- return all.stream().filter(m -> {
- if (m != current) {
- Path pomPath = m.getSourcePath();
- return current.getSourcePath().startsWith((pomPath.getParent() == null ? Paths.get("") : pomPath.getParent()) .resolve("target"));
- }
- return false;
- }).findFirst().isPresent();
- }
-
- private static List getSources(Path srcDir, ExecutionContext ctx, Function parserInputProvider, String... fileTypes) {
- if (!srcDir.toFile().exists()) {
- return List.of();
- }
-
- BiPredicate predicate = (p, bfa) ->
- bfa.isRegularFile() && Arrays.stream(fileTypes).anyMatch(type -> p.getFileName().toString().endsWith(type));
- try {
- return Files.find(srcDir, 999, predicate).map(p -> {
- Parser.Input in = null;
- if (parserInputProvider != null) {
- in = parserInputProvider.apply(p);
- }
- if (in == null) {
- in = new Parser.Input(p, () -> {
- try {
- return Files.newInputStream(p);
- } catch (IOException e) {
- return new ByteArrayInputStream(new byte[0]);
- }
- });
- }
- return in;
- }).collect(Collectors.toList());
- } catch (IOException e) {
- ctx.getOnError().accept(e);
- return List.of();
- }
- }
-
- public static List getMavenPoms(Path projectDir, ExecutionContext ctx,
- Function parserInputProvider) {
- return getSources(projectDir, ctx, parserInputProvider, "pom.xml").stream().filter(p -> {
- Path relativeToProject = projectDir.relativize(p.getPath());
- String relativePathStr = relativeToProject.toString();
- return relativeToProject.getFileName().toString().equals("pom.xml")
- && !relativePathStr.contains("/src/") && !relativePathStr.startsWith("src/")
- && !relativePathStr.contains("/bin/") && !relativePathStr.startsWith("bin/")
- && !relativePathStr.contains("/target/") && !relativePathStr.startsWith("target/");
- }).collect(Collectors.toList());
- }
-
- private static ResolvedPom getModel(Xml.Document maven) {
- MavenResolutionResult pom = getResolvedPom(maven);
- return pom == null ? null : pom.getPom();
- }
-
- private static MavenResolutionResult getResolvedPom(Xml.Document maven) {
- return maven.getMarkers().findFirst(MavenResolutionResult.class).orElse(null);
- }
-
- private static List getJavaSources(Pom pom, Path projectDir, ExecutionContext ctx, Function parserInputProvider) {
- if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
- return List.of();
- }
- return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "main", "java")),
- ctx, parserInputProvider, ".java");
- }
-
- private static List getTestJavaSources(Pom pom, Path projectDir, ExecutionContext ctx, Function parserInputProvider) {
- if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
- return List.of();
- }
- return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "test", "java")),
- ctx, parserInputProvider, ".java");
- }
-
- private static List getResources(Pom pom, Path projectDir, ExecutionContext ctx, Function parserInputProvider) {
- if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
- return List.of();
- }
- return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "main", "resources")),
- ctx, parserInputProvider, ".properties", ".xml", ".yml", ".yaml", ".factories");
- }
-
- private static List getTestResources(Pom pom, Path projectDir, ExecutionContext ctx, Function parserInputProvider) {
- if (pom.getPackaging() != null && !"jar".equals(pom.getPackaging()) && !"bundle".equals(pom.getPackaging())) {
- return List.of();
- }
- return getSources(projectDir.resolve(pom.getSourcePath()).getParent().resolve(Paths.get("src", "test", "resources")),
- ctx, parserInputProvider, ".properties", ".xml", ".yml", ".yaml");
- }
-
-
-}
\ No newline at end of file
diff --git a/headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/gradle/GradleIJavaProjectParserTest.java b/headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/gradle/GradleIJavaProjectParserTest.java
new file mode 100644
index 000000000..4682a25d6
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/gradle/GradleIJavaProjectParserTest.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2023 VMware, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.springframework.ide.vscode.commons.rewrite.gradle;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Test;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.SourceFile;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.java.marker.JavaSourceSet;
+import org.openrewrite.java.tree.J;
+import org.openrewrite.java.tree.JavaSourceFile;
+import org.openrewrite.properties.tree.Properties;
+import org.openrewrite.text.PlainText;
+import org.openrewrite.yaml.tree.Yaml;
+import org.springframework.ide.vscode.commons.gradle.GradleCore;
+import org.springframework.ide.vscode.commons.gradle.GradleJavaProject;
+import org.springframework.ide.vscode.commons.java.IJavaProject;
+import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
+
+public class GradleIJavaProjectParserTest {
+
+ @Test
+ void testSingleGroovy() throws Exception {
+ URL resource = getClass().getResource("/test-projects/example-gradle-groovy");
+ Path testProjectPath = Paths.get(resource.toURI());
+
+ IJavaProject jp = GradleJavaProject.create(null, GradleCore.getDefault(), testProjectPath.resolve("build.gradle").toFile(), null);
+
+ GradleIJavaProjectParser parser = new GradleIJavaProjectParser(jp, JavaParser.fromJavaVersion(), null);
+
+ List sources = parser.parse(Paths.get(jp.getLocationUri()), new InMemoryExecutionContext(t -> {
+ throw new RuntimeException(t);
+ }));
+
+ assertEquals(9, sources.size());
+
+ // java sources
+ assertEquals(2, sources.stream().filter(J.CompilationUnit.class::isInstance).collect(Collectors.toList()).size());
+
+ // java sources from main
+ assertEquals(1, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
+ String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
+ return ProjectParser.MAIN.equals(sourceSetName);
+ }).collect(Collectors.toList()).size());
+
+ // java sources from test
+ assertEquals(1, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
+ String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
+ return ProjectParser.TEST.equals(sourceSetName);
+ }).collect(Collectors.toList()).size());
+
+ // properties files
+ assertEquals(1, sources.stream().filter(Properties.File.class::isInstance).collect(Collectors.toList()).size());
+
+ // application properties
+ assertEquals(1, sources.stream().filter(Properties.File.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().equals("application.properties")).collect(Collectors.toList()).size());
+
+ // yaml files
+ assertEquals(2, sources.stream().filter(Yaml.Documents.class::isInstance).collect(Collectors.toList()).size());
+
+ // application yaml
+ assertEquals(2, sources.stream().filter(Yaml.Documents.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().equals("application.yml")).collect(Collectors.toList()).size());
+
+ // plain text files
+ assertEquals(3, sources.stream().filter(PlainText.class::isInstance).collect(Collectors.toList()).size());
+
+ // .factories files
+ assertEquals(3, sources.stream().filter(PlainText.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().endsWith(".factories")).collect(Collectors.toList()).size());
+
+
+ }
+
+}
diff --git a/headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/maven/MavenProjectParserTest.java b/headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/maven/MavenIJavaProjectParserTest.java
similarity index 67%
rename from headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/maven/MavenProjectParserTest.java
rename to headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/maven/MavenIJavaProjectParserTest.java
index 5db1b4d4d..6b9aba4ec 100644
--- a/headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/maven/MavenProjectParserTest.java
+++ b/headless-services/commons/commons-rewrite/src/test/java/org/springframework/ide/vscode/commons/rewrite/maven/MavenIJavaProjectParserTest.java
@@ -12,10 +12,8 @@ package org.springframework.ide.vscode.commons.rewrite.maven;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -29,25 +27,41 @@ import org.openrewrite.maven.MavenParser;
import org.openrewrite.properties.tree.Properties;
import org.openrewrite.text.PlainText;
import org.openrewrite.yaml.tree.Yaml;
+import org.springframework.ide.vscode.commons.java.IJavaProject;
+import org.springframework.ide.vscode.commons.javadoc.JavaDocProviders;
+import org.springframework.ide.vscode.commons.maven.MavenBuilder;
+import org.springframework.ide.vscode.commons.maven.MavenCore;
+import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
+import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
+
+public class MavenIJavaProjectParserTest {
+
+ private static IJavaProject createProject(String name) throws Exception {
+ Path projectPath = Paths.get(MavenIJavaProjectParserTest.class.getResource("/test-projects/" + name).toURI());
+
+ MavenBuilder.newBuilder(projectPath).clean().pack().skipTests().execute();
+ return MavenJavaProject.create(null, MavenCore.getDefault(),
+ projectPath.resolve(MavenCore.POM_XML).toFile(), (uri, cpe) -> JavaDocProviders.createFor(cpe));
+ }
-public class MavenProjectParserTest {
@Test
void parseResources() throws Exception {
- URL resource = getClass().getResource("/test-projects/test-maven-project-parser");
- Path testProjectPath = Paths.get(resource.toURI());
+ IJavaProject jp = createProject("test-maven-project-parser");
+ Path testProjectPath = Paths.get(jp.getLocationUri());
+
MavenParser.Builder mavenParserBuilder = MavenParser.builder()
.mavenConfig(testProjectPath.resolve(".mvn/maven.config"));
-
- MavenProjectParser parser = new MavenProjectParser(mavenParserBuilder, JavaParser.fromJavaVersion(), new InMemoryExecutionContext(t -> {
+
+ MavenIJavaProjectParser parser = new MavenIJavaProjectParser(jp, JavaParser.fromJavaVersion(), null, mavenParserBuilder);
+
+ List sources = parser.parse(testProjectPath, new InMemoryExecutionContext(t -> {
if (t instanceof Error) {
throw new RuntimeException(t);
};
- }), null);
+ }));
- List sources = parser.parse(testProjectPath, Collections.emptyList());
-
- assertEquals(12, sources.size());
+ assertEquals(13, sources.size());
// java sources
assertEquals(6, sources.stream().filter(JavaSourceFile.class::isInstance).collect(Collectors.toList()).size());
@@ -55,13 +69,13 @@ public class MavenProjectParserTest {
// java sources from main
assertEquals(5, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
- return MavenProjectParser.MAIN.equals(sourceSetName);
+ return ProjectParser.MAIN.equals(sourceSetName);
}).collect(Collectors.toList()).size());
// java sources from test
assertEquals(1, sources.stream().filter(JavaSourceFile.class::isInstance).map(JavaSourceFile.class::cast).filter(j -> {
String sourceSetName = j.getMarkers().findFirst(JavaSourceSet.class).map(js -> js.getName()).orElse(null);
- return MavenProjectParser.TEST.equals(sourceSetName);
+ return ProjectParser.TEST.equals(sourceSetName);
}).collect(Collectors.toList()).size());
// properties files
@@ -77,10 +91,10 @@ public class MavenProjectParserTest {
assertEquals(2, sources.stream().filter(Yaml.Documents.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().equals("application.yml")).collect(Collectors.toList()).size());
// plain text files
- assertEquals(2, sources.stream().filter(PlainText.class::isInstance).collect(Collectors.toList()).size());
+ assertEquals(3, sources.stream().filter(PlainText.class::isInstance).collect(Collectors.toList()).size());
// .factories files
- assertEquals(2, sources.stream().filter(PlainText.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().endsWith(".factories")).collect(Collectors.toList()).size());
+ assertEquals(3, sources.stream().filter(PlainText.class::isInstance).filter(f -> f.getSourcePath().getFileName().toString().endsWith(".factories")).collect(Collectors.toList()).size());
}
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/.gitignore b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/.gitignore
new file mode 100644
index 000000000..c2065bc26
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/.gitignore
@@ -0,0 +1,37 @@
+HELP.md
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/build.gradle b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/build.gradle
new file mode 100644
index 000000000..d1344e837
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/build.gradle
@@ -0,0 +1,23 @@
+plugins {
+ id 'java'
+ id 'org.springframework.boot' version '3.0.7'
+ id 'io.spring.dependency-management' version '1.1.0'
+}
+
+group = 'com.example'
+version = '0.0.1-SNAPSHOT'
+sourceCompatibility = '17'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation 'org.springframework.boot:spring-boot-starter-actuator'
+ implementation 'org.springframework.boot:spring-boot-starter-web'
+ testImplementation 'org.springframework.boot:spring-boot-starter-test'
+}
+
+tasks.named('test') {
+ useJUnitPlatform()
+}
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradle/wrapper/gradle-wrapper.jar b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..249e5832f
Binary files /dev/null and b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradle/wrapper/gradle-wrapper.properties b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..774fae876
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradlew b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradlew
new file mode 100644
index 000000000..a69d9cb6c
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradlew
@@ -0,0 +1,240 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original 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.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradlew.bat b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradlew.bat
new file mode 100644
index 000000000..53a6b238d
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/gradlew.bat
@@ -0,0 +1,91 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/settings.gradle b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/settings.gradle
new file mode 100644
index 000000000..094e8e578
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'example-gradle-groovy'
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/java/com/example/demo/ExampleGradleGroovyApplication.java b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/java/com/example/demo/ExampleGradleGroovyApplication.java
new file mode 100644
index 000000000..50d1d663e
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/java/com/example/demo/ExampleGradleGroovyApplication.java
@@ -0,0 +1,13 @@
+package com.example.demo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class ExampleGradleGroovyApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ExampleGradleGroovyApplication.class, args);
+ }
+
+}
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/application.properties b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/application.properties
new file mode 100644
index 000000000..73b813d27
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+test-map.test-list-object.string-list[0]=not-a-color
+test-map.test-list-object.string-list[1]=RED
+test-map.test-list-object.string-list[2]=GREEN
+test-map.some-key.list[0]=something
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/application.yml b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/application.yml
new file mode 100644
index 000000000..5697ab735
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/application.yml
@@ -0,0 +1,2 @@
+server:
+ port: 6574
\ No newline at end of file
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/more.factories b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/more.factories
new file mode 100644
index 000000000..e69de29bb
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/spring.factories b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/main/resources/spring.factories
new file mode 100644
index 000000000..e69de29bb
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/java/com/example/demo/ExampleGradleGroovyApplicationTests.java b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/java/com/example/demo/ExampleGradleGroovyApplicationTests.java
new file mode 100644
index 000000000..ca0135b8c
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/java/com/example/demo/ExampleGradleGroovyApplicationTests.java
@@ -0,0 +1,13 @@
+package com.example.demo;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest
+class ExampleGradleGroovyApplicationTests {
+
+ @Test
+ void contextLoads() {
+ }
+
+}
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/resources/application.yml b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/resources/application.yml
new file mode 100644
index 000000000..57d009930
--- /dev/null
+++ b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/resources/application.yml
@@ -0,0 +1,2 @@
+server:
+ port: 3243
\ No newline at end of file
diff --git a/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/resources/spring.factories b/headless-services/commons/commons-rewrite/src/test/resources/test-projects/example-gradle-groovy/src/test/resources/spring.factories
new file mode 100644
index 000000000..e69de29bb
diff --git a/headless-services/commons/pom.xml b/headless-services/commons/pom.xml
index e1ec1e3bf..5ddfc1760 100644
--- a/headless-services/commons/pom.xml
+++ b/headless-services/commons/pom.xml
@@ -115,6 +115,7 @@
7.41.0-SNAPSHOT
4.37.0-SNAPSHOT
+ 0.9.0-SNAPSHOT
true
vmware
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java
index fb31f0f4e..1f4b7cf07 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteRecipeRepository.java
@@ -11,7 +11,6 @@
package org.springframework.ide.vscode.boot.java.rewrite;
import java.io.ByteArrayInputStream;
-import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.net.URLClassLoader;
@@ -33,7 +32,6 @@ import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
import org.eclipse.lsp4j.TextDocumentIdentifier;
@@ -59,19 +57,20 @@ import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.ide.vscode.boot.app.BootJavaConfig;
-import org.springframework.ide.vscode.commons.java.IClasspath;
-import org.springframework.ide.vscode.commons.java.IClasspathUtil;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.IndefiniteProgressTask;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.ListenerList;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
+import org.springframework.ide.vscode.commons.protocol.java.ProjectBuild;
import org.springframework.ide.vscode.commons.rewrite.LoadUtils;
import org.springframework.ide.vscode.commons.rewrite.LoadUtils.DurationTypeConverter;
import org.springframework.ide.vscode.commons.rewrite.ORDocUtils;
import org.springframework.ide.vscode.commons.rewrite.config.RecipeCodeActionDescriptor;
import org.springframework.ide.vscode.commons.rewrite.config.StsEnvironment;
-import org.springframework.ide.vscode.commons.rewrite.maven.MavenProjectParser;
+import org.springframework.ide.vscode.commons.rewrite.gradle.GradleIJavaProjectParser;
+import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
+import org.springframework.ide.vscode.commons.rewrite.maven.MavenIJavaProjectParser;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.gson.Gson;
@@ -417,15 +416,15 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
private Optional computeWorkspaceEdit(Recipe r, IJavaProject project, IndefiniteProgressTask progressTask) {
Path absoluteProjectDir = Paths.get(project.getLocationUri());
progressTask.progressEvent("Parsing files...");
- MavenProjectParser projectParser = createRewriteMavenParser(absoluteProjectDir,
- new InMemoryExecutionContext(), p -> {
+ ProjectParser projectParser = createRewriteProjectParser(project,
+ p -> {
TextDocument doc = server.getTextDocumentService().getLatestSnapshot(p.toUri().toASCIIString());
if (doc != null) {
return new Parser.Input(p, () -> new ByteArrayInputStream(doc.get().getBytes()));
}
return null;
});
- List sources = projectParser.parse(absoluteProjectDir, getClasspathEntries(project));
+ List sources = projectParser.parse(absoluteProjectDir, new InMemoryExecutionContext());
progressTask.progressEvent("Computing changes...");
RecipeRun reciperun = r.run(sources, new InMemoryExecutionContext(e -> log.error("Recipe execution failed", e)));
List results = reciperun.getResults();
@@ -447,32 +446,20 @@ public class RewriteRecipeRepository implements ApplicationContextAware {
return Collections.emptyList();
}
- private static MavenProjectParser createRewriteMavenParser(Path absoluteProjectDir, ExecutionContext context, Function inputProvider) {
- MavenParser.Builder mavenParserBuilder = MavenParser.builder()
- .mavenConfig(absoluteProjectDir.resolve(".mvn/maven.config"));
-
- MavenProjectParser mavenProjectParser = new MavenProjectParser(
- mavenParserBuilder,
- JavaParser.fromJavaVersion(),
- context,
- inputProvider
- );
- return mavenProjectParser;
+ private static ProjectParser createRewriteProjectParser(IJavaProject jp, Function inputProvider) {
+ switch (jp.getProjectBuild().getType()) {
+ case ProjectBuild.MAVEN_PROJECT_TYPE:
+ Path absoluteProjectDir = Paths.get(jp.getLocationUri()).toAbsolutePath();
+ MavenParser.Builder mavenParserBuilder = MavenParser.builder()
+ .mavenConfig(absoluteProjectDir.resolve(".mvn/maven.config"));
+ return new MavenIJavaProjectParser(jp, JavaParser.fromJavaVersion(), inputProvider, mavenParserBuilder);
+ case ProjectBuild.GRADLE_PROJECT_TYPE:
+ return new GradleIJavaProjectParser(jp, JavaParser.fromJavaVersion(), inputProvider);
+ default:
+ throw new IllegalStateException("The project is neither Maven nor Gradle!");
+ }
}
- private static List getClasspathEntries(IJavaProject project) {
- if (project == null) {
- return List.of();
- } else {
- IClasspath classpath = project.getClasspath();
- Stream classpathEntries = IClasspathUtil.getAllBinaryRoots(classpath).stream();
- return classpathEntries
- .filter(file -> file.exists())
- .filter(file -> file.getName().endsWith(".jar"))
- .map(file -> file.getAbsoluteFile().toPath()).collect(Collectors.toList());
- }
- }
-
public void onRecipesLoaded(Consumer l) {
loadListeners.add(l);
}
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java
index 833e7eefb..c2b9d04aa 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/RewriteReconciler.java
@@ -54,7 +54,7 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
-import org.springframework.ide.vscode.commons.rewrite.maven.MavenProjectParser;
+import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
@@ -165,8 +165,8 @@ public class RewriteReconciler implements JavaReconciler {
// Pass in source sets created from classpath. (Perhaps it is a good idea to have separate classpath and parsers for test and main, TBD)
// Perhaps it is even better to create empty classpath java source sets as reconcile step seem to only need name of the java source set
// Usually java source set classpath is required to figure out how to organize imports for sources
- JavaSourceSet mainJavaSourceSet = JavaSourceSet.build(MavenProjectParser.MAIN, classpath, null, false);
- JavaSourceSet testJavaSourceSet = new JavaSourceSet(Tree.randomId(), MavenProjectParser.TEST, mainJavaSourceSet.getClasspath());
+ JavaSourceSet mainJavaSourceSet = JavaSourceSet.build(ProjectParser.MAIN, classpath, null, false);
+ JavaSourceSet testJavaSourceSet = new JavaSourceSet(Tree.randomId(), ProjectParser.TEST, mainJavaSourceSet.getClasspath());
allProblems.putAll(doReconcile(project, mainSources, javaParser, mainJavaSourceSet, incrementProgress));
allProblems.putAll(doReconcile(project, testSources, javaParser, testJavaSourceSet, incrementProgress));
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java
index 89d96fec8..b6ec83263 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/rewrite/reconcile/AutowiredFieldIntoConstructorParameterCodeAction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2022 VMware, Inc.
+ * Copyright (c) 2022, 2023 VMware, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -43,7 +43,7 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixAssistMarker;
import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
import org.springframework.ide.vscode.commons.rewrite.java.JavaMarkerVisitor;
import org.springframework.ide.vscode.commons.rewrite.java.ORAstUtils;
-import org.springframework.ide.vscode.commons.rewrite.maven.MavenProjectParser;
+import org.springframework.ide.vscode.commons.rewrite.java.ProjectParser;
public class AutowiredFieldIntoConstructorParameterCodeAction implements RecipeCodeActionDescriptor {
@@ -58,7 +58,7 @@ public class AutowiredFieldIntoConstructorParameterCodeAction implements RecipeC
@Override
public CompilationUnit visitCompilationUnit(CompilationUnit cu, ExecutionContext p) {
JavaSourceSet sourceSet = cu.getMarkers().findFirst(JavaSourceSet.class).orElse(null);
- if (sourceSet != null && MavenProjectParser.TEST.equals(sourceSet.getName())) {
+ if (sourceSet != null && ProjectParser.TEST.equals(sourceSet.getName())) {
return cu;
}
return super.visitCompilationUnit(cu, p);
diff --git a/vscode-extensions/vscode-spring-boot/package.json b/vscode-extensions/vscode-spring-boot/package.json
index 77f69949d..a17949fb3 100644
--- a/vscode-extensions/vscode-spring-boot/package.json
+++ b/vscode-extensions/vscode-spring-boot/package.json
@@ -76,24 +76,24 @@
"menus": {
"editor/context": [
{
- "when": "resourceFilename == pom.xml",
+ "when": "resourceFilename == pom.xml || resourceFilename == build.gradle",
"command": "vscode-spring-boot.rewrite.list.refactorings",
"group": "SpringBoot"
},
{
- "when": "resourceFilename == pom.xml",
+ "when": "resourceFilename == pom.xml || resourceFilename == build.gradle",
"command": "vscode-spring-boot.rewrite.list.boot-upgrades",
"group": "SpringBoot"
}
],
"explorer/context": [
{
- "when": "resourceFilename == pom.xml && config.boot-java.rewrite.refactorings.on == true",
+ "when": "(resourceFilename == pom.xml || resourceFilename == build.gradle) && config.boot-java.rewrite.refactorings.on == true",
"command": "vscode-spring-boot.rewrite.list.refactorings",
"group": "SpringBoot"
},
{
- "when": "resourceFilename == pom.xml && config.boot-java.rewrite.refactorings.on == true",
+ "when": "(resourceFilename == pom.xml || resourceFilename == build.gradle) && config.boot-java.rewrite.refactorings.on == true",
"command": "vscode-spring-boot.rewrite.list.boot-upgrades",
"group": "SpringBoot"
}