package org.objectstyle.wolips.jrebel.utils;
/* BSD Licensed : Originally from http://pmd.svn.sourceforge.net/svnroot/pmd as JavaProjectClassLoader */
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
/**
* This is a ClassLoader for the Build Path of an IJavaProject.
*/
public class WOProjectClassLoader extends URLClassLoader {
// private static final Logger log = Logger.getLogger(JavaProjectClassLoader.class);
private Set<IJavaProject> javaProjects = new HashSet<IJavaProject>();
private Set<URL> urls = new HashSet<URL>();
private IWorkspaceRoot workspaceRoot;
public WOProjectClassLoader(ClassLoader parent, IJavaProject javaProject) {
super(new URL[0], parent);
workspaceRoot = javaProject.getProject().getWorkspace().getRoot();
addURLs(javaProject, false);
// No longer need these things, drop references
javaProjects = null;
workspaceRoot = null;
urls = null;
}
private void addURLs(IJavaProject javaProject, boolean exportsOnly) {
if (!javaProjects.contains(javaProject)) {
javaProjects.add(javaProject);
try {
// Add default output location
addURL(javaProject.getOutputLocation());
// Add each classpath entry
IClasspathEntry[] classpathEntries = javaProject.getResolvedClasspath(true);
for (IClasspathEntry classpathEntry : classpathEntries) {
if (classpathEntry.isExported() || !exportsOnly) {
switch (classpathEntry.getEntryKind()) {
// Recurse on projects
case IClasspathEntry.CPE_PROJECT:
IProject project = javaProject.getProject().getWorkspace().getRoot().getProject(classpathEntry.getPath().toString());
IJavaProject javaProj = JavaCore.create(project);
if (javaProj != null) {
addURLs(javaProj, true);
}
break;
// Library
case IClasspathEntry.CPE_LIBRARY:
addURL(classpathEntry);
break;
// Only Source entries with custom output location need to be added
case IClasspathEntry.CPE_SOURCE:
IPath outputLocation = classpathEntry.getOutputLocation();
if (outputLocation != null) {
addURL(outputLocation);
}
break;
// Variable and Container entries should not be happening, because
// we've asked for resolved entries.
case IClasspathEntry.CPE_VARIABLE:
case IClasspathEntry.CPE_CONTAINER:
break;
}
}
}
} catch (JavaModelException e) {
e.printStackTrace();
// log.debug("MalformedURLException occurred: " + e.getLocalizedMessage(),e);
}
}
}
private void addURL(IClasspathEntry classpathEntry) {
addURL(classpathEntry.getPath());
}
private void addURL(IPath path) {
try {
if (workspaceRoot.exists(path)) {
path = workspaceRoot.getLocation().append(path);
}
if (isBundleFramework(path)) {
URL url = path.removeLastSegments(3).toFile().getAbsoluteFile().toURL();
addURL(url);
}
URL url = path.toFile().getAbsoluteFile().toURL();
addURL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
// log.debug("MalformedURLException occurred: " + e.getLocalizedMessage(),e);
}
}
@Override
protected void addURL(URL url) {
if (!urls.contains(url)) {
urls.add(url);
super.addURL(url);
}
}
private boolean isBundleFramework(IPath path) {
int count = path.segmentCount() - 1;
if ("jar".equals(path.getFileExtension()) && "Java".equals(path.segment(--count)) && "Resources".equals(path.segment(--count)))
return true;
return false;
}
}