Integrate commons-maven to eliminate classpath text file based solution

This commit is contained in:
Alex Boyko
2016-10-25 17:15:25 -04:00
parent ea6079bea2
commit 5ea5b5cb28
47 changed files with 1315 additions and 1002 deletions

41
.gitignore vendored
View File

@@ -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

View File

@@ -1,75 +1,75 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>application-properties-metadata</artifactId>
<description>Builds metadata for boot application properties based on project's classpath contents</description>
<repositories>
<repository>
<id>project-repo</id>
<url>file://${project.basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<!-- Local modified JSON lib packaged to support order in maps -->
<dependency>
<groupId>org.springframework.ide.eclipse</groupId>
<artifactId>org.json</artifactId>
<version>1.0</version>
</dependency>
<!-- Guava collections -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- Javax Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Reactor -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>${reactor-version}</version>
</dependency>
<!-- Common Utilities -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-yaml</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-language-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>language-server-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>application-properties-metadata</artifactId>
<description>Builds metadata for boot application properties based on project's classpath contents</description>
<repositories>
<repository>
<id>project-repo</id>
<url>file://${project.basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<!-- Local modified JSON lib packaged to support order in maps -->
<dependency>
<groupId>org.springframework.ide.eclipse</groupId>
<artifactId>org.json</artifactId>
<version>1.0</version>
</dependency>
<!-- Guava collections -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- Javax Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Reactor -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>${reactor-version}</version>
</dependency>
<!-- Common Utilities -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-yaml</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-language-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>project-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -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<Set<Path>> 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<String, ConfigurationMetadataProperty> 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);
}
}

View File

@@ -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<PropertyInfo> 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<PropertyInfo> 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<PropertyInfo> 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<PropertyInfo> 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<PropertyInfo> 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<PropertyInfo> 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<PropertyInfo> 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<PropertyInfo> 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<PropertyInfo> index = indexManager.get(classpathFileProject);
PropertyInfo propertyInfo = index.get("my.server.port");
assertNull(propertyInfo);
}
}

View File

@@ -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<Path> getClasspathEntries() throws Exception;
}

View File

@@ -1,79 +1,84 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>commons-language-server</artifactId>
<name>commons-language-server</name>
<description>Shared utilities for building vscode language servers in Java</description>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Java implementation of VS Code language server protocol -->
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.services</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.annotations</artifactId>
<version>${lsapi-version}</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>language-server-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>commons-language-server</artifactId>
<name>commons-language-server</name>
<description>Shared utilities for building vscode language servers in Java</description>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-maven</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Java implementation of VS Code language server protocol -->
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.services</artifactId>
<version>${lsapi-version}</version>
</dependency>
<dependency>
<groupId>io.typefox.lsapi</groupId>
<artifactId>io.typefox.lsapi.annotations</artifactId>
<version>${lsapi-version}</version>
</dependency>
<!-- JSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>${jackson-2-version}</version>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>language-server-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -2,7 +2,6 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>commons</groupId>
<artifactId>commons-maven</artifactId>
<packaging>jar</packaging>
<name>commons-maven</name>
@@ -21,38 +20,35 @@
</properties>
<dependencies>
<!-- Common Utilities -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Maven Runtime -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<optional>true</optional>
<version>${maven-core.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<optional>true</optional>
<version>${maven-core.version}</version>
</dependency>
<!-- Java Model -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>project-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven</artifactId>
<version>${maven-core.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@@ -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<String> scopes = new HashSet<String>();
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<Artifact> resolveDependencies(MavenProject project, String scope) throws MavenException {
Set<Artifact> 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<Path> 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<String> scopes = new HashSet<String>();
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<Artifact> resolveDependencies(MavenProject project, String scope) throws MavenException {
Set<Artifact> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<Path> getClasspathEntries() throws Exception {
List<Path> 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;
}
}

View File

@@ -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<Path> getClasspathEntries() throws Exception {
Set<Path> entries = MavenCore.readClassPathFile(classpathFilePath);
entries.add(classpathFilePath.getParent().resolve("target/classes"));
entries.add(classpathFilePath.getParent().resolve("target/test-classes"));
return entries;
}
}

View File

@@ -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;
}
}

View File

@@ -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<Path> 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<Path> calculatedClassPath = MavenCore.getInstance().resolveDependencies(project, null).stream().map(artifact -> {
return Paths.get(artifact.getFile().toURI());
}).collect(Collectors.toSet());;
Set<Path> expectedClasspath = readClassPathFile(testProjectPath.resolve("classpath.txt"));
Set<Path> expectedClasspath = MavenCore.readClassPathFile(testProjectPath.resolve(MavenCore.CLASSPATH_TXT));
assertEquals(expectedClasspath, calculatedClassPath);
}

View File

@@ -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;
}
}

View File

@@ -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!";
}
}

View File

@@ -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/

View File

@@ -4,18 +4,18 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<artifactId>empty-boot-1.4.0-web-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo-1</name>
<description>Demo project for Spring Boot</description>
<name>empty-boot-project-with-classpath-file</name>
<description>Empty Boot project generating classpath.txt file</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
<version>1.4.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
@@ -35,22 +35,6 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-aether</artifactId>
<version>0.10.1</version>
</dependency>
-->
</dependencies>
<build>
@@ -62,7 +46,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>build-classpath</id>

View File

@@ -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);
}
}

View File

@@ -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() {

View File

@@ -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 <code>File</code>
*/
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;
}
}

View File

@@ -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<String, IJavaProject> 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);
}
}

View File

@@ -1,74 +1,75 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>commons-parent</name>
<modules>
<module>commons-language-server</module>
<module>language-server-test-harness</module>
<module>commons-yaml</module>
<module>commons-util</module>
<module>commons-java</module>
<module>java-properties</module>
<module>application-properties-metadata</module>
<module>commons-maven</module>
</modules>
<properties>
<yaml-version>1.17</yaml-version>
<junit-version>4.11</junit-version>
<assertj-version>3.5.2</assertj-version>
<slf4j-version>1.7.21</slf4j-version>
<guava-version>19.0</guava-version>
<jackson-2-version>2.5.0</jackson-2-version>
<jersey-2-version>2.10</jersey-2-version>
<lsapi-version>0.3.0</lsapi-version>
<reactor-version>3.0.2.RELEASE</reactor-version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>commons-parent</name>
<modules>
<module>commons-language-server</module>
<module>language-server-test-harness</module>
<module>commons-yaml</module>
<module>commons-util</module>
<module>commons-java</module>
<module>java-properties</module>
<module>application-properties-metadata</module>
<module>commons-maven</module>
<module>project-test-harness</module>
</modules>
<properties>
<yaml-version>1.17</yaml-version>
<junit-version>4.11</junit-version>
<assertj-version>3.5.2</assertj-version>
<slf4j-version>1.7.21</slf4j-version>
<guava-version>19.0</guava-version>
<jackson-2-version>2.5.0</jackson-2-version>
<jersey-2-version>2.10</jersey-2-version>
<lsapi-version>0.3.0</lsapi-version>
<reactor-version>3.0.2.RELEASE</reactor-version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,2 @@
/.classpath
/.project

View File

@@ -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

View File

@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@@ -0,0 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>project-test-harness</artifactId>
<name>project-test-harness</name>
<description>Test projects and utilities for test projects. Independent of any tooling projects.</description>
<dependencies>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -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;
}
}