246 lines
8.0 KiB
Java
246 lines
8.0 KiB
Java
/*******************************************************************************
|
|
* Copyright (c) 2008 IBM Corporation.
|
|
* 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:
|
|
* IBM Corporation - initial API and implementation
|
|
*******************************************************************************/
|
|
package com.ibm.wala.ide.util;
|
|
|
|
import java.io.File;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Method;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.util.jar.JarFile;
|
|
|
|
import org.eclipse.core.runtime.FileLocator;
|
|
import org.eclipse.core.runtime.IPath;
|
|
import org.eclipse.core.runtime.Path;
|
|
import org.eclipse.core.runtime.Platform;
|
|
import org.eclipse.core.runtime.Plugin;
|
|
import org.osgi.framework.Bundle;
|
|
|
|
import com.ibm.wala.classLoader.JarFileModule;
|
|
import com.ibm.wala.classLoader.Module;
|
|
import com.ibm.wala.ide.plugin.CorePlugin;
|
|
import com.ibm.wala.util.debug.Assertions;
|
|
import com.ibm.wala.util.io.FileProvider;
|
|
|
|
public class EclipseFileProvider extends FileProvider {
|
|
|
|
/**
|
|
* the plug-in to use. If <code>null</code>, {@link CorePlugin#getDefault()} is used.
|
|
*/
|
|
private final Plugin plugIn;
|
|
|
|
public EclipseFileProvider() {
|
|
this(null);
|
|
}
|
|
|
|
public EclipseFileProvider(Plugin plugIn) {
|
|
this.plugIn = plugIn;
|
|
}
|
|
/**
|
|
* This class uses reflection to access classes and methods that are only
|
|
* available when Eclipse is running as an IDE environment. The choice to use
|
|
* reflection is related to builds: with this design the build doesn't need to
|
|
* provide IDE bundles during compilation and hence can spot invalid uses of
|
|
* such classes through this bundle.
|
|
*
|
|
* Because of this class, this bundle must OPTIONALY require
|
|
* 'org.eclipse.core.resources'.
|
|
*/
|
|
private static final class EclipseUtil {
|
|
private static Object workspaceRoot = null;
|
|
private static Method workspaceRoot_getFile = null;
|
|
|
|
public static Module getJarFileModule(String fileName) {
|
|
// Using reflection to enable this code to be built without the
|
|
// org.eclipse.core.resources bundle
|
|
//
|
|
try {
|
|
if (workspaceRoot_getFile == null) {
|
|
Class<?> cls = Class.forName("org.eclipse.core.resources.ResourcesPlugin");
|
|
Method getWorkspaceMethod = cls.getDeclaredMethod("getWorkspace");
|
|
Object workspace = getWorkspaceMethod.invoke(null);
|
|
Method getRoot = workspace.getClass().getDeclaredMethod("getRoot");
|
|
workspaceRoot = getRoot.invoke(workspace);
|
|
workspaceRoot_getFile = workspaceRoot.getClass().getMethod("getFile", IPath.class);
|
|
}
|
|
|
|
IPath path = new Path(fileName);
|
|
if (workspaceRoot_getFile.invoke(workspaceRoot, path) != null) {
|
|
return new JarFileModule(new JarFile(fileName, false));
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Module getJarFileModule(String fileName, ClassLoader loader) throws IOException {
|
|
if (CorePlugin.getDefault() == null) {
|
|
return getJarFileFromClassLoader(fileName, loader);
|
|
} else if (plugIn != null) {
|
|
return getFromPlugin(plugIn, fileName);
|
|
} else if (CorePlugin.IS_RESOURCES_BUNDLE_AVAILABLE) {
|
|
Module module = EclipseUtil.getJarFileModule(fileName);
|
|
if (module != null) {
|
|
return module;
|
|
}
|
|
}
|
|
return getFromPlugin(CorePlugin.getDefault(), fileName);
|
|
}
|
|
|
|
/**
|
|
* @param fileName
|
|
* @return the jar file packaged with this plug-in of the given name, or null
|
|
* if not found.
|
|
*/
|
|
private JarFileModule getFromPlugin(Plugin p, String fileName) throws IOException {
|
|
URL url = getFileURLFromPlugin(p, fileName);
|
|
return (url == null) ? null : new JarFileModule(new JarFile(filePathFromURL(url)));
|
|
}
|
|
|
|
/**
|
|
* get a file URL for a file from a plugin
|
|
*
|
|
* @param fileName
|
|
* the file name
|
|
* @return the URL, or <code>null</code> if the file is not found
|
|
* @throws IOException
|
|
*/
|
|
private URL getFileURLFromPlugin(Plugin p, String fileName) throws IOException {
|
|
try {
|
|
URL url = FileLocator.find(p.getBundle(), new Path(fileName), null);
|
|
if (url == null) {
|
|
// try lib/fileName
|
|
String libFileName = "lib/" + fileName;
|
|
url = FileLocator.find(p.getBundle(), new Path(libFileName), null);
|
|
if (url == null) {
|
|
// try bin/fileName
|
|
String binFileName = "bin/" + fileName;
|
|
url = FileLocator.find(p.getBundle(), new Path(binFileName), null);
|
|
if (url == null) {
|
|
// try it as an absolute path?
|
|
File f = new File(fileName);
|
|
if (!f.exists()) {
|
|
// give up
|
|
return null;
|
|
} else {
|
|
url = f.toURI().toURL();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
url = FileLocator.toFileURL(url);
|
|
url = fixupFileURLSpaces(url);
|
|
return url;
|
|
} catch (ExceptionInInitializerError e) {
|
|
throw new IOException("failure to get file URL for " + fileName);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* escape spaces in a URL, primarily to work around a bug in
|
|
* {@link File#toURL()}
|
|
*
|
|
* @param url
|
|
* @return an escaped version of the URL
|
|
*/
|
|
private URL fixupFileURLSpaces(URL url) {
|
|
String urlString = url.toExternalForm();
|
|
StringBuffer fixedUpUrl = new StringBuffer();
|
|
int lastIndex = 0;
|
|
while (true) {
|
|
int spaceIndex = urlString.indexOf(' ', lastIndex);
|
|
|
|
if (spaceIndex < 0) {
|
|
fixedUpUrl.append(urlString.substring(lastIndex));
|
|
break;
|
|
}
|
|
|
|
fixedUpUrl.append(urlString.substring(lastIndex, spaceIndex));
|
|
fixedUpUrl.append("%20");
|
|
lastIndex = spaceIndex + 1;
|
|
}
|
|
try {
|
|
return new URL(fixedUpUrl.toString());
|
|
} catch (MalformedURLException e) {
|
|
e.printStackTrace();
|
|
Assertions.UNREACHABLE();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public URL getResource(String fileName, ClassLoader loader) throws IOException {
|
|
if (fileName == null) {
|
|
throw new IllegalArgumentException("null fileName");
|
|
}
|
|
Plugin p = plugIn == null ? CorePlugin.getDefault() : plugIn;
|
|
if (p == null && loader == null) {
|
|
throw new IllegalArgumentException("null loader");
|
|
}
|
|
return (p == null) ? loader.getResource(fileName) : FileLocator.find(p.getBundle(),
|
|
new Path(fileName), null);
|
|
}
|
|
|
|
@Override
|
|
public File getFile(String fileName, ClassLoader loader) throws IOException {
|
|
Plugin p = plugIn == null ? CorePlugin.getDefault() : plugIn;
|
|
return (p == null) ? getFileFromClassLoader(fileName, loader) : getFileFromPlugin(
|
|
p, fileName);
|
|
}
|
|
|
|
/**
|
|
* @param fileName
|
|
* @return the jar file packaged with this plug-in of the given name, or null
|
|
* if not found.
|
|
* @throws IllegalArgumentException
|
|
* if p is null
|
|
*/
|
|
public File getFileFromPlugin(Plugin p, String fileName) throws IOException {
|
|
|
|
if (p == null) {
|
|
throw new IllegalArgumentException("p is null");
|
|
}
|
|
if (fileName == null) {
|
|
throw new IllegalArgumentException("null fileName");
|
|
}
|
|
URL url = getFileURLFromPlugin(p, fileName);
|
|
if (url == null) {
|
|
throw new FileNotFoundException(fileName);
|
|
}
|
|
return new File(filePathFromURL(url));
|
|
}
|
|
|
|
/**
|
|
* This is fragile. Use with care.
|
|
* @return a String representing the path to the wala.core plugin installation
|
|
*/
|
|
public static String getWalaCorePluginHome() {
|
|
if (CorePlugin.getDefault() == null) {
|
|
return null;
|
|
}
|
|
String install = Platform.getInstallLocation().getURL().getPath();
|
|
Bundle b = Platform.getBundle("com.ibm.wala.core");
|
|
String l = b.getLocation();
|
|
if (l.startsWith("update@")) {
|
|
l = l.replace("update@", "");
|
|
}
|
|
if (l.startsWith("reference:file:")) {
|
|
return l.replace("reference:file:","");
|
|
} else {
|
|
return install + File.separator + l;
|
|
}
|
|
}
|
|
|
|
}
|