From 5ea5b5cb2888cd89f98329cf7cf415c433b5036b Mon Sep 17 00:00:00 2001 From: Alex Boyko Date: Tue, 25 Oct 2016 17:15:25 -0400 Subject: [PATCH] Integrate commons-maven to eliminate classpath text file based solution --- .gitignore | 41 +- .../application-properties-metadata/pom.xml | 148 +++---- .../properties/metadata/PropertiesLoader.java | 298 +++++++------- .../metadata/PropertiesIndexTest.java | 172 +++++--- .../.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 .../mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 0 .../java/com/example/Demo1Application.java | 0 .../main/java/com/example/DemoProperties.java | 0 .../src/main/java/com/example/RestApi.java | 0 .../src/main/resources/application.properties | 0 .../com/example/Demo1ApplicationTests.java | 0 .../ide/vscode/commons/java/IClasspath.java | 47 ++- .../commons/commons-language-server/pom.xml | 163 ++++---- .../java/DefaultJavaProjectFinder.java | 73 ++-- .../java/IJavaProjectFinderStrategy.java | 27 ++ .../java/JavaProjectFinder.java | 20 +- ...rojectWithClasspathFileFinderStrategy.java | 44 +++ .../java/MavenProjectFinderStrategy.java | 52 +++ .../commons/commons-maven/pom.xml | 38 +- .../ide/vscode/commons/maven/MavenCore.java | 371 ++++++++++-------- .../commons/maven/java/MavenJavaProject.java | 66 ++++ .../maven/java/MavenProjectClasspath.java | 54 +++ .../java/classpathfile/FileClasspath.java | 42 ++ .../JavaProjectWithClasspathFile.java | 167 ++++---- .../commons/maven/DependencyTreeTest.java | 41 +- .../main/java/com/example/DemoProperties.java | 30 -- .../src/main/java/com/example/RestApi.java | 16 - .../.gitignore | 24 ++ .../.mvn/wrapper/maven-wrapper.jar | Bin .../.mvn/wrapper/maven-wrapper.properties | 0 .../mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 27 +- ...tProjectWithClasspathFileApplication.java} | 4 +- .../src/main/resources/application.properties | 0 ...ectWithClasspathFileApplicationTests.java} | 2 +- .../ide/vscode/commons/util/FileUtils.java | 42 ++ .../testharness/TestProjectHarness.java | 78 ---- vscode-extensions/commons/pom.xml | 149 +++---- .../commons/project-test-harness/.gitignore | 2 + .../.settings/org.eclipse.jdt.core.prefs | 5 + .../.settings/org.eclipse.m2e.core.prefs | 4 + .../commons/project-test-harness/pom.xml | 20 + .../ide/vscode/project/harness/Projects.java | 50 +++ 47 files changed, 1315 insertions(+), 1002 deletions(-) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/.mvn/wrapper/maven-wrapper.jar (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/.mvn/wrapper/maven-wrapper.properties (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/mvnw (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/mvnw.cmd (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/pom.xml (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/src/main/java/com/example/Demo1Application.java (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/src/main/java/com/example/DemoProperties.java (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/src/main/java/com/example/RestApi.java (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/src/main/resources/application.properties (100%) rename vscode-extensions/commons/application-properties-metadata/src/test/resources/{demo-1 => custom-properties-boot-project}/src/test/java/com/example/Demo1ApplicationTests.java (100%) create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/IJavaProjectFinderStrategy.java create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectWithClasspathFileFinderStrategy.java create mode 100644 vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/MavenProjectFinderStrategy.java create mode 100644 vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java create mode 100644 vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java create mode 100644 vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile/FileClasspath.java rename vscode-extensions/commons/{commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java => commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile}/JavaProjectWithClasspathFile.java (61%) delete mode 100644 vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java delete mode 100644 vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/RestApi.java create mode 100644 vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.gitignore rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1 => empty-boot-project-with-classpath-file}/.mvn/wrapper/maven-wrapper.jar (100%) rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1 => empty-boot-project-with-classpath-file}/.mvn/wrapper/maven-wrapper.properties (100%) rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1 => empty-boot-project-with-classpath-file}/mvnw (100%) rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1 => empty-boot-project-with-classpath-file}/mvnw.cmd (100%) rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1 => empty-boot-project-with-classpath-file}/pom.xml (70%) rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1/src/main/java/com/example/Demo1Application.java => empty-boot-project-with-classpath-file/src/main/java/com/example/EmptyBootProjectWithClasspathFileApplication.java} (59%) rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1 => empty-boot-project-with-classpath-file}/src/main/resources/application.properties (100%) rename vscode-extensions/commons/commons-maven/src/test/resources/{demo-1/src/test/java/com/example/Demo1ApplicationTests.java => empty-boot-project-with-classpath-file/src/test/java/com/example/EmptyBootProjectWithClasspathFileApplicationTests.java} (81%) create mode 100644 vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/FileUtils.java delete mode 100644 vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/TestProjectHarness.java create mode 100644 vscode-extensions/commons/project-test-harness/.gitignore create mode 100644 vscode-extensions/commons/project-test-harness/.settings/org.eclipse.jdt.core.prefs create mode 100644 vscode-extensions/commons/project-test-harness/.settings/org.eclipse.m2e.core.prefs create mode 100644 vscode-extensions/commons/project-test-harness/pom.xml create mode 100644 vscode-extensions/commons/project-test-harness/src/main/java/org/springframework/ide/vscode/project/harness/Projects.java diff --git a/.gitignore b/.gitignore index b4893d734..b52ad7292 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,22 @@ -*.class - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.ear -# Exceptions -!**/.mvn/wrapper/maven-wrapper.jar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -target/ -*.log - -# Mac OSX aux files -.DS_Store +*.class +**/.classpath + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear +# Exceptions +!**/.mvn/wrapper/maven-wrapper.jar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +target/ +*.log + +# Mac OSX aux files +.DS_Store **/.DS_Store \ No newline at end of file diff --git a/vscode-extensions/commons/application-properties-metadata/pom.xml b/vscode-extensions/commons/application-properties-metadata/pom.xml index 3fae23258..904d280ab 100644 --- a/vscode-extensions/commons/application-properties-metadata/pom.xml +++ b/vscode-extensions/commons/application-properties-metadata/pom.xml @@ -1,75 +1,75 @@ - - 4.0.0 - - org.springframework.ide.vscode - commons-parent - 0.0.1-SNAPSHOT - ../pom.xml - - application-properties-metadata - Builds metadata for boot application properties based on project's classpath contents - - - - project-repo - file://${project.basedir}/repo - - - - - - - org.springframework.ide.eclipse - org.json - 1.0 - - - - com.google.guava - guava - 18.0 - - - - javax.inject - javax.inject - 1 - - - - - io.projectreactor - reactor-core - ${reactor-version} - - - - org.springframework.ide.vscode - commons-util - ${project.version} - - - org.springframework.ide.vscode - commons-yaml - ${project.version} - - - org.springframework.ide.vscode - commons-java - ${project.version} - - - org.springframework.ide.vscode - commons-language-server - ${project.version} - - - org.springframework.ide.vscode - language-server-test-harness - ${project.version} - test - - - + + 4.0.0 + + org.springframework.ide.vscode + commons-parent + 0.0.1-SNAPSHOT + ../pom.xml + + application-properties-metadata + Builds metadata for boot application properties based on project's classpath contents + + + + project-repo + file://${project.basedir}/repo + + + + + + + org.springframework.ide.eclipse + org.json + 1.0 + + + + com.google.guava + guava + 18.0 + + + + javax.inject + javax.inject + 1 + + + + + io.projectreactor + reactor-core + ${reactor-version} + + + + org.springframework.ide.vscode + commons-util + ${project.version} + + + org.springframework.ide.vscode + commons-yaml + ${project.version} + + + org.springframework.ide.vscode + commons-java + ${project.version} + + + org.springframework.ide.vscode + commons-language-server + ${project.version} + + + org.springframework.ide.vscode + project-test-harness + ${project.version} + test + + + \ No newline at end of file diff --git a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/PropertiesLoader.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/PropertiesLoader.java index 166691fb9..01495e8e0 100644 --- a/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/PropertiesLoader.java +++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/PropertiesLoader.java @@ -1,166 +1,132 @@ -package org.springframework.ide.vscode.application.properties.metadata; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.jar.JarFile; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; - -import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty; -import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository; -import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepositoryJsonBuilder; -import org.springframework.ide.vscode.commons.java.IClasspath; - -public class PropertiesLoader { - - private static final String MAIN_SPRING_CONFIGURATION_METADATA_JSON = "META-INF/spring-configuration-metadata.json"; - - public static final String ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON = "META-INF/additional-spring-configuration-metadata.json"; - - /** - * The default classpath location for config metadata loaded when scanning .jar files on the classpath. - */ - public static final String[] JAR_META_DATA_LOCATIONS = { - MAIN_SPRING_CONFIGURATION_METADATA_JSON - //Not scanning 'additional' metadata because it integrated already in the main data. - }; - - /** - * The default classpath location for config metadata loaded when scanning project output folders. - */ - public static final String[] PROJECT_META_DATA_LOCATIONS = { - MAIN_SPRING_CONFIGURATION_METADATA_JSON, - ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON - }; - - private static final Logger LOG = Logger.getLogger(PropertiesLoader.class.getName()); - - private ConfigurationMetadataRepositoryJsonBuilder builder = ConfigurationMetadataRepositoryJsonBuilder.create(); - - public ConfigurationMetadataRepository load(IClasspath classPath) { - Path path = classPath.getPath(); - return load(path.resolve("classpath.txt"), path.resolve("target/classes")); - } - - private ConfigurationMetadataRepository load(Path classPathFilePath, Path outputFolderPath) { - loadFromClasspath(classPathFilePath); - loadFromOutputFolder(outputFolderPath); - ConfigurationMetadataRepository repository = builder.build(); - return repository; - } - - private void loadFromClasspath(Path classPathFilePath) { - if (classPathFilePath != null && Files.exists(classPathFilePath)) { - readClassPathFile(classPathFilePath).ifPresent(classPathSet -> { - classPathSet.stream().forEach(this::loadFromJar); - }); - } - } - - private Optional> readClassPathFile(Path classPathFilePath){ - try { - InputStream in = Files.newInputStream(classPathFilePath); - String text = new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining()); - Path dir = classPathFilePath.getParent(); - return Optional.of(Arrays.stream(text.split(File.pathSeparator)).map(dir::resolve).collect(Collectors.toSet())); - } catch (IOException e) { - LOG.log(Level.SEVERE, "Failed to read classpath text file", e); - return Optional.empty(); - } - } - - private void loadFromOutputFolder(Path outputFolderPath) { - if (outputFolderPath != null && Files.exists(outputFolderPath)) { - Arrays.stream(PROJECT_META_DATA_LOCATIONS).forEach(mdLoc -> { - loadFromJsonFile(outputFolderPath.resolve(mdLoc)); - }); - } - } - - private void loadFromJsonFile(Path mdf) { - if (Files.exists(mdf)) { - InputStream is = null; - try { - is = Files.newInputStream(mdf); - loadFromInputStream(mdf, is); - } catch (Exception e) { - LOG.log(Level.SEVERE, "Error loading file '" + mdf + "'", e); - } finally { - if (is!=null) { - try { - is.close(); - } catch (IOException e) { - //ignore - } - } - } - } - } - - private void loadFromJar(Path f) { - JarFile jarFile = null; - try { - jarFile = new JarFile(f.toFile()); - //jarDump(jarFile); - for (String loc : JAR_META_DATA_LOCATIONS) { - ZipEntry e = jarFile.getEntry(loc); - if (e!=null) { - loadFrom(jarFile, e); - } - } - } catch (Throwable e) { - LOG.log(Level.SEVERE, "Error loading JAR file", e); - } finally { - if (jarFile!=null) { - try { - jarFile.close(); - } catch (IOException e) { - } - } - } - } - - - private void loadFrom(JarFile jarFile, ZipEntry ze) { - InputStream is = null; - try { - is = jarFile.getInputStream(ze); - loadFromInputStream(jarFile.getName()+"["+ze.getName()+"]", is); - } catch (Throwable e) { - LOG.log(Level.SEVERE, "Error loading JAR file", e); - } finally { - if (is!=null) { - try { - is.close(); - } catch (IOException e) { - } - } - } - } - - private void loadFromInputStream(Object origin, InputStream is) throws IOException { - builder.withJsonResource(origin, is); - } - - public static void main(String[] args) { - if (args.length > 0) { - Path projectPath = Paths.get(args[0]); - ConfigurationMetadataRepository repo = new PropertiesLoader().load(() -> projectPath); - Map allProperties = repo.getAllProperties(); - allProperties.keySet().forEach(System.out::println); - } - } - -} +package org.springframework.ide.vscode.application.properties.metadata; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.jar.JarFile; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.ZipEntry; + +import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository; +import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepositoryJsonBuilder; +import org.springframework.ide.vscode.commons.java.IClasspath; + +public class PropertiesLoader { + + private static final String MAIN_SPRING_CONFIGURATION_METADATA_JSON = "META-INF/spring-configuration-metadata.json"; + + public static final String ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON = "META-INF/additional-spring-configuration-metadata.json"; + + /** + * The default classpath location for config metadata loaded when scanning .jar files on the classpath. + */ + public static final String[] JAR_META_DATA_LOCATIONS = { + MAIN_SPRING_CONFIGURATION_METADATA_JSON + //Not scanning 'additional' metadata because it integrated already in the main data. + }; + + /** + * The default classpath location for config metadata loaded when scanning project output folders. + */ + public static final String[] PROJECT_META_DATA_LOCATIONS = { + MAIN_SPRING_CONFIGURATION_METADATA_JSON, + ADDITIONAL_SPRING_CONFIGURATION_METADATA_JSON + }; + + private static final Logger LOG = Logger.getLogger(PropertiesLoader.class.getName()); + + private ConfigurationMetadataRepositoryJsonBuilder builder = ConfigurationMetadataRepositoryJsonBuilder.create(); + + public ConfigurationMetadataRepository load(IClasspath classPath) { + try { + classPath.getClasspathEntries().forEach(entry -> { + if (entry.toFile().isDirectory()) { + loadFromOutputFolder(entry); + } else { + loadFromJar(entry); + } + }); + } catch (Exception e) { + LOG.log(Level.SEVERE, "Failed to retrieve classpath", e); + } + ConfigurationMetadataRepository repository = builder.build(); + return repository; + } + + private void loadFromOutputFolder(Path outputFolderPath) { + if (outputFolderPath != null && Files.exists(outputFolderPath)) { + Arrays.stream(PROJECT_META_DATA_LOCATIONS).forEach(mdLoc -> { + loadFromJsonFile(outputFolderPath.resolve(mdLoc)); + }); + } + } + + private void loadFromJsonFile(Path mdf) { + if (Files.exists(mdf)) { + InputStream is = null; + try { + is = Files.newInputStream(mdf); + loadFromInputStream(mdf, is); + } catch (Exception e) { + LOG.log(Level.SEVERE, "Error loading file '" + mdf + "'", e); + } finally { + if (is!=null) { + try { + is.close(); + } catch (IOException e) { + //ignore + } + } + } + } + } + + private void loadFromJar(Path f) { + JarFile jarFile = null; + try { + jarFile = new JarFile(f.toFile()); + //jarDump(jarFile); + for (String loc : JAR_META_DATA_LOCATIONS) { + ZipEntry e = jarFile.getEntry(loc); + if (e!=null) { + loadFrom(jarFile, e); + } + } + } catch (Throwable e) { + LOG.log(Level.SEVERE, "Error loading JAR file", e); + } finally { + if (jarFile!=null) { + try { + jarFile.close(); + } catch (IOException e) { + } + } + } + } + + + private void loadFrom(JarFile jarFile, ZipEntry ze) { + InputStream is = null; + try { + is = jarFile.getInputStream(ze); + loadFromInputStream(jarFile.getName()+"["+ze.getName()+"]", is); + } catch (Throwable e) { + LOG.log(Level.SEVERE, "Error loading JAR file", e); + } finally { + if (is!=null) { + try { + is.close(); + } catch (IOException e) { + } + } + } + } + + private void loadFromInputStream(Object origin, InputStream is) throws IOException { + builder.withJsonResource(origin, is); + } + +} diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/java/org/springframework/ide/vscode/boot/properties/metadata/PropertiesIndexTest.java b/vscode-extensions/commons/application-properties-metadata/src/test/java/org/springframework/ide/vscode/boot/properties/metadata/PropertiesIndexTest.java index 2d947d260..a456d4068 100644 --- a/vscode-extensions/commons/application-properties-metadata/src/test/java/org/springframework/ide/vscode/boot/properties/metadata/PropertiesIndexTest.java +++ b/vscode-extensions/commons/application-properties-metadata/src/test/java/org/springframework/ide/vscode/boot/properties/metadata/PropertiesIndexTest.java @@ -1,62 +1,110 @@ -/******************************************************************************* - * Copyright (c) 2016 Pivotal, 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.vscode.boot.properties.metadata; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import org.junit.Test; -import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo; -import org.springframework.ide.vscode.application.properties.metadata.SpringPropertiesIndexManager; -import org.springframework.ide.vscode.application.properties.metadata.ValueProviderRegistry; -import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap; -import org.springframework.ide.vscode.languageserver.testharness.TestProjectHarness; - -/** - * Sanity test the boot properties index - * - * @author Alex Boyko - * - */ -public class PropertiesIndexTest { - - private TestProjectHarness projects = new TestProjectHarness(); - - @Test - public void springStandardPropertyPresent() throws Exception { - SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault()); - FuzzyMap index = indexManager.get(projects.mavenProject("demo-1")); - PropertyInfo propertyInfo = index.get("server.port"); - assertNotNull(propertyInfo); - assertEquals(Integer.class.getName(), propertyInfo.getType()); - assertEquals("port", propertyInfo.getName()); - } - - @Test - public void customPropertyPresent() throws Exception { - SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault()); - FuzzyMap index = indexManager.get(projects.mavenProject("demo-1")); - PropertyInfo propertyInfo = index.get("demo.settings.user"); - assertNotNull(propertyInfo); - assertEquals(String.class.getName(), propertyInfo.getType()); - assertEquals("user", propertyInfo.getName()); - } - - @Test - public void propertyNotPresent() throws Exception { - SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault()); - FuzzyMap index = indexManager.get(projects.mavenProject("demo-1")); - PropertyInfo propertyInfo = index.get("my.server.port"); - assertNull(propertyInfo); - } - -} +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.boot.properties.metadata; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Test; +import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo; +import org.springframework.ide.vscode.application.properties.metadata.SpringPropertiesIndexManager; +import org.springframework.ide.vscode.application.properties.metadata.ValueProviderRegistry; +import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap; +import org.springframework.ide.vscode.commons.maven.MavenCore; +import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject; +import org.springframework.ide.vscode.commons.maven.java.classpathfile.JavaProjectWithClasspathFile; +import org.springframework.ide.vscode.project.harness.Projects; + +/** + * Sanity test the boot properties index + * + * @author Alex Boyko + * + */ +public class PropertiesIndexTest { + + private static final String CUSTOM_PROPERTIES_PROJECT = "custom-properties-boot-project"; + + @Test + public void springStandardPropertyPresent_Maven() throws Exception { + SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager( + ValueProviderRegistry.getDefault()); + MavenJavaProject mavenProject = new MavenJavaProject( + Projects.buildMavenProject(CUSTOM_PROPERTIES_PROJECT).resolve(MavenCore.POM_XML).toFile()); + FuzzyMap index = indexManager.get(mavenProject); + PropertyInfo propertyInfo = index.get("server.port"); + assertNotNull(propertyInfo); + assertEquals(Integer.class.getName(), propertyInfo.getType()); + assertEquals("port", propertyInfo.getName()); + } + + @Test + public void customPropertyPresent_Maven() throws Exception { + SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager( + ValueProviderRegistry.getDefault()); + MavenJavaProject mavenProject = new MavenJavaProject( + Projects.buildMavenProject(CUSTOM_PROPERTIES_PROJECT).resolve(MavenCore.POM_XML).toFile()); + FuzzyMap index = indexManager.get(mavenProject); + PropertyInfo propertyInfo = index.get("demo.settings.user"); + assertNotNull(propertyInfo); + assertEquals(String.class.getName(), propertyInfo.getType()); + assertEquals("user", propertyInfo.getName()); + } + + @Test + public void propertyNotPresent_Maven() throws Exception { + SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager( + ValueProviderRegistry.getDefault()); + MavenJavaProject mavenProject = new MavenJavaProject( + Projects.buildMavenProject(CUSTOM_PROPERTIES_PROJECT).resolve(MavenCore.POM_XML).toFile()); + FuzzyMap index = indexManager.get(mavenProject); + PropertyInfo propertyInfo = index.get("my.server.port"); + assertNull(propertyInfo); + } + + @Test + public void springStandardPropertyPresent_ClasspathFile() throws Exception { + SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager( + ValueProviderRegistry.getDefault()); + JavaProjectWithClasspathFile classpathFileProject = new JavaProjectWithClasspathFile( + Projects.buildMavenProject(CUSTOM_PROPERTIES_PROJECT).resolve(MavenCore.CLASSPATH_TXT).toFile()); + FuzzyMap index = indexManager.get(classpathFileProject); + PropertyInfo propertyInfo = index.get("server.port"); + assertNotNull(propertyInfo); + assertEquals(Integer.class.getName(), propertyInfo.getType()); + assertEquals("port", propertyInfo.getName()); + } + + @Test + public void customPropertyPresent_ClasspathFile() throws Exception { + SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager( + ValueProviderRegistry.getDefault()); + JavaProjectWithClasspathFile classpathFileProject = new JavaProjectWithClasspathFile( + Projects.buildMavenProject(CUSTOM_PROPERTIES_PROJECT).resolve(MavenCore.CLASSPATH_TXT).toFile()); + FuzzyMap index = indexManager.get(classpathFileProject); + PropertyInfo propertyInfo = index.get("demo.settings.user"); + assertNotNull(propertyInfo); + assertEquals(String.class.getName(), propertyInfo.getType()); + assertEquals("user", propertyInfo.getName()); + } + + @Test + public void propertyNotPresent_ClasspathFile() throws Exception { + SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager( + ValueProviderRegistry.getDefault()); + JavaProjectWithClasspathFile classpathFileProject = new JavaProjectWithClasspathFile( + Projects.buildMavenProject(CUSTOM_PROPERTIES_PROJECT).resolve(MavenCore.CLASSPATH_TXT).toFile()); + FuzzyMap index = indexManager.get(classpathFileProject); + PropertyInfo propertyInfo = index.get("my.server.port"); + assertNull(propertyInfo); + } +} diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.jar b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.jar rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/.mvn/wrapper/maven-wrapper.jar diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.properties b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.properties rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/.mvn/wrapper/maven-wrapper.properties diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/mvnw b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/mvnw similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/mvnw rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/mvnw diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/mvnw.cmd b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/mvnw.cmd similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/mvnw.cmd rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/mvnw.cmd diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/pom.xml b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/pom.xml similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/pom.xml rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/pom.xml diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/java/com/example/Demo1Application.java similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/java/com/example/Demo1Application.java diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/java/com/example/DemoProperties.java similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/java/com/example/DemoProperties.java diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/java/com/example/RestApi.java b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/java/com/example/RestApi.java similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/java/com/example/RestApi.java rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/java/com/example/RestApi.java diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/resources/application.properties b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/resources/application.properties similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/main/resources/application.properties rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/main/resources/application.properties diff --git a/vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java b/vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/test/java/com/example/Demo1ApplicationTests.java similarity index 100% rename from vscode-extensions/commons/application-properties-metadata/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java rename to vscode-extensions/commons/application-properties-metadata/src/test/resources/custom-properties-boot-project/src/test/java/com/example/Demo1ApplicationTests.java diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java index 3575fa11c..82db92edb 100644 --- a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java +++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/IClasspath.java @@ -1,14 +1,33 @@ -package org.springframework.ide.vscode.commons.java; - -import java.nio.file.Path; - -public interface IClasspath { - - /** - * Deprecated: Remove this. We should expose here information about classpath as a list of entries. Not - * depend on where it is read from. - */ - @Deprecated - Path getPath(); - -} +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.java; + +import java.nio.file.Path; +import java.util.Collection; + +/** + * Classpath for a Java artifact + * + * @author Kris De Volder + * @author Alex Boyko + * + */ +public interface IClasspath { + + /** + * Classpath entries paths + * + * @return collection of classpath entries in a form file/folder paths + * @throws Exception + */ + Collection getClasspathEntries() throws Exception; + +} diff --git a/vscode-extensions/commons/commons-language-server/pom.xml b/vscode-extensions/commons/commons-language-server/pom.xml index 2c47c1de6..f1d920758 100644 --- a/vscode-extensions/commons/commons-language-server/pom.xml +++ b/vscode-extensions/commons/commons-language-server/pom.xml @@ -1,79 +1,84 @@ - - 4.0.0 - commons-language-server - commons-language-server - Shared utilities for building vscode language servers in Java - - - org.springframework.ide.vscode - commons-parent - 0.0.1-SNAPSHOT - ../pom.xml - - - - - org.springframework.ide.vscode - commons-util - ${project.version} - - - org.springframework.ide.vscode - commons-java - ${project.version} - - - - io.typefox.lsapi - io.typefox.lsapi - ${lsapi-version} - - - io.typefox.lsapi - io.typefox.lsapi.services - ${lsapi-version} - - - io.typefox.lsapi - io.typefox.lsapi.annotations - ${lsapi-version} - - - - com.fasterxml.jackson.core - jackson-core - ${jackson-2-version} - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson-2-version} - - - com.fasterxml.jackson.core - jackson-databind - ${jackson-2-version} - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - ${jackson-2-version} - - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - ${jackson-2-version} - - - - - org.springframework.ide.vscode - language-server-test-harness - ${project.version} - test - - - - - + + 4.0.0 + commons-language-server + commons-language-server + Shared utilities for building vscode language servers in Java + + + org.springframework.ide.vscode + commons-parent + 0.0.1-SNAPSHOT + ../pom.xml + + + + + org.springframework.ide.vscode + commons-util + ${project.version} + + + org.springframework.ide.vscode + commons-java + ${project.version} + + + org.springframework.ide.vscode + commons-maven + ${project.version} + + + + io.typefox.lsapi + io.typefox.lsapi + ${lsapi-version} + + + io.typefox.lsapi + io.typefox.lsapi.services + ${lsapi-version} + + + io.typefox.lsapi + io.typefox.lsapi.annotations + ${lsapi-version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson-2-version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson-2-version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-2-version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + ${jackson-2-version} + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + ${jackson-2-version} + + + + + org.springframework.ide.vscode + language-server-test-harness + ${project.version} + test + + + + + diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/DefaultJavaProjectFinder.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/DefaultJavaProjectFinder.java index f940a628f..2a059a9c1 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/DefaultJavaProjectFinder.java +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/DefaultJavaProjectFinder.java @@ -1,49 +1,24 @@ -package org.springframework.ide.vscode.commons.languageserver.java; - -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; - -import org.springframework.ide.vscode.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.languageserver.util.IDocument; -import org.springframework.ide.vscode.commons.util.StringUtil; - -public class DefaultJavaProjectFinder implements JavaProjectFinder { - - private final String CLASSPATH_FILE_NAME; - - public DefaultJavaProjectFinder(String classpathFileName) { - this.CLASSPATH_FILE_NAME = classpathFileName; - } - - private File findClasspathFile(File file) { - if (file!=null && file.exists()) { - File cpFile = new File(file, CLASSPATH_FILE_NAME); - if (cpFile.isFile()) { - return cpFile; - } else { - return findClasspathFile(file.getParentFile()); - } - } - return null; - } - - @Override - public IJavaProject find(IDocument d) { - String uriStr = d.getUri(); - if (StringUtil.hasText(uriStr)) { - try { - URI uri = new URI(uriStr); - //TODO: This only work with File uri. Should it work with others too? - File file = new File(uri).getAbsoluteFile(); - File cpFile = findClasspathFile(file); - if (cpFile!=null) { - return new JavaProjectWithClasspathFile(cpFile); - } - } catch (URISyntaxException | IllegalArgumentException e) { - //garbage data. Ignore it. - } - } - return null; - } -} +package org.springframework.ide.vscode.commons.languageserver.java; + +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.languageserver.util.IDocument; + +public class DefaultJavaProjectFinder implements JavaProjectFinder { + + private final IJavaProjectFinderStrategy[] STRATEGIES = new IJavaProjectFinderStrategy[] { + new JavaProjectWithClasspathFileFinderStrategy(), + new MavenProjectFinderStrategy() + }; + + @Override + public IJavaProject find(IDocument d) { + for (IJavaProjectFinderStrategy strategy : STRATEGIES) { + try { + return strategy.find(d); + } catch (Throwable t) { + // Log perhaps? + } + } + return null; + } +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/IJavaProjectFinderStrategy.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/IJavaProjectFinderStrategy.java new file mode 100644 index 000000000..5ab571f76 --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/IJavaProjectFinderStrategy.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.languageserver.java; + +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.languageserver.util.IDocument; + +/** + * Strategy foe finding Java project for a document + * + * @author Alex Boyko + * + */ +@FunctionalInterface +public interface IJavaProjectFinderStrategy { + + IJavaProject find(IDocument document); + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java index 621dcd8e1..dfb9dd9f4 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectFinder.java @@ -1,10 +1,10 @@ -package org.springframework.ide.vscode.commons.languageserver.java; - -import org.springframework.ide.vscode.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.languageserver.util.IDocument; - -@FunctionalInterface -public interface JavaProjectFinder { - JavaProjectFinder DEFAULT = new DefaultJavaProjectFinder("classpath.txt"); - IJavaProject find(IDocument doc); -} +package org.springframework.ide.vscode.commons.languageserver.java; + +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.languageserver.util.IDocument; + +@FunctionalInterface +public interface JavaProjectFinder { + JavaProjectFinder DEFAULT = new DefaultJavaProjectFinder(); + IJavaProject find(IDocument doc); +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectWithClasspathFileFinderStrategy.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectWithClasspathFileFinderStrategy.java new file mode 100644 index 000000000..af78258a8 --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectWithClasspathFileFinderStrategy.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.languageserver.java; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +import org.springframework.ide.vscode.commons.languageserver.util.IDocument; +import org.springframework.ide.vscode.commons.maven.MavenCore; +import org.springframework.ide.vscode.commons.maven.java.classpathfile.JavaProjectWithClasspathFile; +import org.springframework.ide.vscode.commons.util.FileUtils; +import org.springframework.ide.vscode.commons.util.StringUtil; + +public class JavaProjectWithClasspathFileFinderStrategy implements IJavaProjectFinderStrategy { + + @Override + public JavaProjectWithClasspathFile find(IDocument d) { + String uriStr = d.getUri(); + if (StringUtil.hasText(uriStr)) { + try { + URI uri = new URI(uriStr); + //TODO: This only work with File uri. Should it work with others too? + File file = new File(uri).getAbsoluteFile(); + File cpFile = FileUtils.findFile(file, MavenCore.CLASSPATH_TXT); + if (cpFile!=null) { + return new JavaProjectWithClasspathFile(cpFile); + } + } catch (URISyntaxException | IllegalArgumentException e) { + //garbage data. Ignore it. + } + } + return null; + } + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/MavenProjectFinderStrategy.java b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/MavenProjectFinderStrategy.java new file mode 100644 index 000000000..889bc0285 --- /dev/null +++ b/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/MavenProjectFinderStrategy.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.languageserver.java; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +import org.springframework.ide.vscode.commons.languageserver.util.IDocument; +import org.springframework.ide.vscode.commons.maven.MavenCore; +import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject; +import org.springframework.ide.vscode.commons.util.FileUtils; +import org.springframework.ide.vscode.commons.util.StringUtil; + +/** + * Finds Maven Project based + * + * @author Alex Boyko + * + */ +public class MavenProjectFinderStrategy implements IJavaProjectFinderStrategy { + + @Override + public MavenJavaProject find(IDocument d) { + String uriStr = d.getUri(); + if (StringUtil.hasText(uriStr)) { + try { + URI uri = new URI(uriStr); + //TODO: This only work with File uri. Should it work with others too? + File file = new File(uri).getAbsoluteFile(); + File pomFile = FileUtils.findFile(file, MavenCore.POM_XML); + if (pomFile!=null) { + return new MavenJavaProject(pomFile); + } + } catch (URISyntaxException | IllegalArgumentException e) { + //garbage data. Ignore it. + } catch (Exception e) { + //TODO: Erroneous Pom file. Ignore it? Log? + } + } + return null; + } + +} diff --git a/vscode-extensions/commons/commons-maven/pom.xml b/vscode-extensions/commons/commons-maven/pom.xml index 077227359..3cdda749a 100644 --- a/vscode-extensions/commons/commons-maven/pom.xml +++ b/vscode-extensions/commons/commons-maven/pom.xml @@ -2,7 +2,6 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - commons commons-maven jar commons-maven @@ -21,38 +20,35 @@ - - - org.springframework.ide.vscode - commons-util - ${project.version} - org.apache.maven maven-core - true + ${maven-core.version} org.apache.maven maven-embedder - true + ${maven-core.version} + + + + + org.springframework.ide.vscode + commons-java + ${project.version} + + + + + org.springframework.ide.vscode + project-test-harness + ${project.version} + test - - - - org.apache.maven - maven - ${maven-core.version} - pom - import - - - - diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java index 9caa67074..4ad436dd9 100644 --- a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/MavenCore.java @@ -1,173 +1,198 @@ -/******************************************************************************* - * Copyright (c) 2016 Pivotal, 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 - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.vscode.commons.maven; - -import java.io.File; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.apache.maven.RepositoryUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.execution.MavenExecutionRequest; -import org.apache.maven.model.DependencyManagement; -import org.apache.maven.project.MavenProject; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.artifact.ArtifactTypeRegistry; -import org.eclipse.aether.collection.CollectRequest; -import org.eclipse.aether.collection.DependencyCollectionException; -import org.eclipse.aether.graph.DependencyNode; -import org.eclipse.aether.repository.LocalRepositoryManager; -import org.eclipse.aether.util.filter.ScopeDependencyFilter; -import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; -import org.eclipse.aether.util.graph.transformer.ConflictResolver; -import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver; -import org.eclipse.aether.util.graph.transformer.JavaScopeSelector; -import org.eclipse.aether.util.graph.transformer.NearestVersionSelector; -import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector; -import org.eclipse.aether.util.graph.visitor.CloningDependencyVisitor; -import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor; - -/** - * Maven Core functionality - * - * @author Alex Boyko - * - */ -public class MavenCore { - - private static MavenCore instance = null; - - private MavenBridge maven = new MavenBridge(); - - public static MavenCore getInstance() { - if (instance == null) { - instance = new MavenCore(); - } - return instance; - } - - /** - * Creates Maven Project descriptor based on the pom file. - * - * @param pom The pom file - * @return Maven project instance - * @throws MavenException - */ - public MavenProject readProject(File pom) throws MavenException { - return maven.readProject(pom, maven.createExecutionRequest()); - } - - /** - * Taken from M2E same named method from MavenModelManager - * - * @param repositorySystem - * @param repositorySession - * @param mavenProject - * @param scope - * @return - */ - private DependencyNode readDependencyTree(org.eclipse.aether.RepositorySystem repositorySystem, - RepositorySystemSession repositorySession, MavenProject mavenProject, String scope) { - DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(repositorySession); - - ConflictResolver transformer = new ConflictResolver(new NearestVersionSelector(), new JavaScopeSelector(), - new SimpleOptionalitySelector(), new JavaScopeDeriver()); - session.setDependencyGraphTransformer(transformer); - session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, Boolean.toString(true)); - session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true); - - ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); - - CollectRequest request = new CollectRequest(); - request.setRequestContext("project"); //$NON-NLS-1$ - request.setRepositories(mavenProject.getRemoteProjectRepositories()); - - for (org.apache.maven.model.Dependency dependency : mavenProject.getDependencies()) { - request.addDependency(RepositoryUtils.toDependency(dependency, stereotypes)); - } - - DependencyManagement depMngt = mavenProject.getDependencyManagement(); - if (depMngt != null) { - for (org.apache.maven.model.Dependency dependency : depMngt.getDependencies()) { - request.addManagedDependency(RepositoryUtils.toDependency(dependency, stereotypes)); - } - } - - DependencyNode node; - try { - node = repositorySystem.collectDependencies(session, request).getRoot(); - } catch (DependencyCollectionException ex) { - node = ex.getResult().getRoot(); - } - - Collection scopes = new HashSet(); - Collections.addAll(scopes, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, - Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST); - if (Artifact.SCOPE_COMPILE.equals(scope)) { - scopes.remove(Artifact.SCOPE_COMPILE); - scopes.remove(Artifact.SCOPE_SYSTEM); - scopes.remove(Artifact.SCOPE_PROVIDED); - } else if (Artifact.SCOPE_RUNTIME.equals(scope)) { - scopes.remove(Artifact.SCOPE_COMPILE); - scopes.remove(Artifact.SCOPE_RUNTIME); - } else if (Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals(scope)) { - scopes.remove(Artifact.SCOPE_COMPILE); - scopes.remove(Artifact.SCOPE_SYSTEM); - scopes.remove(Artifact.SCOPE_PROVIDED); - scopes.remove(Artifact.SCOPE_RUNTIME); - } else { - scopes.clear(); - } - - CloningDependencyVisitor cloner = new CloningDependencyVisitor(); - node.accept(new FilteringDependencyVisitor(cloner, new ScopeDependencyFilter(null, scopes))); - node = cloner.getRootNode(); - - return node; - } - - /** - * Calculates dependency graph for a Maven project provided the scope. - * - * @param project Maven Project descriptor - * @param scope Dependency scope - * @return Set of all dependencies including transient ones - * @throws MavenException - */ - public Set resolveDependencies(MavenProject project, String scope) throws MavenException { - Set artifacts = new LinkedHashSet<>(); - - MavenExecutionRequest request = maven.createExecutionRequest(); - DefaultRepositorySystemSession session = maven.createRepositorySession(request); - - DependencyNode graph = readDependencyTree(maven.lookupComponent(org.eclipse.aether.RepositorySystem.class), session, project, scope); - if (graph != null) { - RepositoryUtils.toArtifacts(artifacts, graph.getChildren(), - Collections.singletonList(project.getArtifact().getId()), null); - - // Maven 2.x quirk: an artifact always points at the local repo, - // regardless whether resolved or not - LocalRepositoryManager lrm = session.getLocalRepositoryManager(); - for (Artifact artifact : artifacts) { - if (!artifact.isResolved()) { - String path = lrm.getPathForLocalArtifact(RepositoryUtils.toArtifact(artifact)); - artifact.setFile(new File(lrm.getRepository().getBasedir(), path)); - } - } - } - - return artifacts; - } -} +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.maven; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.repository.LocalRepositoryManager; +import org.eclipse.aether.util.filter.ScopeDependencyFilter; +import org.eclipse.aether.util.graph.manager.DependencyManagerUtils; +import org.eclipse.aether.util.graph.transformer.ConflictResolver; +import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver; +import org.eclipse.aether.util.graph.transformer.JavaScopeSelector; +import org.eclipse.aether.util.graph.transformer.NearestVersionSelector; +import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector; +import org.eclipse.aether.util.graph.visitor.CloningDependencyVisitor; +import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor; + +/** + * Maven Core functionality + * + * @author Alex Boyko + * + */ +public class MavenCore { + + public static final String CLASSPATH_TXT = "classpath.txt"; + public static final String POM_XML = "pom.xml"; + + private static MavenCore instance = null; + + private MavenBridge maven = new MavenBridge(); + + public static MavenCore getInstance() { + if (instance == null) { + instance = new MavenCore(); + } + return instance; + } + + /** + * Reads maven classpath text file + * + * @param classPathFilePath + * @return set of classpath entries + * @throws IOException + */ + public static Set readClassPathFile(Path classPathFilePath) throws IOException { + InputStream in = Files.newInputStream(classPathFilePath); + String text = new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining()); + Path dir = classPathFilePath.getParent(); + return Arrays.stream(text.split(File.pathSeparator)).map(dir::resolve).collect(Collectors.toSet()); + } + + /** + * Creates Maven Project descriptor based on the pom file. + * + * @param pom The pom file + * @return Maven project instance + * @throws MavenException + */ + public MavenProject readProject(File pom) throws MavenException { + return maven.readProject(pom, maven.createExecutionRequest()); + } + + /** + * Taken from M2E same named method from MavenModelManager + * + * @param repositorySystem + * @param repositorySession + * @param mavenProject + * @param scope + * @return + */ + private DependencyNode readDependencyTree(org.eclipse.aether.RepositorySystem repositorySystem, + RepositorySystemSession repositorySession, MavenProject mavenProject, String scope) { + DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(repositorySession); + + ConflictResolver transformer = new ConflictResolver(new NearestVersionSelector(), new JavaScopeSelector(), + new SimpleOptionalitySelector(), new JavaScopeDeriver()); + session.setDependencyGraphTransformer(transformer); + session.setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, Boolean.toString(true)); + session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true); + + ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); + + CollectRequest request = new CollectRequest(); + request.setRequestContext("project"); //$NON-NLS-1$ + request.setRepositories(mavenProject.getRemoteProjectRepositories()); + + for (org.apache.maven.model.Dependency dependency : mavenProject.getDependencies()) { + request.addDependency(RepositoryUtils.toDependency(dependency, stereotypes)); + } + + DependencyManagement depMngt = mavenProject.getDependencyManagement(); + if (depMngt != null) { + for (org.apache.maven.model.Dependency dependency : depMngt.getDependencies()) { + request.addManagedDependency(RepositoryUtils.toDependency(dependency, stereotypes)); + } + } + + DependencyNode node; + try { + node = repositorySystem.collectDependencies(session, request).getRoot(); + } catch (DependencyCollectionException ex) { + node = ex.getResult().getRoot(); + } + + Collection scopes = new HashSet(); + Collections.addAll(scopes, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, + Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST); + if (Artifact.SCOPE_COMPILE.equals(scope)) { + scopes.remove(Artifact.SCOPE_COMPILE); + scopes.remove(Artifact.SCOPE_SYSTEM); + scopes.remove(Artifact.SCOPE_PROVIDED); + } else if (Artifact.SCOPE_RUNTIME.equals(scope)) { + scopes.remove(Artifact.SCOPE_COMPILE); + scopes.remove(Artifact.SCOPE_RUNTIME); + } else if (Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals(scope)) { + scopes.remove(Artifact.SCOPE_COMPILE); + scopes.remove(Artifact.SCOPE_SYSTEM); + scopes.remove(Artifact.SCOPE_PROVIDED); + scopes.remove(Artifact.SCOPE_RUNTIME); + } else { + scopes.clear(); + } + + CloningDependencyVisitor cloner = new CloningDependencyVisitor(); + node.accept(new FilteringDependencyVisitor(cloner, new ScopeDependencyFilter(null, scopes))); + node = cloner.getRootNode(); + + return node; + } + + /** + * Calculates dependency graph for a Maven project provided the scope. + * + * @param project Maven Project descriptor + * @param scope Dependency scope + * @return Set of all dependencies including transient ones + * @throws MavenException + */ + public Set resolveDependencies(MavenProject project, String scope) throws MavenException { + Set artifacts = new LinkedHashSet<>(); + + MavenExecutionRequest request = maven.createExecutionRequest(); + DefaultRepositorySystemSession session = maven.createRepositorySession(request); + + DependencyNode graph = readDependencyTree(maven.lookupComponent(org.eclipse.aether.RepositorySystem.class), session, project, scope); + if (graph != null) { + RepositoryUtils.toArtifacts(artifacts, graph.getChildren(), + Collections.singletonList(project.getArtifact().getId()), null); + + // Maven 2.x quirk: an artifact always points at the local repo, + // regardless whether resolved or not + LocalRepositoryManager lrm = session.getLocalRepositoryManager(); + for (Artifact artifact : artifacts) { + if (!artifact.isResolved()) { + String path = lrm.getPathForLocalArtifact(RepositoryUtils.toArtifact(artifact)); + artifact.setFile(new File(lrm.getRepository().getBasedir(), path)); + } + } + } + + return artifacts; + } +} diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java new file mode 100644 index 000000000..dce65e05f --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenJavaProject.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.maven.java; + +import java.io.File; + +import org.apache.maven.project.MavenProject; +import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.java.IType; +import org.springframework.ide.vscode.commons.maven.MavenCore; +import org.springframework.ide.vscode.commons.util.HtmlSnippet; + +/** + * Wrapper for Maven Core project + * + * @author Alex Boyko + * + */ +public class MavenJavaProject implements IJavaProject { + + private MavenProject mavenProject; + private MavenProjectClasspath classpath; + private MavenCore maven; + + public MavenJavaProject(File pom) throws Exception { + this.maven = MavenCore.getInstance(); + this.mavenProject = maven.readProject(pom); + this.classpath = new MavenProjectClasspath(mavenProject, maven); + } + + @Override + public String getElementName() { + return mavenProject.getName(); + } + + @Override + public HtmlSnippet getJavaDoc() { + return null; + } + + @Override + public boolean exists() { + return mavenProject != null; + } + + @Override + public IType findType(String fqName) { + // TODO Auto-generated method stub + return null; + } + + @Override + public IClasspath getClasspath() { + return classpath; + } + +} diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java new file mode 100644 index 000000000..be8346788 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/MavenProjectClasspath.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.maven.java; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.maven.project.MavenProject; +import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.maven.MavenCore; + +/** + * Classpath for a maven project + * + * @author Alex Boyko + * + */ +public class MavenProjectClasspath implements IClasspath { + + private MavenCore maven; + private MavenProject project; + + public MavenProjectClasspath(MavenProject project) { + this(project, MavenCore.getInstance()); + } + + MavenProjectClasspath(MavenProject project, MavenCore maven) { + this.maven = maven; + this.project = project; + } + + @Override + public Collection getClasspathEntries() throws Exception { + List entries = maven.resolveDependencies(project, null).stream().map(artifact -> { + return Paths.get(artifact.getFile().toURI()); + }).collect(Collectors.toList()); + entries.add(Paths.get(new File(project.getBuild().getOutputDirectory()).toURI())); + entries.add(Paths.get(new File(project.getBuild().getTestOutputDirectory()).toURI())); + return entries; + } + +} diff --git a/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile/FileClasspath.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile/FileClasspath.java new file mode 100644 index 000000000..f475e3018 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile/FileClasspath.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.maven.java.classpathfile; + +import java.nio.file.Path; +import java.util.Collection; +import java.util.Set; + +import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.maven.MavenCore; + +/** + * Classpath for a project containing classpath text file + * + * @author Alex Boyko + * + */ +public class FileClasspath implements IClasspath { + + private Path classpathFilePath; + + public FileClasspath(Path classpathFilePath) { + this.classpathFilePath = classpathFilePath; + } + + @Override + public Collection getClasspathEntries() throws Exception { + Set entries = MavenCore.readClassPathFile(classpathFilePath); + entries.add(classpathFilePath.getParent().resolve("target/classes")); + entries.add(classpathFilePath.getParent().resolve("target/test-classes")); + return entries; + } + +} diff --git a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectWithClasspathFile.java b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile/JavaProjectWithClasspathFile.java similarity index 61% rename from vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectWithClasspathFile.java rename to vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile/JavaProjectWithClasspathFile.java index 228b91820..0a3458f53 100644 --- a/vscode-extensions/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/java/JavaProjectWithClasspathFile.java +++ b/vscode-extensions/commons/commons-maven/src/main/java/org/springframework/ide/vscode/commons/maven/java/classpathfile/JavaProjectWithClasspathFile.java @@ -1,75 +1,94 @@ -package org.springframework.ide.vscode.commons.languageserver.java; - -import java.io.File; - -import org.springframework.ide.vscode.commons.java.IClasspath; -import org.springframework.ide.vscode.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.java.IType; -import org.springframework.ide.vscode.commons.util.HtmlSnippet; - -public class JavaProjectWithClasspathFile implements IJavaProject { - - private File cpFile; - - public JavaProjectWithClasspathFile(File cpFile) { - this.cpFile = cpFile; - } - - @Override - public String getElementName() { - return cpFile.getParentFile().getName(); - } - - @Override - public HtmlSnippet getJavaDoc() { - return null; - } - - @Override - public boolean exists() { - return cpFile.exists(); - } - - @Override - public IType findType(String fqName) { - //TODO: implement - return null; - } - - @Override - public IClasspath getClasspath() { - return () -> cpFile.toPath(); - } - - @Override - public String toString() { - return "JavaProjectWithClasspathFile("+cpFile+")"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cpFile == null) ? 0 : cpFile.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - JavaProjectWithClasspathFile other = (JavaProjectWithClasspathFile) obj; - if (cpFile == null) { - if (other.cpFile != null) - return false; - } else if (!cpFile.equals(other.cpFile)) - return false; - return true; - } - - +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.maven.java.classpathfile; + +import java.io.File; +import java.nio.file.Paths; + +import org.springframework.ide.vscode.commons.java.IClasspath; +import org.springframework.ide.vscode.commons.java.IJavaProject; +import org.springframework.ide.vscode.commons.java.IType; +import org.springframework.ide.vscode.commons.util.HtmlSnippet; + +/** + * Java project that contains classpath text file + * + * @author Alex Boyko + * + */ +public class JavaProjectWithClasspathFile implements IJavaProject { + + private File cpFile; + private FileClasspath classpath; + + public JavaProjectWithClasspathFile(File cpFile) { + this.cpFile = cpFile; + this.classpath = new FileClasspath(Paths.get(cpFile.toURI())); + } + + @Override + public String getElementName() { + return cpFile.getParentFile().getName(); + } + + @Override + public HtmlSnippet getJavaDoc() { + return null; + } + + @Override + public boolean exists() { + return cpFile.exists(); + } + + @Override + public IType findType(String fqName) { + //TODO: implement + return null; + } + + @Override + public IClasspath getClasspath() { + return classpath; + } + + @Override + public String toString() { + return "JavaProjectWithClasspathFile("+cpFile+")"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((cpFile == null) ? 0 : cpFile.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + JavaProjectWithClasspathFile other = (JavaProjectWithClasspathFile) obj; + if (cpFile == null) { + if (other.cpFile != null) + return false; + } else if (!cpFile.equals(other.cpFile)) + return false; + return true; + } + + } \ No newline at end of file diff --git a/vscode-extensions/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/DependencyTreeTest.java b/vscode-extensions/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/DependencyTreeTest.java index 304c6b609..691f55776 100644 --- a/vscode-extensions/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/DependencyTreeTest.java +++ b/vscode-extensions/commons/commons-maven/src/test/java/org/springframework/ide/vscode/commons/maven/DependencyTreeTest.java @@ -12,22 +12,14 @@ package org.springframework.ide.vscode.commons.maven; *******************************************************************************/ import static org.junit.Assert.assertEquals; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; import org.apache.maven.project.MavenProject; import org.junit.Test; -import org.springframework.ide.vscode.commons.util.ExternalCommand; -import org.springframework.ide.vscode.commons.util.ExternalProcess; +import org.springframework.ide.vscode.project.harness.Projects; /** * Tests for comparing maven calculated dependencies with ours @@ -37,41 +29,16 @@ import org.springframework.ide.vscode.commons.util.ExternalProcess; */ public class DependencyTreeTest { - /** - * Build test project if it's not built already - * @throws Exception - */ - private static void buildProject(Path testProjectPath) throws Exception { - if (!Files.exists(testProjectPath.resolve("classpath.txt"))) { - Path mvnwPath = System.getProperty("os.name").toLowerCase().startsWith("win") - ? testProjectPath.resolve("mvnw.cmd") : testProjectPath.resolve("mvnw"); - mvnwPath.toFile().setExecutable(true); - ExternalProcess process = new ExternalProcess(testProjectPath.toFile(), - new ExternalCommand(mvnwPath.toAbsolutePath().toString(), "clean", "package"), true); - if (process.getExitValue() != 0) { - throw new RuntimeException("Failed to build test project"); - } - } - } - - private static Set readClassPathFile(Path classPathFilePath) throws IOException { - InputStream in = Files.newInputStream(classPathFilePath); - String text = new BufferedReader(new InputStreamReader(in)).lines().collect(Collectors.joining()); - Path dir = classPathFilePath.getParent(); - return Arrays.stream(text.split(File.pathSeparator)).map(dir::resolve).collect(Collectors.toSet()); - } - @Test public void mavenTest() throws Exception { - Path testProjectPath = Paths.get(DependencyTreeTest.class.getResource("/demo-1").toURI()); - buildProject(testProjectPath); + Path testProjectPath = Projects.buildMavenProject("empty-boot-project-with-classpath-file"); - MavenProject project = MavenCore.getInstance().readProject(testProjectPath.resolve("pom.xml").toFile()); + MavenProject project = MavenCore.getInstance().readProject(testProjectPath.resolve(MavenCore.POM_XML).toFile()); Set calculatedClassPath = MavenCore.getInstance().resolveDependencies(project, null).stream().map(artifact -> { return Paths.get(artifact.getFile().toURI()); }).collect(Collectors.toSet());; - Set expectedClasspath = readClassPathFile(testProjectPath.resolve("classpath.txt")); + Set expectedClasspath = MavenCore.readClassPathFile(testProjectPath.resolve(MavenCore.CLASSPATH_TXT)); assertEquals(expectedClasspath, calculatedClassPath); } diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java deleted file mode 100644 index f05598d03..000000000 --- a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/DemoProperties.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; - -@ConfigurationProperties("demo.settings") -@Component -public class DemoProperties { - - private String user = "user"; - - private long timeout = 3000; - - public String getUser() { - return user; - } - - public void setUser(String user) { - this.user = user; - } - - public long getTimeout() { - return timeout; - } - - public void setTimeout(long timeout) { - this.timeout = timeout; - } - -} diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/RestApi.java b/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/RestApi.java deleted file mode 100644 index 1a65edaf8..000000000 --- a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/RestApi.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example; - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class RestApi { - - @RequestMapping("/hello") - @ResponseBody - public String hello() { - return "hello!"; - } - -} diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.gitignore b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.gitignore new file mode 100644 index 000000000..2af7cefb0 --- /dev/null +++ b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.gitignore @@ -0,0 +1,24 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ \ No newline at end of file diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.jar b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.jar rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.mvn/wrapper/maven-wrapper.jar diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.properties b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/.mvn/wrapper/maven-wrapper.properties rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/.mvn/wrapper/maven-wrapper.properties diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/mvnw similarity index 100% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/mvnw diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw.cmd b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/mvnw.cmd similarity index 100% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/mvnw.cmd rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/mvnw.cmd diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/pom.xml b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/pom.xml similarity index 70% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/pom.xml rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/pom.xml index e01f9f26c..959cceda9 100644 --- a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/pom.xml +++ b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/pom.xml @@ -4,18 +4,18 @@ 4.0.0 com.example - demo + empty-boot-1.4.0-web-app 0.0.1-SNAPSHOT jar - demo-1 - Demo project for Spring Boot + empty-boot-project-with-classpath-file + Empty Boot project generating classpath.txt file org.springframework.boot spring-boot-starter-parent - 1.4.0.RELEASE - + 1.4.1.RELEASE + @@ -35,22 +35,6 @@ spring-boot-starter-test test - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - - @@ -62,7 +46,6 @@ org.apache.maven.plugins maven-dependency-plugin - 2.9 build-classpath diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/main/java/com/example/EmptyBootProjectWithClasspathFileApplication.java similarity index 59% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/main/java/com/example/EmptyBootProjectWithClasspathFileApplication.java index 8f39b2fc2..31e2354e4 100644 --- a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/java/com/example/Demo1Application.java +++ b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/main/java/com/example/EmptyBootProjectWithClasspathFileApplication.java @@ -4,9 +4,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication -public class Demo1Application { +public class EmptyBootProjectWithClasspathFileApplication { public static void main(String[] args) { - SpringApplication.run(Demo1Application.class, args); + SpringApplication.run(EmptyBootProjectWithClasspathFileApplication.class, args); } } diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/resources/application.properties b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/main/resources/application.properties similarity index 100% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/main/resources/application.properties rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/main/resources/application.properties diff --git a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/test/java/com/example/EmptyBootProjectWithClasspathFileApplicationTests.java similarity index 81% rename from vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java rename to vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/test/java/com/example/EmptyBootProjectWithClasspathFileApplicationTests.java index ccc49c598..18e4bf09f 100644 --- a/vscode-extensions/commons/commons-maven/src/test/resources/demo-1/src/test/java/com/example/Demo1ApplicationTests.java +++ b/vscode-extensions/commons/commons-maven/src/test/resources/empty-boot-project-with-classpath-file/src/test/java/com/example/EmptyBootProjectWithClasspathFileApplicationTests.java @@ -7,7 +7,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest -public class Demo1ApplicationTests { +public class EmptyBootProjectWithClasspathFileApplicationTests { @Test public void contextLoads() { diff --git a/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/FileUtils.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/FileUtils.java new file mode 100644 index 000000000..4f9848ba5 --- /dev/null +++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/FileUtils.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.util; + +import java.io.File; + +/** + * Utilitity methods for working with files + * + * @authro Kris De Volder + * @author Alex Boyko + * + */ +public class FileUtils { + + /** + * Find file given its fil name in the given folder or its parent folders + * @param folder Starting folder + * @param fileNameToFind Name of the file to find + * @return Found File + */ + public static File findFile(File folder, String fileNameToFind) { + if (folder!=null && folder.exists()) { + File file = new File(folder, fileNameToFind); + if (file.isFile()) { + return file; + } else { + return findFile(folder.getParentFile(), fileNameToFind); + } + } + return null; + } + +} diff --git a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/TestProjectHarness.java b/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/TestProjectHarness.java deleted file mode 100644 index f21c658ad..000000000 --- a/vscode-extensions/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/TestProjectHarness.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.springframework.ide.vscode.languageserver.testharness; - -import static org.junit.Assert.assertTrue; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.springframework.ide.vscode.commons.java.IClasspath; -import org.springframework.ide.vscode.commons.java.IJavaProject; -import org.springframework.ide.vscode.commons.java.IType; -import org.springframework.ide.vscode.commons.util.ExternalCommand; -import org.springframework.ide.vscode.commons.util.ExternalProcess; -import org.springframework.ide.vscode.commons.util.HtmlSnippet; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; - -/** - * Class meant to be used in writing tests that require test projects to be populated - * from some data on the classpath. - */ -public class TestProjectHarness { - - private static final class TestProject implements IJavaProject { - private Path location; - - public TestProject(Path location) { - this.location = location; - } - - @Override - public HtmlSnippet getJavaDoc() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getElementName() { - return location.toFile().getName(); - } - - @Override - public boolean exists() { - return true; - } - - @Override - public IClasspath getClasspath() { - return () -> location; - } - - @Override - public IType findType(String fqName) { - // TODO Auto-generated method stub - return null; - } - } - - public Cache cache = CacheBuilder.newBuilder().build(); - - public IJavaProject mavenProject(String name) throws Exception { - Path testProjectPath = Paths.get(TestProjectHarness.class.getResource("/" + name).toURI()); - assertTrue(Files.exists(testProjectPath)); - if (!Files.exists(testProjectPath.resolve("classpath.txt"))) { - Path mvnwPath = System.getProperty("os.name").toLowerCase().startsWith("win") - ? testProjectPath.resolve("mvnw.cmd") : testProjectPath.resolve("mvnw"); - mvnwPath.toFile().setExecutable(true); - ExternalProcess process = new ExternalProcess(testProjectPath.toFile(), - new ExternalCommand(mvnwPath.toAbsolutePath().toString(), "clean", "package"), true); - if (process.getExitValue() != 0) { - throw new RuntimeException("Failed to build test project"); - } - } - return new TestProject(testProjectPath); - } - -} diff --git a/vscode-extensions/commons/pom.xml b/vscode-extensions/commons/pom.xml index 88321ebab..bfb2fc15f 100644 --- a/vscode-extensions/commons/pom.xml +++ b/vscode-extensions/commons/pom.xml @@ -1,74 +1,75 @@ - - 4.0.0 - - org.springframework.ide.vscode - commons-parent - pom - 0.0.1-SNAPSHOT - commons-parent - - - commons-language-server - language-server-test-harness - commons-yaml - commons-util - commons-java - java-properties - application-properties-metadata - commons-maven - - - - 1.17 - 4.11 - 3.5.2 - 1.7.21 - 19.0 - 2.5.0 - 2.10 - 0.3.0 - 3.0.2.RELEASE - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - - - - - - org.slf4j - slf4j-api - ${slf4j-version} - - - org.slf4j - slf4j-simple - ${slf4j-version} - - - junit - junit - ${junit-version} - test - - - org.assertj - assertj-core - ${assertj-version} - test - - - + + 4.0.0 + + org.springframework.ide.vscode + commons-parent + pom + 0.0.1-SNAPSHOT + commons-parent + + + commons-language-server + language-server-test-harness + commons-yaml + commons-util + commons-java + java-properties + application-properties-metadata + commons-maven + project-test-harness + + + + 1.17 + 4.11 + 3.5.2 + 1.7.21 + 19.0 + 2.5.0 + 2.10 + 0.3.0 + 3.0.2.RELEASE + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + + + org.slf4j + slf4j-api + ${slf4j-version} + + + org.slf4j + slf4j-simple + ${slf4j-version} + + + junit + junit + ${junit-version} + test + + + org.assertj + assertj-core + ${assertj-version} + test + + + diff --git a/vscode-extensions/commons/project-test-harness/.gitignore b/vscode-extensions/commons/project-test-harness/.gitignore new file mode 100644 index 000000000..88b8d0751 --- /dev/null +++ b/vscode-extensions/commons/project-test-harness/.gitignore @@ -0,0 +1,2 @@ +/.classpath +/.project diff --git a/vscode-extensions/commons/project-test-harness/.settings/org.eclipse.jdt.core.prefs b/vscode-extensions/commons/project-test-harness/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..d59e09c90 --- /dev/null +++ b/vscode-extensions/commons/project-test-harness/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/vscode-extensions/commons/project-test-harness/.settings/org.eclipse.m2e.core.prefs b/vscode-extensions/commons/project-test-harness/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 000000000..14b697b7b --- /dev/null +++ b/vscode-extensions/commons/project-test-harness/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/vscode-extensions/commons/project-test-harness/pom.xml b/vscode-extensions/commons/project-test-harness/pom.xml new file mode 100644 index 000000000..7c30b0eba --- /dev/null +++ b/vscode-extensions/commons/project-test-harness/pom.xml @@ -0,0 +1,20 @@ + + 4.0.0 + + org.springframework.ide.vscode + commons-parent + 0.0.1-SNAPSHOT + ../pom.xml + + project-test-harness + project-test-harness + Test projects and utilities for test projects. Independent of any tooling projects. + + + org.springframework.ide.vscode + commons-util + ${project.version} + + + \ No newline at end of file diff --git a/vscode-extensions/commons/project-test-harness/src/main/java/org/springframework/ide/vscode/project/harness/Projects.java b/vscode-extensions/commons/project-test-harness/src/main/java/org/springframework/ide/vscode/project/harness/Projects.java new file mode 100644 index 000000000..b73f62180 --- /dev/null +++ b/vscode-extensions/commons/project-test-harness/src/main/java/org/springframework/ide/vscode/project/harness/Projects.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2016 Pivotal, 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.project.harness; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.springframework.ide.vscode.commons.util.ExternalCommand; +import org.springframework.ide.vscode.commons.util.ExternalProcess; + +/** + * Test project harness utilities + * + * @author Alex Boyko + * + */ +public class Projects { + + /** + * Builds maven project + * + * @param name + * @return + * @throws Exception + */ + public static Path buildMavenProject(String name) throws Exception { + Path testProjectPath = Paths.get(Projects.class.getResource("/" + name).toURI()); + if (!Files.exists(testProjectPath.resolve("classpath.txt"))) { + Path mvnwPath = System.getProperty("os.name").toLowerCase().startsWith("win") + ? testProjectPath.resolve("mvnw.cmd") : testProjectPath.resolve("mvnw"); + mvnwPath.toFile().setExecutable(true); + ExternalProcess process = new ExternalProcess(testProjectPath.toFile(), + new ExternalCommand(mvnwPath.toAbsolutePath().toString(), "clean", "package"), true); + if (process.getExitValue() != 0) { + throw new RuntimeException("Failed to build test project"); + } + } + return testProjectPath; + } + +}