package org.eclipse.jdt.internal.launching;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.DirectorySourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.ExternalArchiveSourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer;
import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;
public class JavaSourceLookupUtil {
public static ISourceContainer[] translate(IRuntimeClasspathEntry[] entries) {
List<ISourceContainer> containers = new ArrayList<>(entries.length);
for (int i = 0; i < entries.length; i++) {
IRuntimeClasspathEntry entry = entries[i];
switch (entry.getType()) {
case IRuntimeClasspathEntry.ARCHIVE:
if (entry.getPath().lastSegment().equals("jrt-fs.jar")) {
getPackageFragmentRootContainers(entry, containers);
} else {
IPackageFragmentRoot root = getPackageFragmentRoot(entry);
if (root == null) {
addSourceAttachment(entry, containers);
} else {
ISourceContainer container = new PackageFragmentRootSourceContainer(root);
if (!containers.contains(container)) {
containers.add(container);
}
}
}
break;
case IRuntimeClasspathEntry.PROJECT:
IResource resource = entry.getResource();
if (resource != null && resource.getType() == IResource.PROJECT) {
IJavaProject javaProject = JavaCore.create((IProject)resource);
ISourceContainer container = null;
if (javaProject.exists()) {
container = new JavaProjectSourceContainer(javaProject);
} else if (resource.exists()) {
container = new ProjectSourceContainer((IProject)resource, false);
}
if (container != null && !containers.contains(container)) {
containers.add(container);
}
}
break;
default:
break;
}
}
return containers.toArray(new ISourceContainer[containers.size()]);
}
private static void addSourceAttachment(IRuntimeClasspathEntry entry, List<ISourceContainer> containers) {
String path = entry.getSourceAttachmentLocation();
ISourceContainer container = null;
if (path == null) {
path = entry.getLocation();
}
if (path != null) {
File file = new File(path);
if (file.isDirectory()) {
IResource resource = entry.getResource();
if (resource instanceof IContainer) {
container = new FolderSourceContainer((IContainer) resource, false);
} else {
container = new DirectorySourceContainer(file, false);
}
} else {
container = new ExternalArchiveSourceContainer(path, true);
}
if (!containers.contains(container)) {
containers.add(container);
}
}
}
private static boolean isSourceAttachmentEqual(IPackageFragmentRoot root, IRuntimeClasspathEntry entry) throws JavaModelException {
IPath entryPath = entry.getSourceAttachmentPath();
if (entryPath == null) {
return true;
}
IPath rootPath = root.getSourceAttachmentPath();
if (rootPath == null) {
return false;
}
return rootPath.equals(entryPath);
}
private static IPackageFragmentRoot getPackageFragmentRoot(IRuntimeClasspathEntry entry) {
IResource resource = entry.getResource();
if (resource != null) {
IProject project = resource.getProject();
IJavaProject jp = JavaCore.create(project);
try {
if (project.isOpen() && jp.exists()) {
IPackageFragmentRoot root = jp.findPackageFragmentRoot(resource.getFullPath());
if (root != null && isSourceAttachmentEqual(root, entry)) {
return root;
}
}
} catch (JavaModelException e) {
LaunchingPlugin.log(e);
}
}
IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
IPath entryPath = entry.getPath();
try {
IJavaProject[] jps = model.getJavaProjects();
for (int i = 0; i < jps.length; i++) {
IJavaProject jp = jps[i];
IProject p = jp.getProject();
if (p.isOpen()) {
IPackageFragmentRoot[] allRoots = jp.getPackageFragmentRoots();
for (int j = 0; j < allRoots.length; j++) {
IPackageFragmentRoot root = allRoots[j];
if (root.getPath().equals(entryPath) && isSourceAttachmentEqual(root, entry)) {
return root;
}
}
}
}
} catch (JavaModelException e) {
LaunchingPlugin.log(e);
}
return null;
}
private static void getPackageFragmentRootContainers(IRuntimeClasspathEntry entry, List<ISourceContainer> containers) {
IJavaModel model = JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
IPath entryPath = entry.getPath();
boolean found = false;
try {
IJavaProject[] jps = model.getJavaProjects();
for (int i = 0; i < jps.length; i++) {
IJavaProject jp = jps[i];
IProject p = jp.getProject();
if (p.isOpen()) {
IPackageFragmentRoot[] allRoots = jp.getPackageFragmentRoots();
for (int j = 0; j < allRoots.length; j++) {
IPackageFragmentRoot root = allRoots[j];
if (root.getPath().equals(entryPath) && isSourceAttachmentEqual(root, entry)) {
PackageFragmentRootSourceContainer container = new PackageFragmentRootSourceContainer(root);
if (!containers.contains(container)) {
containers.add(container);
found = true;
}
}
}
}
}
}
catch (JavaModelException e) {
LaunchingPlugin.log(e);
}
if (!found) {
addSourceAttachment(entry, containers);
}
}
}