org.openxma.dsl.common.jdt.JdtResourceLoader Maven / Gradle / Ivy
package org.openxma.dsl.common.jdt;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.mwe.core.resources.ResourceLoader;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.JavaModel;
import com.google.common.collect.Sets;
@SuppressWarnings("restriction")
public class JdtResourceLoader implements ResourceLoader {
private ResourceLoader delegate;
private Set visitedProjects;
private ClassLoader classLoader;
/**
* @param project
* the project to load classpath entries from
* @param parent
* the parent ClassLoader
for delegation first
* @param parent
* the parent ResourceLoader
for delegation first
*/
public JdtResourceLoader(IProject project, ClassLoader parent, ResourceLoader parentResourceLoader) {
Set classPathEntryUrls = getClassPathEntryUrls(JavaCore.create(project));
this.classLoader = new ChildFirstUrlClassloader((URL[]) classPathEntryUrls.toArray(new URL[classPathEntryUrls.size()]),
parent,new String[]{"org.openxma."},new String[0],new String[]{".xpt",".properties",".ext"});
this.delegate = parentResourceLoader;
}
public URL getResource(String uri) {
URL resource = classLoader.getResource(uri);
return resource != null ? resource : delegate.getResource(uri);
}
public InputStream getResourceAsStream(String uri) {
InputStream inputStream = classLoader.getResourceAsStream(uri);
return inputStream != null ? inputStream : delegate.getResourceAsStream(uri);
}
public Class> loadClass(String clazzName) {
try {
Class> clazz = classLoader.loadClass(clazzName);
return clazz != null ? clazz : delegate.loadClass(clazzName);
} catch (ClassNotFoundException exception) {
throw new WrappedException(exception);
}
}
/**
* Get the path for a project
*
* This works also for projects which are imported to a workspace without copying them into the workspace.
*
* @param project
* The project for which the path should be determined.
* @return The path of the project
*/
protected IPath pathForProject(IJavaProject project) {
IPath projectPath = project.getResource().getRawLocation();
// projectPath is only defined for imported projects with a different location
if (projectPath == null) {
IPath workspaceRootPath = ResourcesPlugin.getWorkspace().getRoot().getRawLocation();
projectPath = workspaceRootPath.append(project.getPath());
}
return projectPath;
}
private Set getClassPathEntryUrls(IJavaProject project) {
if (project == null) {
throw new IllegalArgumentException("The parameter project has not to be null");
}
HashSet result = Sets.newHashSet();
IPath workspaceRootPath = ResourcesPlugin.getWorkspace().getRoot().getRawLocation();
IPath projectPath = pathForProject(project);
if (visitedProjects == null) {
visitedProjects = Sets.newHashSet();
}
visitedProjects.add(project);
try {
IClasspathEntry[] javacp = project.getResolvedClasspath(true);
for (IClasspathEntry classpathEntry : javacp) {
switch (classpathEntry.getEntryKind()) {
case IClasspathEntry.CPE_SOURCE:
IPath outputFolder = classpathEntry.getOutputLocation();
if (outputFolder != null) {
result.add(workspaceRootPath.append(outputFolder).toFile().toURI().toURL());
} else {
if (project.getOutputLocation().segmentCount() == 0) {
// This means that not even the (relative) project location (which is
// usually the first segment) is defined.
throw new RuntimeException("A project output location with 0 segments is not supported");
}
IPath projectOutputFolder = project.getOutputLocation().removeFirstSegments(1);
result.add(projectPath.append(projectOutputFolder).toFile().toURI().toURL());
}
break;
case IClasspathEntry.CPE_PROJECT:
IWorkspaceRoot root = project.getCorrespondingResource().getWorkspace().getRoot();
String entryPath = classpathEntry.getPath().toString();
IProject requiredProject = root.getProject(entryPath);
if (!visitedProjects.contains(requiredProject) && requiredProject.hasNature(JavaCore.NATURE_ID)) {
result.addAll(getClassPathEntryUrls(JavaCore.create(requiredProject)));
}
break;
default:
File absolutePath = classpathEntry.getPath().toFile();
Object target = JavaModel.getTarget(classpathEntry.getPath(), true);
if (target instanceof IResource) {
IResource targetResource = (IResource) target;
absolutePath = targetResource.getLocation().toFile();
} else if (target instanceof File) {
absolutePath = (File) target;
}
result.add(absolutePath.toURI().toURL());
}
}
} catch (Exception exception) {
throw new WrappedException(exception);
}
return result;
}
}