Introduce IClasspath abstraction.

This commit is contained in:
Kris De Volder
2016-10-21 16:01:42 -07:00
parent f05e3b66cb
commit 46e2334b0c
12 changed files with 159 additions and 120 deletions

View File

@@ -64,6 +64,12 @@
<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>

View File

@@ -21,6 +21,7 @@ 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 {
@@ -48,8 +49,9 @@ public class PropertiesLoader {
private ConfigurationMetadataRepositoryJsonBuilder builder = ConfigurationMetadataRepositoryJsonBuilder.create();
public ConfigurationMetadataRepository load(Path projectPath) {
return load(projectPath.resolve("classpath.txt"), projectPath.resolve("target/classes"));
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) {
@@ -154,8 +156,8 @@ public class PropertiesLoader {
public static void main(String[] args) {
if (args.length > 0) {
Path projectPath = Paths.get(args[0]);
ConfigurationMetadataRepository repo = new PropertiesLoader().load(projectPath);
Path projectPath = Paths.get(args[0]);
ConfigurationMetadataRepository repo = new PropertiesLoader().load(() -> projectPath);
Map<String, ConfigurationMetadataProperty> allProperties = repo.getAllProperties();
allProperties.keySet().forEach(System.out::println);
}

View File

@@ -17,6 +17,8 @@ import java.util.Map;
import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap;
import org.springframework.ide.vscode.application.properties.metadata.util.Listener;
import org.springframework.ide.vscode.application.properties.metadata.util.ListenerManager;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IJavaProject;
/**
* Support for Reconciling, Content Assist and Hover Text in spring properties
@@ -28,21 +30,21 @@ import org.springframework.ide.vscode.application.properties.metadata.util.Liste
*/
public class SpringPropertiesIndexManager extends ListenerManager<Listener<SpringPropertiesIndexManager>> {
private Map<Path, SpringPropertyIndex> indexes = null;
private Map<IJavaProject, SpringPropertyIndex> indexes = null;
final private ValueProviderRegistry valueProviders;
public SpringPropertiesIndexManager(ValueProviderRegistry valueProviders) {
this.valueProviders = valueProviders;
}
public synchronized FuzzyMap<PropertyInfo> get(Path projectFolder) {
public synchronized FuzzyMap<PropertyInfo> get(IJavaProject project) {
if (indexes==null) {
indexes = new HashMap<>();
}
SpringPropertyIndex index = indexes.get(projectFolder);
SpringPropertyIndex index = indexes.get(project);
if (index==null) {
index = new SpringPropertyIndex(valueProviders, projectFolder);
indexes.put(projectFolder, index);
index = new SpringPropertyIndex(valueProviders, project.getClasspath());
indexes.put(project, index);
}
return index;
}

View File

@@ -10,7 +10,6 @@
*******************************************************************************/
package org.springframework.ide.vscode.application.properties.metadata;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
@@ -19,12 +18,13 @@ import org.springframework.boot.configurationmetadata.ConfigurationMetadataPrope
import org.springframework.boot.configurationmetadata.ConfigurationMetadataRepository;
import org.springframework.boot.configurationmetadata.ConfigurationMetadataSource;
import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap;
import org.springframework.ide.vscode.commons.java.IClasspath;
public class SpringPropertyIndex extends FuzzyMap<PropertyInfo> {
private ValueProviderRegistry valueProviders;
public SpringPropertyIndex(ValueProviderRegistry valueProviders, Path projectPath) {
public SpringPropertyIndex(ValueProviderRegistry valueProviders, IClasspath projectPath) {
this.valueProviders = valueProviders;
if (projectPath!=null) {
// try {

View File

@@ -14,18 +14,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.BeforeClass;
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.util.ExternalCommand;
import org.springframework.ide.vscode.commons.util.ExternalProcess;
import org.springframework.ide.vscode.languageserver.testharness.TestProjectHarness;
/**
* Sanity test the boot properties index
@@ -35,26 +29,12 @@ import org.springframework.ide.vscode.commons.util.ExternalProcess;
*/
public class PropertiesIndexTest {
/**
* Build test project demo-1 if it's not built already
* @throws Exception
*/
@BeforeClass
public static void initTestProject() throws Exception {
Path testProjectPath = Paths.get(PropertiesIndexTest.class.getResource("/demo-1").toURI());
if (!Files.exists(testProjectPath.resolve("classpath.txt"))) {
testProjectPath.resolve("mvnw").toFile().setExecutable(true);
ExternalProcess process = new ExternalProcess(testProjectPath.toFile(), new ExternalCommand("./mvnw", "clean", "package"), true);
if (process.getExitValue() != 0) {
throw new RuntimeException("Failed to build test project");
}
}
}
private TestProjectHarness projects = new TestProjectHarness();
@Test
public void springStandardPropertyPresent() throws Exception {
SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault());
FuzzyMap<PropertyInfo> index = indexManager.get(Paths.get(getClass().getResource("/demo-1").toURI()));
FuzzyMap<PropertyInfo> index = indexManager.get(projects.mavenProject("demo-1"));
PropertyInfo propertyInfo = index.get("server.port");
assertNotNull(propertyInfo);
assertEquals(Integer.class.getName(), propertyInfo.getType());
@@ -64,7 +44,7 @@ public class PropertiesIndexTest {
@Test
public void customPropertyPresent() throws Exception {
SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault());
FuzzyMap<PropertyInfo> index = indexManager.get(Paths.get(getClass().getResource("/demo-1").toURI()));
FuzzyMap<PropertyInfo> index = indexManager.get(projects.mavenProject("demo-1"));
PropertyInfo propertyInfo = index.get("demo.settings.user");
assertNotNull(propertyInfo);
assertEquals(String.class.getName(), propertyInfo.getType());
@@ -74,7 +54,7 @@ public class PropertiesIndexTest {
@Test
public void propertyNotPresent() throws Exception {
SpringPropertiesIndexManager indexManager = new SpringPropertiesIndexManager(ValueProviderRegistry.getDefault());
FuzzyMap<PropertyInfo> index = indexManager.get(Paths.get(getClass().getResource("/demo-1").toURI()));
FuzzyMap<PropertyInfo> index = indexManager.get(projects.mavenProject("demo-1"));
PropertyInfo propertyInfo = index.get("my.server.port");
assertNull(propertyInfo);
}

View File

@@ -0,0 +1,14 @@
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();
}

View File

@@ -1,8 +1,6 @@
package org.springframework.ide.vscode.commons.java;
import java.nio.file.Path;
public interface IJavaProject extends IJavaElement {
IType findType(String fqName);
Path getPath();
IClasspath getClasspath();
}

View File

@@ -3,12 +3,9 @@ package org.springframework.ide.vscode.commons.languageserver.java;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.java.IType;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.util.HtmlSnippet;
import org.springframework.ide.vscode.commons.util.StringUtil;
public class DefaultJavaProjectFinder implements JavaProjectFinder {
@@ -48,45 +45,5 @@ public class DefaultJavaProjectFinder implements JavaProjectFinder {
}
}
return null;
};
private static 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 Path getPath() {
return cpFile.getParentFile().toPath();
}
@Override
public String toString() {
return "JavaProjectWithClasspathFile("+cpFile+")";
}
}
}

View File

@@ -0,0 +1,75 @@
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;
}
}

View File

@@ -6,6 +6,7 @@ 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;
@@ -21,10 +22,45 @@ import com.google.common.cache.CacheBuilder;
*/
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 get(String name) throws Exception {
Path testProjectPath = Paths.get(TestProjectHarness.class.getResource("/demo-1").toURI());
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"))) {
testProjectPath.resolve("mvnw").toFile().setExecutable(true);
@@ -33,34 +69,7 @@ public class TestProjectHarness {
throw new RuntimeException("Failed to build test project");
}
}
return new IJavaProject() {
@Override
public HtmlSnippet getJavaDoc() {
return null;
}
@Override
public String getElementName() {
return name;
}
@Override
public boolean exists() {
return true;
}
@Override
public Path getPath() {
return testProjectPath;
}
@Override
public IType findType(String string) {
//throw new UnsupportedOperationException("Not yet implemented");
return null;
}
};
return new TestProject(testProjectPath);
}
}

View File

@@ -1,7 +1,5 @@
package org.springframework.ide.vscode.application.yaml;
import java.nio.file.Path;
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.SpringPropertyIndexProvider;
@@ -20,10 +18,7 @@ public class DefaultSpringPropertyIndexProvider implements SpringPropertyIndexPr
public FuzzyMap<PropertyInfo> getIndex(IDocument doc) {
IJavaProject jp = javaProjectFinder.find(doc);
if (jp!=null) {
Path projectFolder = jp.getPath();
if (projectFolder!=null) {
return indexManager.get(projectFolder);
}
return indexManager.get(jp);
}
return null;
}

View File

@@ -14,6 +14,7 @@ import org.springframework.ide.vscode.application.properties.metadata.SpringProp
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
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.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
@@ -30,8 +31,8 @@ public class PropertyIndexHarness {
protected SpringPropertyIndexProvider indexProvider = new SpringPropertyIndexProvider() {
public FuzzyMap<PropertyInfo> getIndex(IDocument doc) {
if (index==null) {
Path path = testProject == null ? null : testProject.getPath();
index = new SpringPropertyIndex(valueProviders, path);
IClasspath classpath = testProject == null ? null : testProject.getClasspath();
index = new SpringPropertyIndex(valueProviders, classpath);
for (ConfigurationMetadataProperty propertyInfo : datas.values()) {
index.add(propertyInfo);
}