diff options
Diffstat (limited to 'examples/org.eclipse.emf.generic.editor/src/org/eclipse/emf/editor/provider/ClasspathUriResolver.java')
-rw-r--r-- | examples/org.eclipse.emf.generic.editor/src/org/eclipse/emf/editor/provider/ClasspathUriResolver.java | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/examples/org.eclipse.emf.generic.editor/src/org/eclipse/emf/editor/provider/ClasspathUriResolver.java b/examples/org.eclipse.emf.generic.editor/src/org/eclipse/emf/editor/provider/ClasspathUriResolver.java new file mode 100644 index 00000000..bfea5350 --- /dev/null +++ b/examples/org.eclipse.emf.generic.editor/src/org/eclipse/emf/editor/provider/ClasspathUriResolver.java @@ -0,0 +1,196 @@ +package org.eclipse.emf.editor.provider; + +/** + * <copyright> + * + * Copyright (c) 2008 itemis AG and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * itemis AG - Initial API and implementation + * + * </copyright> + * + */ + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +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.IProject; +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.osgi.baseadaptor.BaseData; +import org.eclipse.osgi.framework.internal.core.BundleHost; +import org.eclipse.osgi.framework.internal.core.BundleURLConnection; +import org.osgi.framework.Bundle; + +/** + * Resolves a classpath URI to a file URI or platform:/resource URI. + * + * A classpath URI has the following form: + * + * <pre> + * classpath:/<java package>/<resource file name> + * <pre> + * </pre> + * + * A classpath URI can only be resolved in the context of a classpath. This can + * either be given + * <ul> + * <li>by a Java project in workspace + * <li>by the global classloader of a standalone Java application. + * </ul> + * It can only be resolved if the referenced resource file can be located. It + * does not matter if it is contained in a jar or exists as a plain file. + * + * @author koehnlein + */ +public class ClasspathUriResolver { + + public static final String CLASSPATH_SCHEME = "classpath"; + + public URI resolve(ClassLoader classLoader, URI classpathUri) { + try { + if (isClassapthUri(classpathUri)) { + return findResourceOnClasspath(classLoader, classpathUri); + } + } + catch (Exception exc) { + throw new ClasspathUriResolutionException(exc); + } + return classpathUri; + } + + public URI resolve(IResource resource, URI classpathUri) { + try { + if (isClassapthUri(classpathUri)) { + IProject project = resource.getProject(); + IJavaProject javaProject = JavaCore.create(project); + return findResourceInWorkspace(javaProject, classpathUri); + } + } + catch (Exception exc) { + throw new ClasspathUriResolutionException(exc); + } + return classpathUri; + } + + public URI resolve(IJavaElement javaElement, URI classpathUri) { + try { + if (isClassapthUri(classpathUri)) { + IJavaProject javaProject = javaElement.getJavaProject(); + return findResourceInWorkspace(javaProject, classpathUri); + } + } + catch (Exception exc) { + throw new ClasspathUriResolutionException(exc); + } + return classpathUri; + } + + public URI resolve(Bundle bundle, URI classpathUri) { + try { + if (isClassapthUri(classpathUri)) { + return findResourceInBundle(bundle, classpathUri); + } + } + catch (Exception exc) { + throw new ClasspathUriResolutionException(exc); + } + return classpathUri; + } + + public static boolean isClassapthUri(URI uri) { + String scheme = uri.scheme(); + return CLASSPATH_SCHEME.equals(scheme); + } + + private URI findResourceOnClasspath(ClassLoader classLoader, URI classpathUri) throws URISyntaxException { + String pathAsString = classpathUri.path(); + if (classpathUri.hasAbsolutePath()) { + pathAsString = pathAsString.substring(1); + } + URL resource = classLoader.getResource(pathAsString); + URI fileUri = URI.createURI(resource.toURI().toString()); + return fileUri; + } + + @SuppressWarnings("restriction") + private URI findResourceInBundle(Bundle bundle, URI classpathUri) throws MalformedURLException, IOException { + Path fullPath = new Path(classpathUri.path()); + if (bundle != null) { + String projectRelativePath = "/" + fullPath; + URL resourceUrl = bundle.getResource(projectRelativePath); + if (resourceUrl != null) { + String baseUrl = ((BaseData) ((BundleHost) bundle).getBundleData()).getBundleFile().getBaseFile() + .toURL().toString(); + if (baseUrl.endsWith(".jar")) { + baseUrl = "jar:" + baseUrl + "!/"; + } + String localUrl = ((BundleURLConnection) resourceUrl.openConnection()).getLocalURL().toString(); + String platformPluginUri = bundle.getSymbolicName() + "/" + localUrl.substring(baseUrl.length()); + URI normalizedURI = URI.createPlatformPluginURI(platformPluginUri, true); + return normalizedURI; + } + } + return classpathUri; + } + + @SuppressWarnings("restriction") + private URI findResourceInWorkspace(IJavaProject javaProject, URI classpathUri) throws JavaModelException, + CoreException { + Path fullPath = new Path(classpathUri.path()); + String projectRelativePath = fullPath.toString(); + if (javaProject.exists()) { + IPackageFragmentRoot[] allPackageFragmentRoots = javaProject.getAllPackageFragmentRoots(); + for (IPackageFragmentRoot packageFragmentRoot : allPackageFragmentRoots) { + IResource correspondingResource = packageFragmentRoot.getCorrespondingResource(); + if (correspondingResource != null) { + if (correspondingResource instanceof IFile) { + // jar file + JarPackageFragmentRoot jarPackageFragmentRoot = (JarPackageFragmentRoot) JavaCore + .createJarPackageFragmentRootFrom((IFile) correspondingResource); + if (jarPackageFragmentRoot != null) { + ZipFile zipFile = jarPackageFragmentRoot.getJar(); + if (zipFile != null) { + ZipEntry zipEntry = zipFile.getEntry(projectRelativePath.substring(1)); + if (zipEntry != null) { + return URI.createURI("jar:" + "platform:/resource" + + correspondingResource.getFullPath() + "!" + projectRelativePath, true); + } + } + } + } + else { + // plain file + IFolder rootFolder = (IFolder) correspondingResource; + 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; + } +}
\ No newline at end of file |