Merge branch 'master' of github.com:spring-projects/sts4
This commit is contained in:
@@ -22,7 +22,7 @@ import org.gradle.tooling.model.eclipse.EclipseProject;
|
||||
import org.gradle.tooling.model.eclipse.EclipseProjectDependency;
|
||||
import org.gradle.tooling.model.eclipse.EclipseSourceDirectory;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaUtils;
|
||||
import org.springframework.ide.vscode.commons.java.JavaUtils;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE;
|
||||
|
||||
|
||||
@@ -11,32 +11,21 @@
|
||||
package org.springframework.ide.vscode.commons.jandex;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.IndexReader;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.jandex.JarIndexer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMatcher;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
@@ -71,212 +60,106 @@ public class BasicJandexIndex {
|
||||
return folder;
|
||||
}
|
||||
|
||||
private Map<File, Supplier<Optional<IndexView>>> index;
|
||||
private ImmutableList<ModuleJandexIndex> modules;
|
||||
|
||||
private Map<File, Supplier<List<Tuple3<String, File, ClassInfo>>>> knownTypes;
|
||||
|
||||
private Map<File, Supplier<List<String>>> knownPackages;
|
||||
|
||||
private BasicJandexIndex[] baseIndex;
|
||||
|
||||
BasicJandexIndex(Collection<File> classpathEntries, IndexFileFinder indexFileFinder,
|
||||
BasicJandexIndex... baseIndex) {
|
||||
this.baseIndex = baseIndex;
|
||||
this.index = new ConcurrentHashMap<>();
|
||||
this.knownTypes = new HashMap<>();
|
||||
this.knownPackages = new HashMap<>();
|
||||
classpathEntries.forEach(file -> {
|
||||
index.put(file, /*Suppliers.synchronizedSupplier(*/Suppliers.memoize(() -> createIndex(file, indexFileFinder))/*)*/);
|
||||
knownTypes.put(file, Suppliers.memoize(() -> getKnownTypesStream(file).collect(Collectors.toList())));
|
||||
knownPackages.put(file, Suppliers.memoize(() -> getKnownPackages(file).collect(Collectors.toList())));
|
||||
});
|
||||
}
|
||||
|
||||
private Optional<IndexView> createIndex(File file, IndexFileFinder indexFileFinder) {
|
||||
if (file != null && file.isFile() && file.getName().endsWith(".jar")) {
|
||||
return indexJar(file, indexFileFinder);
|
||||
} else if (file != null && file.isDirectory()) {
|
||||
return indexFolder(file);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
BasicJandexIndex(IClasspath classpath, IndexFileFinder indexFileFinder) {
|
||||
ImmutableList.Builder<ModuleJandexIndex> builder = ImmutableList.builder();
|
||||
try {
|
||||
classpath.getClasspathEntries().forEach(cpe -> {
|
||||
File binaryLocation = IClasspathUtil.binaryLocation(cpe);
|
||||
builder.addAll(IndexRoutines.fromCPE(cpe, indexFileFinder.findIndexFile(binaryLocation)));
|
||||
});
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
this.modules = builder.build();
|
||||
}
|
||||
|
||||
private static Optional<IndexView> indexFolder(File folder) {
|
||||
Indexer indexer = new Indexer();
|
||||
for (Iterator<File> itr = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder)
|
||||
.iterator(); itr.hasNext();) {
|
||||
File file = itr.next();
|
||||
if (file.isFile() && file.getName().endsWith(".class")) {
|
||||
try {
|
||||
final InputStream stream = new FileInputStream(file);
|
||||
try {
|
||||
indexer.index(stream);
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to index file " + file, e);
|
||||
Tuple2<IJavaModuleData, ClassInfo> getClassByName(DotName fqName) {
|
||||
for (ModuleJandexIndex m : modules) {
|
||||
IndexView indexView = m.getIndex().get();
|
||||
if (indexView != null) {
|
||||
ClassInfo info = indexView.getClassByName(fqName);
|
||||
if (info != null) {
|
||||
return Tuples.of(m, info);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.of(indexer.complete());
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Optional<IndexView> indexJar(File file, IndexFileFinder indexFileFinder) {
|
||||
File indexFile = indexFileFinder.findIndexFile(file);
|
||||
if (indexFile != null) {
|
||||
try {
|
||||
if (!indexFile.getParentFile().exists()) {
|
||||
indexFile.getParentFile().mkdirs();
|
||||
public IJavaModuleData findClasspathResourceForType(String fqName) {
|
||||
Tuple2<IJavaModuleData, ClassInfo> match = getClassByName(DotName.createSimple(fqName));
|
||||
return match == null ? null : match.getT1();
|
||||
}
|
||||
|
||||
private Collection<String> getKnownPackages(ModuleJandexIndex module) {
|
||||
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
|
||||
IndexView indexView = module.getIndex().get();
|
||||
if (indexView != null) {
|
||||
indexView.getKnownClasses();
|
||||
Collection<ClassInfo> knownClasses = indexView.getKnownClasses();
|
||||
if (knownClasses != null) {
|
||||
for (ClassInfo info : knownClasses) {
|
||||
String name = info.name().toString();
|
||||
String pkg = name.substring(0, name.lastIndexOf('.'));
|
||||
builder.add(pkg);
|
||||
}
|
||||
if (indexFile.createNewFile()) {
|
||||
try {
|
||||
return Optional.of(JarIndexer.createJarIndex(file, new Indexer(), indexFile, false, false,
|
||||
false, System.out, System.err).getIndex());
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to index '" + file + "'", e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return Optional.of(new IndexReader(new FileInputStream(indexFile)).read());
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to read index file '" + indexFile + "'. Creating new index file.", e);
|
||||
if (indexFile.delete()) {
|
||||
return indexJar(file, indexFileFinder);
|
||||
} else {
|
||||
log.error("Failed to read index file '" + indexFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Unable to create index file '" + indexFile + "'", e);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return Optional.of(JarIndexer
|
||||
.createJarIndex(file, new Indexer(), file.canWrite(), file.getParentFile().canWrite(), false)
|
||||
.getIndex());
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to index '" + file + "'", e);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
Tuple2<File, ClassInfo> getClassByName(DotName fqName) {
|
||||
// First look for type in the base index array
|
||||
return (baseIndex == null ? Stream.<Tuple2<File, ClassInfo>>empty()
|
||||
: Arrays.stream(
|
||||
baseIndex)
|
||||
.filter(
|
||||
jandexIndex -> jandexIndex != null)
|
||||
.map(jandexIndex -> jandexIndex.getClassByName(fqName))).filter(type -> type != null)
|
||||
.findFirst()
|
||||
// If not found look at indices owned by this
|
||||
// JandexIndex instance
|
||||
.orElseGet(() -> streamOfIndices()
|
||||
.map(e -> Tuples.of(e.getT1(), Optional.ofNullable(e.getT2().getClassByName(fqName))))
|
||||
.filter(t -> t.getT2().isPresent())
|
||||
.map(e -> Tuples.of(e.getT1(), e.getT2().get())).findFirst()
|
||||
.orElse(null));
|
||||
|
||||
}
|
||||
|
||||
private Optional<Tuple2<File, ClassInfo>> findMatch(DotName fqName) {
|
||||
return (baseIndex == null ? Stream.<Optional<Tuple2<File, ClassInfo>>>empty()
|
||||
: Arrays.stream(
|
||||
baseIndex)
|
||||
.filter(
|
||||
jandexIndex -> jandexIndex != null)
|
||||
.map(jandexIndex -> jandexIndex.findMatch(fqName))).filter(o -> o.isPresent())
|
||||
.findFirst()
|
||||
// If not found look at indices owned by this
|
||||
// JandexIndex instance
|
||||
.orElseGet(() -> streamOfIndices()
|
||||
.map(e -> {
|
||||
IndexView view = e.getT2();
|
||||
ClassInfo info = view.getClassByName(fqName);
|
||||
return Tuples.of(e.getT1(), Optional.ofNullable(info));
|
||||
// return Tuples.of(e.getT1(), Optional.ofNullable(e.getT2().getClassByName(fqName)));
|
||||
})
|
||||
.filter(t -> t.getT2().isPresent())
|
||||
.map(e -> Tuples.of(e.getT1(), e.getT2().get())).findFirst());
|
||||
}
|
||||
|
||||
public Optional<File> findClasspathResourceForType(String fqName) {
|
||||
Optional<Tuple2<File, ClassInfo>> match = findMatch(DotName.createSimple(fqName));
|
||||
return Optional.ofNullable(match.isPresent() ? match.get().getT1() : null);
|
||||
}
|
||||
|
||||
private Stream<Tuple2<File, IndexView>> streamOfIndices() {
|
||||
return index.entrySet().parallelStream().map(e -> Tuples.of(e.getKey(), e.getValue().get()))
|
||||
.filter(t -> t.getT2().isPresent()).map(t -> Tuples.of(t.getT1(), t.getT2().get()));
|
||||
}
|
||||
|
||||
private Stream<Tuple3<String, File, ClassInfo>> getKnownTypesStream(File file) {
|
||||
Optional<IndexView> indexView = index.get(file).get();
|
||||
if (indexView.isPresent()) {
|
||||
return indexView.get().getKnownClasses().parallelStream()
|
||||
.map(info -> Tuples.of(info.name().toString(), file, info));
|
||||
private List<Tuple2<IJavaModuleData, ClassInfo>> getKnownTypeTuples(ModuleJandexIndex module) {
|
||||
ImmutableList.Builder<Tuple2<IJavaModuleData, ClassInfo>> builder = ImmutableList.builder();
|
||||
IndexView indexView = module.getIndex().get();
|
||||
if (indexView != null) {
|
||||
Collection<ClassInfo> knownClasses = indexView.getKnownClasses();
|
||||
if (knownClasses != null) {
|
||||
for (ClassInfo info : knownClasses) {
|
||||
builder.add(Tuples.of(module, info));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private final Stream<String> getKnownPackages(File file) {
|
||||
Optional<IndexView> indexView = index.get(file).get();
|
||||
if (indexView.isPresent()) {
|
||||
return indexView.get().getKnownClasses().parallelStream().map(info -> {
|
||||
String name = info.name().toString();
|
||||
return name.substring(0, name.lastIndexOf('.'));
|
||||
}).distinct();
|
||||
private List<Tuple2<IJavaModuleData, ClassInfo>> getAllKnownSubclasses(ModuleJandexIndex module, DotName name, boolean isInterface) {
|
||||
ImmutableList.Builder<Tuple2<IJavaModuleData, ClassInfo>> builder = ImmutableList.builder();
|
||||
IndexView indexView = module.getIndex().get();
|
||||
if (indexView != null) {
|
||||
Collection<ClassInfo> subTypes = isInterface ? indexView.getAllKnownImplementors(name) : indexView.getAllKnownSubclasses(name);
|
||||
if (subTypes != null) {
|
||||
for (ClassInfo info : subTypes) {
|
||||
builder.add(Tuples.of(module, info));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
Flux<Tuple3<File, ClassInfo, Double>> fuzzySearchTypes(String searchTerm) {
|
||||
Flux<Tuple3<File, ClassInfo, Double>> flux = Flux.fromIterable(knownTypes.values()).publishOn(Schedulers.parallel())
|
||||
.flatMap(s -> Flux.fromIterable(s.get()))
|
||||
.map(t -> Tuples.of(t.getT2(), t.getT3(), FuzzyMatcher.matchScore(searchTerm, t.getT1())))
|
||||
.filter(t -> t.getT3() != 0.0);
|
||||
if (baseIndex == null) {
|
||||
return flux;
|
||||
} else {
|
||||
return Flux.merge(flux,
|
||||
Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchTypes(searchTerm)));
|
||||
}
|
||||
Flux<Tuple3<IJavaModuleData, ClassInfo, Double>> fuzzySearchTypes(String searchTerm) {
|
||||
Flux<Tuple3<IJavaModuleData, ClassInfo, Double>> flux = Flux.fromIterable(modules).publishOn(Schedulers.parallel())
|
||||
.flatMap(m -> Flux.fromIterable(getKnownTypeTuples(m)))
|
||||
.map(t -> Tuples.of(t.getT1(), t.getT2(), FuzzyMatcher.matchScore(searchTerm, t.getT2().name().toString())))
|
||||
.filter(t -> t.getT3() != 0.0);
|
||||
|
||||
return flux;
|
||||
}
|
||||
|
||||
public Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm) {
|
||||
Flux<Tuple2<String, Double>> flux = Flux.fromIterable(knownPackages.values()).publishOn(Schedulers.parallel())
|
||||
.flatMap(s -> Flux.fromIterable(s.get()))
|
||||
.map(pkg -> Tuples.of(pkg, FuzzyMatcher.matchScore(searchTerm, pkg))).filter(t -> t.getT2() != 0.0);
|
||||
if (baseIndex == null) {
|
||||
return flux;
|
||||
} else {
|
||||
return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.fuzzySearchPackages(searchTerm)));
|
||||
}
|
||||
Flux<Tuple2<String, Double>> flux = Flux.fromIterable(modules).publishOn(Schedulers.parallel())
|
||||
.flatMap(m -> Flux.fromIterable(getKnownPackages(m)))
|
||||
.map(pkg -> Tuples.of(pkg, FuzzyMatcher.matchScore(searchTerm, pkg)))
|
||||
.filter(t -> t.getT2() != 0.0);
|
||||
|
||||
return flux;
|
||||
}
|
||||
|
||||
Flux<Tuple2<File, ClassInfo>> allSubtypesOf(DotName name, boolean isInterface) {
|
||||
Flux<Tuple2<File, ClassInfo>> flux = Flux.fromIterable(index.keySet()).publishOn(Schedulers.parallel()).flatMap(file -> {
|
||||
Optional<IndexView> optional = index.get(file).get();
|
||||
if (optional.isPresent()) {
|
||||
return Flux
|
||||
.fromIterable(isInterface ? optional.get().getAllKnownImplementors(name)
|
||||
: optional.get().getAllKnownSubclasses(name))
|
||||
.publishOn(Schedulers.parallel()).map(info -> Tuples.of(file, info));
|
||||
} else {
|
||||
return Flux.empty();
|
||||
}
|
||||
});
|
||||
if (baseIndex == null) {
|
||||
return flux;
|
||||
} else {
|
||||
return Flux.merge(flux, Flux.fromArray(baseIndex).flatMap(index -> index.allSubtypesOf(name, isInterface)));
|
||||
}
|
||||
Flux<Tuple2<IJavaModuleData, ClassInfo>> allSubtypesOf(DotName name, boolean isInterface) {
|
||||
Flux<Tuple2<IJavaModuleData, ClassInfo>> flux = Flux.fromIterable(modules).publishOn(Schedulers.parallel())
|
||||
.flatMap(module -> Flux.fromIterable(getAllKnownSubclasses(module, name, isInterface)));
|
||||
|
||||
return flux;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.jandex;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.jboss.jandex.Index;
|
||||
import org.jboss.jandex.IndexReader;
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.jboss.jandex.IndexWriter;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.jandex.JarIndexer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
public class IndexRoutines {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(IndexRoutines.class);
|
||||
|
||||
private static final URI JRT_URI = URI.create("jrt:/");
|
||||
|
||||
static ImmutableList<ModuleJandexIndex> fromClasspathBinaryEntry(File file, File indexFile) {
|
||||
ImmutableList.Builder<ModuleJandexIndex> builder = ImmutableList.builder();
|
||||
if (file != null) {
|
||||
if (file.isFile()) {
|
||||
if (file.getName().endsWith("jrt-fs.jar")) {
|
||||
builder.addAll(IndexRoutines.fromJrtFs(file, indexFile));
|
||||
} else if (file.getName().endsWith(".jar")) {
|
||||
builder.add(IndexRoutines.fromJar(file, indexFile));
|
||||
}
|
||||
} else if (file.isDirectory()) {
|
||||
builder.add(IndexRoutines.fromFolder(file));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
static ImmutableList<ModuleJandexIndex> fromCPE(CPE cpe, File indexFile) {
|
||||
File binaryLocation = IClasspathUtil.binaryLocation(cpe);
|
||||
if (cpe.isSystem()) {
|
||||
return JandexSystemLibsIndex.getInstance().index(binaryLocation.toPath());
|
||||
} else {
|
||||
return IndexRoutines.fromClasspathBinaryEntry(binaryLocation, indexFile);
|
||||
}
|
||||
}
|
||||
|
||||
private static ModuleJandexIndex fromJar(File file, File indexFile) {
|
||||
return new ModuleJandexIndex(file, null, Suppliers.memoize(() -> indexJar(file, indexFile)));
|
||||
}
|
||||
|
||||
private static ModuleJandexIndex fromFolder(File folder) {
|
||||
return new ModuleJandexIndex(folder, null, Suppliers.memoize(() -> indexFolder(folder)));
|
||||
}
|
||||
|
||||
private static ModuleJandexIndex fromModule(File container, Path modulePath, File indexFolder) {
|
||||
String module = modulePath.getFileName().toString();
|
||||
File indexFile = new File(indexFolder, module + ".jdx");
|
||||
return new ModuleJandexIndex(container, module, Suppliers.memoize(() -> indexModule(modulePath, indexFile)));
|
||||
}
|
||||
|
||||
private static ImmutableList<ModuleJandexIndex> fromJrtFs(File jrtFsJar, File indexFolder) {
|
||||
// little hack for backwards compatibility
|
||||
if (indexFolder.isFile()) {
|
||||
indexFolder.delete();
|
||||
}
|
||||
|
||||
ImmutableList.Builder<ModuleJandexIndex> builder = ImmutableList.builder();
|
||||
String javaVersion = System.getProperty("java.version"); //$NON-NLS-1$
|
||||
FileSystem fs = null;
|
||||
Path jdkHome = jrtFsJar.toPath().getParent().getParent();
|
||||
try {
|
||||
if (javaVersion != null && javaVersion.startsWith("1.8")) { //$NON-NLS-1$
|
||||
URLClassLoader loader = new URLClassLoader(new URL[] { jrtFsJar.toURI().toURL() });
|
||||
HashMap<String, ?> env = new HashMap<>();
|
||||
fs = FileSystems.newFileSystem(JRT_URI, env, loader);
|
||||
} else {
|
||||
HashMap<String, String> env = new HashMap<>();
|
||||
env.put("java.home", jdkHome.toString()); //$NON-NLS-1$
|
||||
fs = FileSystems.newFileSystem(JRT_URI, env);
|
||||
}
|
||||
if (fs != null) {
|
||||
Files.list(fs.getPath("/modules")).filter(Files::isDirectory).forEach(path -> builder.add(fromModule(jrtFsJar, path, indexFolder)));
|
||||
// builder.add(fromModule(jrtFsJar, fs.getPath("modules", "java.base"), indexFolder));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static IndexView indexModule(Path modulePath, File indexFile) {
|
||||
return createOrLoadIndex(indexFile, () -> createModuleIndex(modulePath, indexFile));
|
||||
}
|
||||
|
||||
private static IndexView createModuleIndex(Path modulePath, File indexFile) {
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(indexFile);
|
||||
Indexer indexer = new Indexer();
|
||||
Files.walk(modulePath).forEach(entry -> {
|
||||
if (entry.getFileName().toString().endsWith(".class")) {
|
||||
try {
|
||||
final InputStream stream = Files.newInputStream(entry);
|
||||
try {
|
||||
indexer.index(stream);
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
IndexWriter writer = new IndexWriter(out);
|
||||
Index index = indexer.complete();
|
||||
writer.write(index);
|
||||
return index;
|
||||
} catch (IOException e) {
|
||||
log.error("", e);
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IndexView indexFolder(File folder) {
|
||||
Indexer indexer = new Indexer();
|
||||
for (Iterator<File> itr = com.google.common.io.Files.fileTreeTraverser().breadthFirstTraversal(folder)
|
||||
.iterator(); itr.hasNext();) {
|
||||
File file = itr.next();
|
||||
if (file.isFile() && file.getName().endsWith(".class")) {
|
||||
try {
|
||||
final InputStream stream = new FileInputStream(file);
|
||||
try {
|
||||
indexer.index(stream);
|
||||
} finally {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to index file " + file, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return indexer.complete();
|
||||
}
|
||||
|
||||
private static IndexView indexJar(File file, File indexFile) {
|
||||
return createOrLoadIndex(indexFile, () -> createJarIndex(indexFile, file));
|
||||
}
|
||||
|
||||
private static IndexView createJarIndex(File indexFile, File jarFile) {
|
||||
try {
|
||||
return JarIndexer.createJarIndex(jarFile, new Indexer(), indexFile, false, false,
|
||||
false, System.out, System.err).getIndex();
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to index '" + jarFile + "'", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static IndexView createOrLoadIndex(File indexFile, Supplier<IndexView> indexCreator) {
|
||||
if (indexFile != null) {
|
||||
if (!indexFile.getParentFile().exists()) {
|
||||
indexFile.getParentFile().mkdirs();
|
||||
}
|
||||
if (!indexFile.exists()) {
|
||||
return indexCreator.get();
|
||||
} else {
|
||||
try {
|
||||
return new IndexReader(new FileInputStream(indexFile)).read();
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to read index file '" + indexFile + "'. Creating new index file.", e);
|
||||
if (indexFile.delete()) {
|
||||
return createOrLoadIndex(indexFile, indexCreator);
|
||||
} else {
|
||||
log.error("Failed to read index file '" + indexFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -31,6 +30,7 @@ import org.springframework.ide.vscode.commons.jandex.JandexIndex.JavadocProvider
|
||||
import org.springframework.ide.vscode.commons.java.ClasspathIndex;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE;
|
||||
@@ -77,13 +77,7 @@ public final class JandexClasspath implements ClasspathIndex {
|
||||
protected JandexIndex createIndex() {
|
||||
log.info("Creating JandexIndex for "+classpath.getName());
|
||||
attachFolderListeners();
|
||||
Collection<File> classpathEntries = ImmutableList.of();
|
||||
try {
|
||||
classpathEntries = IClasspathUtil.getBinaryRoots(classpath, (cpe) -> !cpe.isSystem());
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot obtain binary root from classpath entries for " + classpath.getName(), e);
|
||||
}
|
||||
return new JandexIndex(classpathEntries, jarFile -> findIndexFile(jarFile), javadocProviderFactory, getBaseIndices());
|
||||
return new JandexIndex(classpath, jarFile -> findIndexFile(jarFile), javadocProviderFactory);
|
||||
}
|
||||
|
||||
private Disposable.Composite subscriptions = Disposables.composite();
|
||||
@@ -115,10 +109,6 @@ public final class JandexClasspath implements ClasspathIndex {
|
||||
return cpe == null ? Optional.empty() : Optional.ofNullable(cpe.getSourceContainerUrl());
|
||||
}
|
||||
|
||||
protected BasicJandexIndex[] getBaseIndices() {
|
||||
return JandexSystemLibsIndex.getInstance().fromJars(IClasspathUtil.getBinaryRoots(classpath, CPE::isSystem));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType findType(String fqName) {
|
||||
return javaIndex.get().findType(fqName);
|
||||
@@ -152,7 +142,7 @@ public final class JandexClasspath implements ClasspathIndex {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<File> findClasspathResourceContainer(String fqName) {
|
||||
public IJavaModuleData findClasspathResourceContainer(String fqName) {
|
||||
return javaIndex.get().findClasspathResourceForType(fqName);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
package org.springframework.ide.vscode.commons.jandex;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -20,6 +19,8 @@ import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
|
||||
@@ -51,21 +52,22 @@ public class JandexIndex extends BasicJandexIndex {
|
||||
return javadocProviderFactory;
|
||||
}
|
||||
|
||||
public JandexIndex(Collection<File> classpathEntries, IndexFileFinder indexFileFinder,
|
||||
JavadocProviderFactory javadocProviderFactory, BasicJandexIndex... baseIndex) {
|
||||
super(classpathEntries, indexFileFinder, baseIndex);
|
||||
public JandexIndex(IClasspath classpath, IndexFileFinder indexFileFinder,
|
||||
JavadocProviderFactory javadocProviderFactory) {
|
||||
super(classpath, indexFileFinder);
|
||||
this.javadocProviderFactory = javadocProviderFactory;
|
||||
}
|
||||
|
||||
public IType findType(String fqName) {
|
||||
return createType(getClassByName(DotName.createSimple(fqName)));
|
||||
Tuple2<IJavaModuleData, ClassInfo> result = getClassByName(DotName.createSimple(fqName));
|
||||
return result == null ? null : createType(result);
|
||||
}
|
||||
|
||||
private IType createType(Tuple2<File, ClassInfo> match) {
|
||||
private IType createType(Tuple2<IJavaModuleData, ClassInfo> match) {
|
||||
if (match == null) {
|
||||
return null;
|
||||
}
|
||||
File classpathResource = match.getT1();
|
||||
File classpathResource = match.getT1().getContainer();
|
||||
IJavadocProvider javadocProvider = null;
|
||||
try {
|
||||
javadocProvider = javadocProvidersCache.get(classpathResource, () -> {
|
||||
|
||||
@@ -11,29 +11,22 @@
|
||||
package org.springframework.ide.vscode.commons.jandex;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.IllegalSelectorException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
|
||||
/**
|
||||
@@ -44,67 +37,34 @@ import com.google.common.io.BaseEncoding;
|
||||
*/
|
||||
public class JandexSystemLibsIndex {
|
||||
|
||||
private static final String DEFAULT_JAVA_VERSION = "1.8.0";
|
||||
|
||||
private static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("^java version \"(.*)\"$");
|
||||
// private static final String DEFAULT_JAVA_VERSION = "1.8.0";
|
||||
//
|
||||
// private static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("^java version \"(.*)\"$");
|
||||
|
||||
public static final Logger log = LoggerFactory.getLogger(JandexSystemLibsIndex.class);
|
||||
|
||||
private static final Supplier<JandexSystemLibsIndex> INSTANCE = Suppliers.memoize(() -> new JandexSystemLibsIndex());
|
||||
|
||||
private Cache<Path, BasicJandexIndex> cache;
|
||||
private LoadingCache<Path, ImmutableList<ModuleJandexIndex>> indexCache;
|
||||
|
||||
private JandexSystemLibsIndex() {
|
||||
this.cache = CacheBuilder.newBuilder().build(new CacheLoader<Path, BasicJandexIndex>() {
|
||||
this.indexCache = CacheBuilder.newBuilder().build(new CacheLoader<Path, ImmutableList<ModuleJandexIndex>>() {
|
||||
|
||||
@Override
|
||||
public BasicJandexIndex load(Path key) throws Exception {
|
||||
return createIndex(key);
|
||||
public ImmutableList<ModuleJandexIndex> load(Path path) throws Exception {
|
||||
File file = path.toFile();
|
||||
return IndexRoutines.fromClasspathBinaryEntry(file, findIndexFile(path));
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves or lazily creates Jandex Index for a folder containing system lib jars
|
||||
* @param path the path containing jars
|
||||
* @return Jandex Index of the jars contained in the folder
|
||||
*/
|
||||
public BasicJandexIndex index(Path path) {
|
||||
try {
|
||||
return cache.get(path, () -> createIndex(path));
|
||||
} catch (ExecutionException e) {
|
||||
log.error("Failed to detrmine Jandex index for " + path, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Jandex Indexes appropriate for systm lib jars. One Jandex Index may contain all sys lib jars.
|
||||
* @param jars system lib jars
|
||||
* @return Jandex Indexs for jars
|
||||
*/
|
||||
public BasicJandexIndex[] fromJars(Collection<File> jars) {
|
||||
return jars.stream().map(jar -> jar.toPath().getParent()).distinct().map(folder -> index(folder)).filter(Objects::nonNull).toArray(BasicJandexIndex[]::new);
|
||||
}
|
||||
|
||||
public static JandexSystemLibsIndex getInstance() {
|
||||
return INSTANCE.get();
|
||||
}
|
||||
|
||||
private BasicJandexIndex createIndex(Path path) {
|
||||
List<File> jars = Collections.emptyList();
|
||||
try {
|
||||
jars = Files.list(path).filter(p -> p.getFileName().toString().endsWith(".jar") && Files.isRegularFile(p)).map(p -> p.toFile()).collect(Collectors.toList());
|
||||
} catch (IOException e) {
|
||||
// Shouldn't happen - there should at least be one jar file
|
||||
log.error("Cannot list files in folder " + path, e);
|
||||
}
|
||||
return new BasicJandexIndex(jars, jarFile -> findIndexFile(jarFile));
|
||||
}
|
||||
|
||||
private File findIndexFile(File jarFile) {
|
||||
return Paths.get(System.getProperty("user.home"), ".sts4-jandex", folderNameforPath(jarFile.getParentFile().toString()), jarFile.getName() + ".jdx").toFile();
|
||||
private File findIndexFile(Path path) {
|
||||
return Paths.get(System.getProperty("user.home"), ".sts4-jandex", folderNameforPath(path.getParent().toString()), path.getFileName() + ".jdx").toFile();
|
||||
}
|
||||
|
||||
private static String folderNameforPath(String path) {
|
||||
@@ -120,6 +80,15 @@ public class JandexSystemLibsIndex {
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutableList<ModuleJandexIndex> index(Path path) {
|
||||
try {
|
||||
return indexCache.get(path);
|
||||
} catch (ExecutionException e) {
|
||||
log.error("", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// private static String getJavaVersion(Path path) {
|
||||
// // Find valid /bin folder
|
||||
// for (; path != null && !(Files.isDirectory(path.resolve("bin")) && Files.isReadable(path.resolve("bin"))); path = path.getParent());
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.jandex;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
class ModuleJandexIndex implements IJavaModuleData {
|
||||
|
||||
private Supplier<IndexView> index;
|
||||
|
||||
private File container;
|
||||
|
||||
private String module;
|
||||
|
||||
public ModuleJandexIndex(File container, String module, Supplier<IndexView> index) {
|
||||
this.container = container;
|
||||
this.module = module;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Supplier<IndexView> getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModuleJandexIndex [container=" + container + ", module=" + module + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
package org.springframework.ide.vscode.commons.jandex;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -25,6 +24,7 @@ import org.jboss.jandex.Type;
|
||||
import org.springframework.ide.vscode.commons.java.Flags;
|
||||
import org.springframework.ide.vscode.commons.java.IAnnotation;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
@@ -36,9 +36,9 @@ class TypeImpl implements IType {
|
||||
private ClassInfo info;
|
||||
private JandexIndex index;
|
||||
private IJavadocProvider javadocProvider;
|
||||
private File classpathContainer;
|
||||
private IJavaModuleData classpathContainer;
|
||||
|
||||
TypeImpl(JandexIndex index, File classpathContainer, ClassInfo info, IJavadocProvider javadocProvider) {
|
||||
TypeImpl(JandexIndex index, IJavaModuleData classpathContainer, ClassInfo info, IJavadocProvider javadocProvider) {
|
||||
this.info = info;
|
||||
this.index = index;
|
||||
this.classpathContainer = classpathContainer;
|
||||
@@ -154,7 +154,7 @@ class TypeImpl implements IType {
|
||||
}
|
||||
|
||||
@Override
|
||||
public File classpathContainer() {
|
||||
public IJavaModuleData classpathContainer() {
|
||||
return classpathContainer;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ package org.springframework.ide.vscode.commons.jandex;
|
||||
|
||||
import static org.springframework.ide.vscode.commons.util.Assert.isNotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.AnnotationValue;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
@@ -26,6 +24,7 @@ import org.jboss.jandex.Type;
|
||||
import org.jboss.jandex.Type.Kind;
|
||||
import org.springframework.ide.vscode.commons.java.IAnnotation;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaType;
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.java.IMemberValuePair;
|
||||
@@ -36,11 +35,11 @@ import org.springframework.ide.vscode.commons.java.IVoidType;
|
||||
|
||||
public class Wrappers {
|
||||
|
||||
public static IType wrap(JandexIndex index, File classpathContainer, ClassInfo info, IJavadocProvider javadocProvider) {
|
||||
public static IType wrap(JandexIndex index, IJavaModuleData moduleContainer, ClassInfo info, IJavadocProvider javadocProvider) {
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
return new TypeImpl(index, classpathContainer, info, javadocProvider);
|
||||
return new TypeImpl(index, moduleContainer, info, javadocProvider);
|
||||
}
|
||||
|
||||
public static IField wrap(IType declaringType, FieldInfo field, IJavadocProvider javadocProvider) {
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -38,38 +36,4 @@ public class BootProjectUtil {
|
||||
String name = cpe.getName();
|
||||
return name.endsWith(".jar") && name.startsWith("spring-boot");
|
||||
}
|
||||
|
||||
public static Path javaHomeFromLibJar(Path libJar) {
|
||||
Path root = libJar.getRoot();
|
||||
for (Path home = libJar; !root.equals(home.getParent()); home = home.getParent()) {
|
||||
Path bin = home.resolve("bin");
|
||||
Path lib = home.resolve("lib");
|
||||
Path include = home.resolve("include");
|
||||
Path man = home.resolve("man");
|
||||
if (Files.isDirectory(bin) && Files.isDirectory(lib) && Files.isDirectory(include) && Files.isDirectory(man)) {
|
||||
return home;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Path jreSources(Path libJar) {
|
||||
Path home = javaHomeFromLibJar(libJar);
|
||||
if (home != null) {
|
||||
Path sources = sourceZip(home);
|
||||
if (sources == null) {
|
||||
sources = sourceZip(home.resolve("lib"));
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Path sourceZip(Path containerFolder) {
|
||||
Path sourcesZip = containerFolder.resolve("src.zip");
|
||||
if (Files.exists(sourcesZip)) {
|
||||
return sourcesZip;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public interface ClasspathIndex extends Disposable {
|
||||
Flux<Tuple2<String, Double>> fuzzySearchPackages(String searchTerm);
|
||||
Flux<IType> allSubtypesOf(IType type);
|
||||
Flux<IType> allSuperTypesOf(IType type);
|
||||
Optional<File> findClasspathResourceContainer(String fqName);
|
||||
IJavaModuleData findClasspathResourceContainer(String fqName);
|
||||
|
||||
//Maybe the stuff below is another interface? Something that provides operations
|
||||
// on classpaths?
|
||||
|
||||
@@ -68,7 +68,7 @@ public class IClasspathUtil {
|
||||
return Objects.equals(canonicalFile, classpathEntryFile);
|
||||
}
|
||||
|
||||
private static File binaryLocation(CPE cpe) {
|
||||
public static File binaryLocation(CPE cpe) {
|
||||
switch (cpe.getKind()) {
|
||||
case Classpath.ENTRY_KIND_BINARY:
|
||||
return canonicalFile(cpe.getPath());
|
||||
|
||||
@@ -10,15 +10,13 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface IField extends IMember {
|
||||
boolean isEnumConstant();
|
||||
|
||||
IJavaType type();
|
||||
|
||||
@Override
|
||||
default File classpathContainer() {
|
||||
default IJavaModuleData classpathContainer() {
|
||||
return getDeclaringType().classpathContainer();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2018 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.io.File;
|
||||
|
||||
public interface IJavaModuleData {
|
||||
|
||||
File getContainer();
|
||||
|
||||
String getModule();
|
||||
|
||||
}
|
||||
@@ -57,7 +57,7 @@ public interface IJavaProject {
|
||||
return getIndex().getClasspathResources();
|
||||
}
|
||||
|
||||
default Optional<File> findClasspathResourceContainer(String fqName) {
|
||||
default IJavaModuleData findClasspathResourceContainer(String fqName) {
|
||||
return getIndex().findClasspathResourceContainer(fqName);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public interface IMember extends IJavaElement, IAnnotatable {
|
||||
|
||||
/**
|
||||
@@ -45,7 +43,7 @@ public interface IMember extends IJavaElement, IAnnotatable {
|
||||
*/
|
||||
IType getDeclaringType();
|
||||
|
||||
File classpathContainer();
|
||||
IJavaModuleData classpathContainer();
|
||||
|
||||
String signature();
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface IMethod extends IMember {
|
||||
@@ -68,7 +67,7 @@ public interface IMethod extends IMember {
|
||||
boolean isConstructor();
|
||||
|
||||
@Override
|
||||
default File classpathContainer() {
|
||||
default IJavaModuleData classpathContainer() {
|
||||
return getDeclaringType().classpathContainer();
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.java;
|
||||
package org.springframework.ide.vscode.commons.java;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
@@ -82,8 +82,45 @@ public class JavaUtils {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return tokenized[0];
|
||||
String version = tokenized[0];
|
||||
int idx = version.indexOf('+');
|
||||
return idx >= 0 ? version.substring(0, idx) : version;
|
||||
}
|
||||
}
|
||||
|
||||
public static Path javaHomeFromLibJar(Path libJar) {
|
||||
Path root = libJar.getRoot();
|
||||
for (Path home = libJar; !root.equals(home.getParent()); home = home.getParent()) {
|
||||
Path bin = home.resolve("bin");
|
||||
Path lib = home.resolve("lib");
|
||||
Path include = home.resolve("include");
|
||||
Path man = home.resolve("man");
|
||||
Path legal = home.resolve("legal");
|
||||
if (Files.isDirectory(bin) && Files.isDirectory(lib) && Files.isDirectory(include) && (Files.isDirectory(man) || Files.isDirectory(legal))) {
|
||||
return home;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Path jreSources(Path libJar) {
|
||||
Path home = javaHomeFromLibJar(libJar);
|
||||
if (home != null) {
|
||||
Path sources = JavaUtils.sourceZip(home);
|
||||
if (sources == null) {
|
||||
sources = JavaUtils.sourceZip(home.resolve("lib"));
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Path sourceZip(Path containerFolder) {
|
||||
Path sourcesZip = containerFolder.resolve("src.zip");
|
||||
if (Files.exists(sourcesZip)) {
|
||||
return sourcesZip;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,7 +13,6 @@ package org.springframework.ide.vscode.commons.javadoc;
|
||||
import java.net.URL;
|
||||
|
||||
import org.springframework.ide.vscode.commons.java.IJavadocProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE;
|
||||
|
||||
public class JavaDocProviders {
|
||||
@@ -26,7 +25,7 @@ public class JavaDocProviders {
|
||||
? TypeUrlProviderFromContainerUrl.JAR_JAVADOC_URL_PROVIDER
|
||||
: TypeUrlProviderFromContainerUrl.JAVADOC_FOLDER_URL_SUPPLIER;
|
||||
return new HtmlJavadocProvider(
|
||||
type -> urlProvider.url(classpathEntry.getJavadocContainerUrl(), type.getFullyQualifiedName())
|
||||
type -> urlProvider.url(classpathEntry.getJavadocContainerUrl(), type.getFullyQualifiedName(), type.classpathContainer().getModule())
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -16,29 +16,34 @@ import java.nio.file.Paths;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface TypeUrlProviderFromContainerUrl {
|
||||
|
||||
|
||||
static String extractTopLevelType(String fqName) {
|
||||
int innerTypeIdx = fqName.indexOf('$');
|
||||
return innerTypeIdx > 0 ? fqName.substring(0, innerTypeIdx) : fqName;
|
||||
}
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl JAR_SOURCE_URL_PROVIDER = (jarSourceUrl, fqName) -> {
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl JAR_SOURCE_URL_PROVIDER = (jarSourceUrl, fqName, module) -> {
|
||||
StringBuilder urlStr = new StringBuilder();
|
||||
urlStr.append("jar:");
|
||||
urlStr.append(jarSourceUrl);
|
||||
urlStr.append("!");
|
||||
urlStr.append('/');
|
||||
if (module != null) {
|
||||
urlStr.append(module);
|
||||
urlStr.append('/');
|
||||
}
|
||||
urlStr.append(extractTopLevelType(fqName).replaceAll("\\.", "/"));
|
||||
urlStr.append(".java");
|
||||
return new URL(urlStr.toString());
|
||||
|
||||
};
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl SOURCE_FOLDER_URL_SUPPLIER = (sourceContainerUrl, fqName) -> {
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl SOURCE_FOLDER_URL_SUPPLIER = (sourceContainerUrl, fqName, module) -> {
|
||||
// Unclear how to deal with modules and source folders at the moment hence module is ignored
|
||||
return Paths.get(sourceContainerUrl.toURI()).resolve(extractTopLevelType(fqName).replaceAll("\\.", "/") + ".java").toUri().toURL();
|
||||
};
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl JAR_JAVADOC_URL_PROVIDER = (javadocContainerUrl, fqName) -> {
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl JAR_JAVADOC_URL_PROVIDER = (javadocContainerUrl, fqName, module) -> {
|
||||
StringBuilder urlStr = new StringBuilder();
|
||||
urlStr.append("jar:");
|
||||
urlStr.append(javadocContainerUrl);
|
||||
@@ -50,8 +55,8 @@ public interface TypeUrlProviderFromContainerUrl {
|
||||
return new URL(urlStr.toString());
|
||||
|
||||
};
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl JAVADOC_FOLDER_URL_SUPPLIER = (javadocContainerUrl, fqName) -> {
|
||||
|
||||
public static final TypeUrlProviderFromContainerUrl JAVADOC_FOLDER_URL_SUPPLIER = (javadocContainerUrl, fqName, module) -> {
|
||||
String urlStr = javadocContainerUrl.toString();
|
||||
StringBuilder sb = new StringBuilder(urlStr);
|
||||
if (!urlStr.endsWith("/")) {
|
||||
@@ -61,7 +66,7 @@ public interface TypeUrlProviderFromContainerUrl {
|
||||
sb.append(fqName.replaceAll("\\.", "/").replaceAll("\\$", ".") + ".html");
|
||||
return new URL(sb.toString());
|
||||
};
|
||||
|
||||
URL url(URL containerUrl, String fqName) throws Exception;
|
||||
|
||||
URL url(URL containerUrl, String fqName, String module) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ import org.eclipse.aether.util.graph.visitor.CloningDependencyVisitor;
|
||||
import org.eclipse.aether.util.graph.visitor.FilteringDependencyVisitor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaUtils;
|
||||
import org.springframework.ide.vscode.commons.java.JavaUtils;
|
||||
|
||||
/**
|
||||
* Maven Core functionality
|
||||
|
||||
@@ -22,9 +22,9 @@ import java.util.Set;
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.model.Resource;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.springframework.ide.vscode.commons.java.BootProjectUtil;
|
||||
import org.springframework.ide.vscode.commons.java.ClasspathData;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.JavaUtils;
|
||||
import org.springframework.ide.vscode.commons.languageserver.jdt.ls.Classpath.CPE;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenCore;
|
||||
import org.springframework.ide.vscode.commons.maven.MavenException;
|
||||
@@ -92,7 +92,7 @@ public class MavenProjectClasspath implements IClasspath {
|
||||
cpe.setSystem(true);
|
||||
entries.add(cpe);
|
||||
// Add at the end, not critical if throws exception, but the CPE needs to be around regardless if the below throws
|
||||
Path sources = BootProjectUtil.jreSources(path);
|
||||
Path sources = JavaUtils.jreSources(path);
|
||||
if (sources != null) {
|
||||
cpe.setSourceContainerUrl(sources.toUri().toURL());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.nio.file.Paths;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
@@ -33,6 +34,8 @@ import org.springframework.ide.vscode.commons.util.FileObserver;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
@Ignore
|
||||
//@EnabledOnJre(JAVA_8)
|
||||
public class HtmlJavadocTest {
|
||||
|
||||
private static FileObserver fileObserver = new BasicFileObserver();
|
||||
|
||||
@@ -17,20 +17,19 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.springframework.ide.vscode.languageserver.testharness.ClasspathTestUtil.getOutputFolder;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.java.Flags;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IMethod;
|
||||
import org.springframework.ide.vscode.commons.java.IPrimitiveType;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
@@ -103,6 +102,15 @@ public class JavaIndexTest {
|
||||
assertNotNull(type);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void findStringStripMethodinJDK() throws Exception {
|
||||
// MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
// IType type = project.findType("java.lang.String");
|
||||
// assertNotNull(type);
|
||||
// IMethod method = type.getMethod("strip", Stream.empty());
|
||||
// assertNotNull(method);
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void findClassInOutputFolder() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
@@ -154,18 +162,18 @@ public class JavaIndexTest {
|
||||
@Test
|
||||
public void testFindJarResource() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
Optional<File> jar = project.findClasspathResourceContainer("org.springframework.boot.autoconfigure.SpringBootApplication");
|
||||
assertTrue(jar.isPresent());
|
||||
assertEquals("spring-boot-autoconfigure-1.4.1.RELEASE.jar", jar.get().getName());
|
||||
IJavaModuleData module = project.findClasspathResourceContainer("org.springframework.boot.autoconfigure.SpringBootApplication");
|
||||
assertNotNull(module);
|
||||
assertEquals("spring-boot-autoconfigure-1.4.1.RELEASE.jar", module.getContainer().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindJavaResource() throws Exception {
|
||||
MavenJavaProject project = mavenProjectsCache.get("gs-rest-service-cors-boot-1.4.1-with-classpath-file");
|
||||
Optional<File> file = project.findClasspathResourceContainer("hello.GreetingController");
|
||||
assertTrue(file.isPresent());
|
||||
assertTrue(file.get().exists());
|
||||
assertEquals(getOutputFolder(project).toString(), file.get().toString());
|
||||
IJavaModuleData module = project.findClasspathResourceContainer("hello.GreetingController");
|
||||
assertNotNull(module);
|
||||
assertTrue(module.getContainer().exists());
|
||||
assertEquals(getOutputFolder(project).toString(), module.getContainer().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.javadoc.TypeUrlProviderFromContainerUrl;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
@@ -50,13 +51,13 @@ public abstract class AbstractSourceLinks implements SourceLinks {
|
||||
|
||||
@Override
|
||||
public Optional<String> sourceLinkUrlForFQName(IJavaProject project, String fqName) {
|
||||
Optional<File> classpathResource = project.getIndex().findClasspathResourceContainer(fqName);
|
||||
if (classpathResource.isPresent()) {
|
||||
File file = classpathResource.get();
|
||||
IJavaModuleData classpathResource = project.getIndex().findClasspathResourceContainer(fqName);
|
||||
if (classpathResource != null) {
|
||||
File file = classpathResource.getContainer();
|
||||
if (file.isDirectory()) {
|
||||
return javaSourceLinkUrl(project, fqName, file);
|
||||
return javaSourceLinkUrl(project, fqName, classpathResource);
|
||||
} else {
|
||||
return jarSourceLinkUrl(project, fqName, file);
|
||||
return jarSourceLinkUrl(project, fqName, classpathResource);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
@@ -74,7 +75,7 @@ public abstract class AbstractSourceLinks implements SourceLinks {
|
||||
|
||||
|
||||
|
||||
private Optional<String> javaSourceLinkUrl(IJavaProject project, String fqName, File containerFolder) {
|
||||
private Optional<String> javaSourceLinkUrl(IJavaProject project, String fqName, IJavaModuleData folderModuleData) {
|
||||
IClasspath classpath = project.getClasspath();
|
||||
return SourceLinks.sourceFromSourceFolder(fqName, classpath)
|
||||
.map(sourcePath -> javaSourceLinkUrl(project, sourcePath, fqName));
|
||||
@@ -95,19 +96,19 @@ public abstract class AbstractSourceLinks implements SourceLinks {
|
||||
return cuCache == null ? Optional.empty() : cuCache.withCompilationUnit(project, uri, compilationUnit -> Optional.ofNullable(compilationUnit));
|
||||
}
|
||||
|
||||
abstract protected Optional<String> jarLinkUrl(IJavaProject project, String fqName, File jarFile);
|
||||
abstract protected Optional<String> jarLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData);
|
||||
|
||||
private Optional<String> jarSourceLinkUrl(IJavaProject project, String fqName, File jarFile) {
|
||||
return jarLinkUrl(project, fqName, jarFile).map(sourceUrl -> {
|
||||
Optional<String> positionLink = findCUForFQNameFromJar(project, jarFile, fqName).map(cu -> positionLink(cu, fqName));
|
||||
private Optional<String> jarSourceLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData) {
|
||||
return jarLinkUrl(project, fqName, jarModuleData).map(sourceUrl -> {
|
||||
Optional<String> positionLink = findCUForFQNameFromJar(project, jarModuleData, fqName).map(cu -> positionLink(cu, fqName));
|
||||
return positionLink.isPresent() ? sourceUrl + positionLink.get() : sourceUrl;
|
||||
});
|
||||
}
|
||||
|
||||
private Optional<CompilationUnit> findCUForFQNameFromJar(IJavaProject project, File jarFile, String fqName) {
|
||||
return project.sourceContainer(jarFile).map(url -> {
|
||||
private Optional<CompilationUnit> findCUForFQNameFromJar(IJavaProject project, IJavaModuleData jarModuleData, String fqName) {
|
||||
return project.sourceContainer(jarModuleData.getContainer()).map(url -> {
|
||||
try {
|
||||
return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(url, fqName);
|
||||
return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(url, fqName, jarModuleData.getModule());
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to determine source URL from url={} fqName={}", url, fqName, e);
|
||||
return null;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.links;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.file.Path;
|
||||
@@ -20,6 +19,7 @@ import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class AtomSourceLinks extends AbstractSourceLinks {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> jarLinkUrl(IJavaProject project, String fqName, File jarFile) {
|
||||
protected Optional<String> jarLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData) {
|
||||
// JAR URLs are not supported yet
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@ package org.springframework.ide.vscode.boot.java.links;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
|
||||
public class JdtJavaDocumentUriProvider implements JavaDocumentUriProvider {
|
||||
@@ -30,9 +30,9 @@ public class JdtJavaDocumentUriProvider implements JavaDocumentUriProvider {
|
||||
}
|
||||
|
||||
public static URI uri(IJavaProject project, String fqName) {
|
||||
Optional<File> classpathResource = project.getIndex().findClasspathResourceContainer(fqName);
|
||||
if (classpathResource.isPresent()) {
|
||||
File file = classpathResource.get();
|
||||
IJavaModuleData classpathResource = project.getIndex().findClasspathResourceContainer(fqName);
|
||||
if (classpathResource != null) {
|
||||
File file = classpathResource.getContainer();
|
||||
if (file.isDirectory()) {
|
||||
IClasspath classpath = project.getClasspath();
|
||||
return SourceLinks.sourceFromSourceFolder(fqName, classpath).map(path -> path.toUri()).orElse(null);
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.links;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
@@ -23,6 +22,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspath;
|
||||
import org.springframework.ide.vscode.commons.java.IClasspathUtil;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.javadoc.TypeUrlProviderFromContainerUrl;
|
||||
|
||||
@@ -54,7 +54,7 @@ public interface SourceLinks {
|
||||
})
|
||||
.map(url -> {
|
||||
try {
|
||||
return TypeUrlProviderFromContainerUrl.SOURCE_FOLDER_URL_SUPPLIER.url(url, fqName);
|
||||
return TypeUrlProviderFromContainerUrl.SOURCE_FOLDER_URL_SUPPLIER.url(url, fqName, /* module */ null);
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to determine source URL from url={} fqName=", url, fqName, e);
|
||||
return null;
|
||||
@@ -73,31 +73,30 @@ public interface SourceLinks {
|
||||
}
|
||||
|
||||
public static Optional<URL> source(IJavaProject project, String fqName) {
|
||||
Optional<File> classpathResourceContainer = project.findClasspathResourceContainer(fqName);
|
||||
// Try to find in a source JAR
|
||||
Optional<URL> url = classpathResourceContainer
|
||||
.flatMap(file -> project.sourceContainer(file))
|
||||
.map(file -> {
|
||||
IJavaModuleData classpathResourceContainer = project.findClasspathResourceContainer(fqName);
|
||||
if (classpathResourceContainer != null) {
|
||||
Optional<URL> url = project.sourceContainer(classpathResourceContainer.getContainer()).map(file -> {
|
||||
try {
|
||||
return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(file, fqName, classpathResourceContainer.getModule());
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
});
|
||||
|
||||
if (!url.isPresent()) {
|
||||
// Try Source folder
|
||||
url = sourceFromSourceFolder(fqName, project.getClasspath()).map(p -> {
|
||||
try {
|
||||
return TypeUrlProviderFromContainerUrl.JAR_SOURCE_URL_PROVIDER.url(file, fqName);
|
||||
} catch (Exception e) {
|
||||
return p.toUri().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (!url.isPresent()) {
|
||||
// Try Source folder
|
||||
url = classpathResourceContainer
|
||||
.flatMap(file -> sourceFromSourceFolder(fqName, project.getClasspath()).map(p -> {
|
||||
try {
|
||||
return p.toUri().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
return url;
|
||||
}
|
||||
return url;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.boot.java.links;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.jdt.core.dom.CompilationUnit;
|
||||
import org.springframework.ide.vscode.boot.java.utils.CompilationUnitCache;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaModuleData;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.Region;
|
||||
|
||||
@@ -55,7 +55,7 @@ public class VSCodeSourceLinks extends AbstractSourceLinks {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<String> jarLinkUrl(IJavaProject project, String fqName, File jarFile) {
|
||||
protected Optional<String> jarLinkUrl(IJavaProject project, String fqName, IJavaModuleData jarModuleData) {
|
||||
return Optional.ofNullable(JdtJavaDocumentUriProvider.uri(project, fqName)).map(uri -> uri.toString());
|
||||
}
|
||||
|
||||
|
||||
@@ -39,19 +39,18 @@ import com.google.common.collect.ImmutableSet;
|
||||
public class LoggerNameProviderTest {
|
||||
|
||||
private static final String[] JBOSS_RESULTS = {
|
||||
"com.fasterxml.jackson.databind.jsonFormatVisitors", //1
|
||||
// org.jboss is not really a package...
|
||||
// "org.jboss", //2
|
||||
"org.jboss.logging", //3
|
||||
"org.jboss.logging.JBossLogManagerLogger", //4
|
||||
"org.jboss.logging.JBossLogManagerProvider", //5
|
||||
"org.jboss.logging.JBossLogRecord", //6
|
||||
"org.springframework.instrument.classloading.jboss", //7
|
||||
"org.springframework.instrument.classloading.jboss.JBossClassLoaderAdapter", //8
|
||||
"org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver", //9
|
||||
"org.springframework.instrument.classloading.jboss.JBossMCAdapter", //10
|
||||
"org.springframework.instrument.classloading.jboss.JBossMCTranslatorAdapter", //11
|
||||
"org.springframework.instrument.classloading.jboss.JBossModulesAdapter" //12
|
||||
// "org.jboss", //1
|
||||
"org.jboss.logging", //2
|
||||
"org.jboss.logging.JBossLogManagerLogger", //3
|
||||
"org.jboss.logging.JBossLogManagerProvider", //4
|
||||
"org.jboss.logging.JBossLogRecord", //5
|
||||
"org.springframework.instrument.classloading.jboss", //6
|
||||
"org.springframework.instrument.classloading.jboss.JBossClassLoaderAdapter", //7
|
||||
"org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver", //8
|
||||
"org.springframework.instrument.classloading.jboss.JBossMCAdapter", //9
|
||||
"org.springframework.instrument.classloading.jboss.JBossMCTranslatorAdapter", //10
|
||||
"org.springframework.instrument.classloading.jboss.JBossModulesAdapter" //11
|
||||
};
|
||||
|
||||
private ProjectsHarness projects = ProjectsHarness.INSTANCE;
|
||||
|
||||
Reference in New Issue
Block a user