Skip to content

Add referenced libraries as reference container #113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 20, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ public class PackageCommand {

private static final String DEFAULT_PACKAGE_DISPLAYNAME = "(default package)";

private static final String REFERENCED_LIBRARIES_PATH = "REFERENCED_LIBRARIES_PATH";

private static final String REFERENCED_LIBRARIES_CONTAINER_NAME = "Referenced Libraries";

private static final ContainerNode REFERENCED_LIBRARIES_CONTAINER = new ContainerNode(REFERENCED_LIBRARIES_CONTAINER_NAME, REFERENCED_LIBRARIES_PATH,
NodeKind.CONTAINER, IClasspathEntry.CPE_CONTAINER);

private static final Gson gson = new GsonBuilder().registerTypeAdapterFactory(new CollectionTypeAdapterFactory())
.registerTypeAdapterFactory(new EnumTypeAdapterFactory()).create();

Expand Down Expand Up @@ -97,7 +104,6 @@ public static List<PackageNode> getChildren(List<Object> arguments, IProgressMon
throw new IllegalArgumentException("Should have at least one arugment for getChildren");
}
PackageParams params = gson.fromJson(gson.toJson(arguments.get(0)), PackageParams.class);

BiFunction<PackageParams, IProgressMonitor, List<PackageNode>> loader = commands.get(params.getKind());
if (loader == null) {
throw new CoreException(new Status(IStatus.ERROR, JdtlsExtActivator.PLUGIN_ID, String.format("Unknown classpath item type: %s", params.getKind())));
Expand Down Expand Up @@ -144,7 +150,13 @@ public static List<PackageNode> resolvePath(List<Object> arguments, IProgressMon
IPackageFragmentRoot pkgRoot = (IPackageFragmentRoot) packageFragment.getParent();
PackageNode rootNode = null;
if (typeRoot instanceof IClassFile) {
rootNode = new PackageRootNode(pkgRoot.getElementName(), pkgRoot.getPath().toPortableString(), NodeKind.PACKAGEROOT, pkgRoot.getKind());
IClasspathEntry entry = pkgRoot.getRawClasspathEntry();
// Process Referenced Variable
if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
rootNode = getNodeFromClasspathVariable(entry);
} else {
rootNode = new PackageRootNode(pkgRoot.getElementName(), pkgRoot.getPath().toPortableString(), NodeKind.PACKAGEROOT, pkgRoot.getKind());
}
} else {
rootNode = new PackageRootNode(ExtUtils.removeProjectSegment(typeRoot.getJavaProject().getElementName(), pkgRoot.getPath()).toPortableString(),
pkgRoot.getPath().toPortableString(), NodeKind.PACKAGEROOT, pkgRoot.getKind());
Expand All @@ -154,8 +166,13 @@ public static List<PackageNode> resolvePath(List<Object> arguments, IProgressMon
if (typeRoot instanceof IClassFile) {
IClasspathEntry entry = pkgRoot.getRawClasspathEntry();
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), typeRoot.getJavaProject());
PackageNode containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER,
entry.getEntryKind());
PackageNode containerNode = null;
if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
containerNode = REFERENCED_LIBRARIES_CONTAINER;
} else {
containerNode = new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER,
entry.getEntryKind());
}
result.add(containerNode);
}
result.add(rootNode);
Expand All @@ -174,36 +191,80 @@ public static List<PackageNode> resolvePath(List<Object> arguments, IProgressMon
*/
private static List<PackageNode> getContainers(PackageParams query, IProgressMonitor pm) {
IJavaProject javaProject = getJavaProject(query.getProjectUri());

if (javaProject != null) {
try {
IClasspathEntry[] references = javaProject.getRawClasspath();
return Arrays.stream(references).map(entry -> {
try {
entry = JavaCore.getResolvedClasspathEntry(entry);
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
// HACK: There is an initialization issue for the first container.
if (container == null) {
container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
}

if (container != null) {
return new ContainerNode(container.getDescription(), container.getPath().toPortableString(), NodeKind.CONTAINER,
entry.getEntryKind());
}
} catch (CoreException e) {
// Ignore it
}
return null;
}).filter(containerNode -> containerNode != null).collect(Collectors.toList());
List<PackageNode> result = Arrays.stream(references)
.filter(entry -> entry.getEntryKind() != IClasspathEntry.CPE_LIBRARY && entry.getEntryKind() != IClasspathEntry.CPE_VARIABLE)
.map(entry -> getNodeFromClasspathEntry(entry, javaProject, NodeKind.CONTAINER)).filter(containerNode -> containerNode != null)
.collect(Collectors.toList());
boolean isReferencedLibrariesExist = Arrays.stream(references)
.anyMatch(entry -> entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE);
if (isReferencedLibrariesExist) {
result.add(REFERENCED_LIBRARIES_CONTAINER);
}
return result;
} catch (CoreException e) {
JdtlsExtActivator.logException("Problem load project library ", e);
}
}
return Collections.emptyList();
}

/**
* Get the correspond node of classpath, it may be container or a package root
*
* @param classpathEntry
* classpath entry
* @param javaProject
* correspond java project
* @param nodeKind
* could be CONTAINER or PACKAGEROOT(for referenced libraries)
* @return correspond PackageNode of classpath entry
*/
private static PackageNode getNodeFromClasspathEntry(IClasspathEntry classpathEntry, IJavaProject javaProject, NodeKind nodeKind) {
try {
IClasspathEntry entry = JavaCore.getResolvedClasspathEntry(classpathEntry);
IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
// HACK: There is an initialization issue for the first container.
if (container == null) {
container = JavaCore.getClasspathContainer(entry.getPath(), javaProject);
}
if (container != null) {
switch (nodeKind) {
case CONTAINER:
return new ContainerNode(container.getDescription(), container.getPath().toPortableString(), nodeKind, entry.getEntryKind());
case PACKAGEROOT:
// Use package name as package root name
String[] pathSegments = container.getPath().segments();
return new PackageRootNode(pathSegments[pathSegments.length - 1], container.getPath().toPortableString(), nodeKind,
IPackageFragmentRoot.K_BINARY);
default:
return null;
}
}
} catch (CoreException e) {
JdtlsExtActivator.logException("Problems when convert classpath entry to package node ", e);
}
return null;
}

/**
* Get correspond node of referenced variable
*
* @param classpathEntry
* referenced cariable's classpath entry
* @return correspond package node
*/
private static PackageNode getNodeFromClasspathVariable(IClasspathEntry classpathEntry) {
IClasspathEntry entry = JavaCore.getResolvedClasspathEntry(classpathEntry);
String name = classpathEntry.getPath().toPortableString();
String path = entry.getPath().toPortableString();
return new PackageRootNode(name, path, NodeKind.PACKAGEROOT, IPackageFragmentRoot.K_BINARY);
}

private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IProgressMonitor pm) {
ArrayList<PackageNode> children = new ArrayList<>();
IJavaProject javaProject = getJavaProject(query.getProjectUri());

if (javaProject != null) {
Expand All @@ -217,7 +278,6 @@ private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IP
}
}
if (containerEntry != null) {
ArrayList<PackageNode> children = new ArrayList<>();
IPackageFragmentRoot[] packageFragmentRoots = javaProject.findPackageFragmentRoots(containerEntry);
for (IPackageFragmentRoot fragmentRoot : packageFragmentRoots) {
String displayName = fragmentRoot.getElementName();
Expand All @@ -232,6 +292,16 @@ private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IP
}
}
return children;
} else if (query.getPath().equals(REFERENCED_LIBRARIES_PATH)) {
// Process referenced libraries
List<PackageNode> referLibs = Arrays.stream(references).filter(entry -> entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY)
.map(classpath -> getNodeFromClasspathEntry(classpath, javaProject, NodeKind.PACKAGEROOT)).filter(entry -> entry != null)
.collect(Collectors.toList());
List<PackageNode> referVariables = Arrays.stream(references).filter(entry -> entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE)
.map(classpath -> getNodeFromClasspathVariable(classpath)).filter(entry -> entry != null).collect(Collectors.toList());
children.addAll(referLibs);
children.addAll(referVariables);
return children;
}
} catch (CoreException e) {
JdtlsExtActivator.logException("Problem load project JAR entries ", e);
Expand All @@ -243,9 +313,7 @@ private static List<PackageNode> getPackageFragmentRoots(PackageParams query, IP

private static List<PackageNode> getPackages(PackageParams query, IProgressMonitor pm) {
IJavaProject javaProject = getJavaProject(query.getProjectUri());

if (javaProject != null) {

try {
IPackageFragmentRoot packageRoot = javaProject.findPackageFragmentRoot(Path.fromPortableString(query.getRootPath()));
if (packageRoot == null) {
Expand Down Expand Up @@ -274,7 +342,7 @@ private static List<PackageNode> getRootTypes(PackageParams query, IProgressMoni
if (packageFragment != null) {
IJavaElement[] types = packageFragment.getChildren();
Object[] nonJavaResources = packageFragment.getNonJavaResources();
List<PackageNode> rootTypeNodes = Arrays.stream(types).filter(typeRoot -> !typeRoot.getElementName().contains("$")).map(typeRoot -> {
List<PackageNode> rootTypeNodes = Arrays.stream(types).filter(typeRoot -> !typeRoot.getElementName().contains("$")).map(typeRoot -> {
PackageNode item = new TypeRootNode(typeRoot.getElementName(), typeRoot.getPath().toPortableString(), NodeKind.TYPEROOT,
typeRoot instanceof IClassFile ? TypeRootNode.K_BINARY : TypeRootNode.K_SOURCE);
if (typeRoot instanceof ICompilationUnit) {
Expand All @@ -289,20 +357,20 @@ private static List<PackageNode> getRootTypes(PackageParams query, IProgressMoni
}
// when .java files and other .properties files are mixed up
rootTypeNodes.addAll(
Arrays.stream(nonJavaResources).filter(resource -> resource instanceof IFile || resource instanceof JarEntryFile).map(resource -> {
if (resource instanceof IFile) {
IFile file = (IFile) resource;
PackageNode item = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
item.setUri(JDTUtils.getFileURI(file));
return item;
} else {
JarEntryFile file = (JarEntryFile) resource;
PackageNode entry = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
entry.setUri(ExtUtils.toUri((JarEntryFile) resource));
return entry;
}

}).collect(Collectors.toList()));
Arrays.stream(nonJavaResources).filter(resource -> resource instanceof IFile || resource instanceof JarEntryFile).map(resource -> {
if (resource instanceof IFile) {
IFile file = (IFile) resource;
PackageNode item = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
item.setUri(JDTUtils.getFileURI(file));
return item;
} else {
JarEntryFile file = (JarEntryFile) resource;
PackageNode entry = new PackageNode(file.getName(), file.getFullPath().toPortableString(), NodeKind.FILE);
entry.setUri(ExtUtils.toUri((JarEntryFile) resource));
return entry;
}

}).collect(Collectors.toList()));
return rootTypeNodes;
}
} catch (CoreException e) {
Expand Down