diff --git a/vscode-extensions/commons/commons-java/pom.xml b/vscode-extensions/commons/commons-java/pom.xml
index abb8bdd51..b8cc94fc6 100644
--- a/vscode-extensions/commons/commons-java/pom.xml
+++ b/vscode-extensions/commons/commons-java/pom.xml
@@ -23,5 +23,10 @@
jandex
2.0.3.Final
+
+ com.github.javaparser
+ javaparser-core
+ 2.5.1
+
\ No newline at end of file
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java
index c713c0ac4..871a6e7f0 100644
--- a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/JandexIndex.java
@@ -6,11 +6,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Iterator;
+import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import org.jboss.jandex.CompositeIndex;
+import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.IndexReader;
import org.jboss.jandex.IndexView;
@@ -24,12 +25,28 @@ import com.google.common.base.Suppliers;
public class JandexIndex {
+ private static class Entry {
+ K key;
+ V value;
+ Entry(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+ }
+
@FunctionalInterface
public static interface IndexFileFinder {
File findIndexFile(File jarFile);
}
- private Supplier index;
+ @FunctionalInterface
+ public static interface SourceContainerProvider {
+ File getSourceContainer(File container);
+ }
+
+ private Supplier>> index;
+
+ private SourceContainerProvider sourceContainerProvider;
public JandexIndex(Stream classpathEntries) {
this(classpathEntries, jarFile -> null, Optional.empty());
@@ -43,31 +60,38 @@ public class JandexIndex {
this(classpathEntries, jarFile -> null, baseIndex);
}
+ public void setSourceContainerProvider(SourceContainerProvider sourceContainerProvider) {
+ this.sourceContainerProvider = sourceContainerProvider;
+ }
+
+ public SourceContainerProvider getSourceContainerProvider() {
+ return sourceContainerProvider;
+ }
+
public JandexIndex(Stream classpathEntries, IndexFileFinder indexFileFinder, Optional baseIndex) {
index = Suppliers.memoize(() -> {
+ List> indices = buildIndex(classpathEntries, indexFileFinder).collect(Collectors.toList());
if (baseIndex.isPresent()) {
- return CompositeIndex.create(baseIndex.get().index.get(), buildIndex(classpathEntries, indexFileFinder));
- } else {
- return buildIndex(classpathEntries, indexFileFinder);
+ indices.addAll(baseIndex.get().index.get());
}
+ return indices;
});
}
- private static CompositeIndex buildIndex(Stream classpathEntries, IndexFileFinder indexFileFinder) {
- return CompositeIndex.create(classpathEntries
+ private Stream> buildIndex(Stream classpathEntries, IndexFileFinder indexFileFinder) {
+ return classpathEntries
.map(entry -> entry.toFile())
.map(file -> {
+ Optional index = Optional.empty();
if (file.isFile() && file.getName().endsWith(".jar")) {
- return indexJar(file, indexFileFinder);
+ index = indexJar(file, indexFileFinder);
} else if (file.isDirectory()) {
- return indexFolder(file);
- } else {
- return Optional.empty();
+ index = indexFolder(file);
}
+ return new Entry<>(file, index);
})
- .filter(o -> o.isPresent())
- .map(o -> o.get())
- .collect(Collectors.toList()));
+ .filter(e -> e.value.isPresent())
+ .map(e -> new Entry<>(e.key, e.value.get()));
}
private static Optional indexFolder(File folder) {
@@ -134,8 +158,16 @@ public class JandexIndex {
}
public IType findType(String fqName) {
- IndexView compositeIndex = index.get();
- return Wrappers.wrap(compositeIndex, compositeIndex.getClassByName(DotName.createSimple(fqName)));
+ return getClassByName(DotName.createSimple(fqName));
+ }
+
+ IType getClassByName(DotName className) {
+ Optional> pair = index.get().stream().map(e -> new Entry<>(e.key, e.value.getClassByName(className))).filter(e -> e.value != null).findFirst();
+ if (pair.isPresent()) {
+ return Wrappers.wrap(this, pair.get().value, pair.get().key);
+ } else {
+ return null;
+ }
}
}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java
index 333d897ff..0d9e65476 100644
--- a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/jandex/Wrappers.java
@@ -2,6 +2,7 @@ package org.springframework.ide.vscode.commons.jandex;
import static org.springframework.ide.vscode.commons.util.Assert.isNotNull;
+import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -29,7 +30,7 @@ import org.springframework.ide.vscode.commons.util.HtmlSnippet;
public class Wrappers {
- public static IType wrap(IndexView index, ClassInfo info) {
+ public static IType wrap(JandexIndex index, ClassInfo info, File container) {
if (info == null) {
return null;
}
@@ -43,7 +44,7 @@ public class Wrappers {
@Override
public IType getDeclaringType() {
DotName enclosingClass = info.enclosingClass();
- return enclosingClass == null ? null : wrap(index, index.getClassByName(enclosingClass));
+ return enclosingClass == null ? null : index.getClassByName(enclosingClass);
}
@Override
@@ -89,26 +90,26 @@ public class Wrappers {
@Override
public IField getField(String name) {
- return wrap(index, info.field(name));
+ return wrap(index, info.field(name), container);
}
@Override
public Stream getFields() {
return info.fields().stream().map(f -> {
- return wrap(index, f);
+ return wrap(index, f, container);
});
}
@Override
public IMethod getMethod(String name, Stream parameters) {
List typeParameters = parameters.map(Wrappers::from).collect(Collectors.toList());
- return wrap(index, info.method(name, typeParameters.toArray(new Type[typeParameters.size()])));
+ return wrap(index, info.method(name, typeParameters.toArray(new Type[typeParameters.size()])), container);
}
@Override
public Stream getMethods() {
return info.methods().stream().map(m -> {
- return wrap(index, m);
+ return wrap(index, m, container);
});
}
@@ -120,7 +121,7 @@ public class Wrappers {
};
}
- public static IField wrap(IndexView index, FieldInfo field) {
+ public static IField wrap(JandexIndex index, FieldInfo field, File container) {
if (field == null) {
return null;
}
@@ -133,7 +134,7 @@ public class Wrappers {
@Override
public IType getDeclaringType() {
- return wrap(index, field.declaringClass());
+ return wrap(index, field.declaringClass(), container);
}
@Override
@@ -170,7 +171,7 @@ public class Wrappers {
};
}
- public static IMethod wrap(IndexView index, MethodInfo method) {
+ public static IMethod wrap(JandexIndex index, MethodInfo method, File container) {
isNotNull(index);
isNotNull(method);
return new IMethod() {
@@ -182,7 +183,7 @@ public class Wrappers {
@Override
public IType getDeclaringType() {
- return wrap(index, method.declaringClass());
+ return wrap(index, method.declaringClass(), container);
}
@Override
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/parser/CompilationUnitIndex.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/parser/CompilationUnitIndex.java
new file mode 100644
index 000000000..ce8b26028
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/parser/CompilationUnitIndex.java
@@ -0,0 +1,13 @@
+package org.springframework.ide.vscode.commons.java.parser;
+
+import java.net.URL;
+
+import com.github.javaparser.ast.CompilationUnit;
+
+public interface CompilationUnitIndex {
+
+ static final CompilationUnitIndex DEFAULT = new DefaultCompilationUnitIndex();
+
+ CompilationUnit getCompilationUnit(URL url);
+
+}
diff --git a/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/parser/DefaultCompilationUnitIndex.java b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/parser/DefaultCompilationUnitIndex.java
new file mode 100644
index 000000000..7a74b6fdd
--- /dev/null
+++ b/vscode-extensions/commons/commons-java/src/main/java/org/springframework/ide/vscode/commons/java/parser/DefaultCompilationUnitIndex.java
@@ -0,0 +1,44 @@
+package org.springframework.ide.vscode.commons.java.parser;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.concurrent.ExecutionException;
+
+import org.springframework.ide.vscode.commons.util.Log;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+class DefaultCompilationUnitIndex implements CompilationUnitIndex {
+
+ private LoadingCache cache = CacheBuilder.newBuilder().build(new CacheLoader() {
+
+ @Override
+ public CompilationUnit load(URL url) throws Exception {
+ InputStream in = url.openStream();
+ try {
+ return JavaParser.parse(in);
+ } catch (ParseException e) {
+ in.close();
+ Log.log("Failed to parse java source file: " + url, e);
+ }
+ return null;
+ }
+
+ });
+
+ @Override
+ public CompilationUnit getCompilationUnit(URL url) {
+ try {
+ return cache.get(url);
+ } catch (ExecutionException e) {
+ Log.log(e);
+ }
+ return null;
+ }
+
+}