org.openxma.dsl.common.jdt.JdtClasspathUriResolverPlus Maven / Gradle / Ivy
package org.openxma.dsl.common.jdt;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.IJavaElement;
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.internal.core.JarPackageFragmentRoot;
import org.eclipse.xtext.resource.ClasspathUriResolutionException;
import org.eclipse.xtext.resource.ClasspathUriUtil;
import org.eclipse.xtext.resource.IClasspathUriResolver;
/**
* Source code copied from {@link JdtClasspathUriResolvers} and slightly modified to handle
* emf jar uris. (e.g. model files stored in external jar files)
*/
@SuppressWarnings("restriction")
public class JdtClasspathUriResolverPlus implements IClasspathUriResolver {
private static final String ARCHIVE_SEPARATOR = "!/";
private static final String SCHEME_JAR = "jar:file:";
private Map uriMap = new HashMap();
private IJavaElement javaElement;
public URI resolve(Object context, URI classpathUri) {
if (!(context instanceof IJavaElement)) {
throw new IllegalArgumentException(
"Context must implement IResource");
}
javaElement = (IJavaElement) context;
try {
if (ClasspathUriUtil.isClasspathUri(classpathUri)) {
IJavaProject javaProject = javaElement.getJavaProject();
String string = classpathUri.toString();
URI findResourceInWorkspace = uriMap.get(string);
if (null==findResourceInWorkspace) {
findResourceInWorkspace= findResourceInWorkspace(javaProject, classpathUri);
uriMap.put(string,findResourceInWorkspace);
}
return findResourceInWorkspace;
}
} catch (Exception exc) {
throw new ClasspathUriResolutionException(exc);
}
return classpathUri;
}
protected static URI findResourceInWorkspace(IJavaProject javaProject,
URI classpathUri) throws JavaModelException, CoreException {
Path fullPath = new Path(classpathUri.path());
String projectRelativePath = fullPath.toString().charAt(0)=='/' ? fullPath.toString().substring(1):fullPath.toString();
if (javaProject.exists()) {
IPackageFragmentRoot[] allPackageFragmentRoots = javaProject
.getAllPackageFragmentRoots();
for (IPackageFragmentRoot packageFragmentRoot : allPackageFragmentRoots) {
IResource correspondingResource = packageFragmentRoot
.getCorrespondingResource();
if (correspondingResource != null
&& correspondingResource instanceof IFile) {
// plugin or project jar file
JarPackageFragmentRoot jarPackageFragmentRoot = (JarPackageFragmentRoot) JavaCore
.createJarPackageFragmentRootFrom((IFile) correspondingResource);
if (jarPackageFragmentRoot != null) {
ZipFile zipFile = jarPackageFragmentRoot.getJar();
if (zipFile != null) {
ZipEntry zipEntry = zipFile
.getEntry(projectRelativePath);
if (zipEntry != null) {
return URI.createURI("jar:"
+ "platform:/resource"
+ correspondingResource.getFullPath()
+ "!" + projectRelativePath, true);
}
}
}
} else if (null == correspondingResource) {
// external jar file
try {
URL jarUrl = new URL(SCHEME_JAR
+ packageFragmentRoot.getPath().toString()
+ ARCHIVE_SEPARATOR);
JarURLConnection conn = (JarURLConnection) jarUrl
.openConnection();
JarFile jarfile = conn.getJarFile();
ZipEntry zipEntry = jarfile
.getEntry(projectRelativePath);
if (zipEntry != null) {
return URI.createURI(SCHEME_JAR + packageFragmentRoot.getPath().toString()
+ ARCHIVE_SEPARATOR + projectRelativePath, true);
}
} catch (UnknownHostException ioException) {
ioException.printStackTrace();
// ignore it
} catch (IOException ioException) {
// ignore it
}
} else {
// folder
IFolder rootFolder = null;
if (correspondingResource instanceof IFolder) {
rootFolder = (IFolder) correspondingResource;
} else {
rootFolder = getRootFromExternalPackageFragmentRoot(
packageFragmentRoot);
}
if (rootFolder != null) {
IResource modelFile = rootFolder
.findMember(projectRelativePath);
if (modelFile != null && modelFile.exists()
&& modelFile instanceof IFile) {
URI platformResourceUri = URI
.createPlatformResourceURI(modelFile
.getFullPath().toString(), true);
return platformResourceUri;
}
}
}
}
}
return classpathUri;
}
private static IFolder getRootFromExternalPackageFragmentRoot(
IPackageFragmentRoot packageFragmentRoot) {
IFolder rootFolder = null;
try {
Class> externalPackageFragmentRootClass = Class
.forName("org.eclipse.jdt.internal.core.ExternalPackageFragmentRoot");
if (externalPackageFragmentRootClass
.isInstance(packageFragmentRoot)) {
Method resourceMethod = packageFragmentRoot.getClass().getMethod("resource");
if(resourceMethod != null) {
IResource resource = (IResource) resourceMethod.invoke(packageFragmentRoot);
if (resource instanceof IFolder) {
rootFolder = (IFolder) resource;
}
}
}
} catch (Exception e) {
// Class does not exist in Eclipse 3.3
}
return rootFolder;
}
}