delete obsolete code
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1920 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
0074f4e6c5
commit
9eb07d255e
|
@ -1,664 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 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.util.scope;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import org.osgi.framework.Constants;
|
||||
|
||||
import com.ibm.wala.classLoader.ArrayClassLoader;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.emf.wrappers.EMFScopeWrapper;
|
||||
import com.ibm.wala.emf.wrappers.JavaScopeUtil;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.properties.WalaProperties;
|
||||
import com.ibm.wala.types.ClassLoaderReference;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.util.Atom;
|
||||
import com.ibm.wala.util.ImmutableByteArray;
|
||||
import com.ibm.wala.util.collections.FifoQueueNoDuplicates;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
|
||||
/**
|
||||
* This class is used to build the complete analysis scope for analyzing an
|
||||
* Eclipse plugin.
|
||||
* <p>
|
||||
* Given an Eclipse plugin, this class detects all the other plugins that should
|
||||
* be part of the analysis scope when analyzing the given plugin.
|
||||
*
|
||||
* This is buggy in that it ignores the Import-Package declarations in the
|
||||
* manifest. This is a problem. Probably the way to go is to recode this whole
|
||||
* thing using a headless Eclipse instance, and rely on Eclipse APIs to resolve
|
||||
* dependencies the right way.
|
||||
*
|
||||
* @author Marco Pistoia
|
||||
* @author Stephen Fink
|
||||
*/
|
||||
@Deprecated
|
||||
public class EclipseAnalysisScope extends AnalysisScope {
|
||||
|
||||
public static final boolean DEBUG = true;
|
||||
|
||||
private static final String ECLIPSE_PRODUCT_NAME = ".eclipseproduct";
|
||||
|
||||
/**
|
||||
* We delegate tracking the analysis scope to this object
|
||||
*/
|
||||
private final EMFScopeWrapper delegate;
|
||||
|
||||
/**
|
||||
* <code>byte</code> value indicating the Eclipse version.
|
||||
*/
|
||||
private byte version;
|
||||
|
||||
/**
|
||||
* <code>byte</code> value indicating the Eclipse subversion. Default value
|
||||
* is 0.
|
||||
*/
|
||||
private byte subversion = 0;
|
||||
|
||||
/**
|
||||
* A Set containing String objects, each String object representing the plugin
|
||||
* id of a plug-in, fragment, or bundle being analyzed.
|
||||
*/
|
||||
final private Set<String> pluginIds = HashSetFactory.make();
|
||||
|
||||
/**
|
||||
* name of plugin being analyzed
|
||||
*/
|
||||
private final String pluginName;
|
||||
|
||||
/**
|
||||
* absolute name of plugins directory in Eclipse installation
|
||||
*/
|
||||
private final String pluginsDirName;
|
||||
|
||||
/**
|
||||
* @param pluginName
|
||||
* name of the plugin to be analyzed
|
||||
* @throws WalaException
|
||||
*/
|
||||
public EclipseAnalysisScope(String pluginName) throws WalaException {
|
||||
|
||||
this.pluginName = pluginName;
|
||||
|
||||
Properties wp = WalaProperties.loadProperties();
|
||||
this.pluginsDirName = wp.getProperty(WalaProperties.ECLIPSE_PLUGINS_DIR);
|
||||
Assertions.productionAssertion(pluginsDirName != null, "eclipse_plugins_dir property is not set");
|
||||
|
||||
File pluginDirectory = new File(pluginsDirName);
|
||||
|
||||
initVersionInfo(pluginDirectory);
|
||||
|
||||
this.delegate = buildDelegate(pluginDirectory);
|
||||
}
|
||||
|
||||
public EMFScopeWrapper buildDelegate(File pluginDirectory) throws WalaException {
|
||||
pluginIds.add(pluginName);
|
||||
|
||||
File plugIn = findPluginDirOrJAR(pluginName, pluginsDirName, pluginDirectory);
|
||||
if (plugIn == null) {
|
||||
throw new WalaException("EclipseAnalysisScopeBuilder: Unable to identify " + pluginName);
|
||||
}
|
||||
|
||||
Collection<JarFile> relevantJars = findRequiredPluginsFragmentsAndBundles(plugIn, pluginDirectory);
|
||||
// Scan all plug-in manifests for a Fragment-host whose id matches
|
||||
// the eclipse plugin ids (Eclipse.plugin.nnn from RootDetector.config).
|
||||
relevantJars.addAll(getContributingFragments(pluginDirectory));
|
||||
// Build the analysis scope
|
||||
return createScope(relevantJars);
|
||||
|
||||
}
|
||||
|
||||
private EMFScopeWrapper createScope(Collection<JarFile> analysisScopeJars) throws WalaException {
|
||||
EMFScopeWrapper scope = EMFScopeWrapper.generateScope(JavaScopeUtil.makePrimordialScope());
|
||||
for (JarFile jarFile : analysisScopeJars) {
|
||||
scope.addToScope(ClassLoaderReference.Application, jarFile);
|
||||
}
|
||||
if (DEBUG) {
|
||||
printConfigurationInformation(scope);
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize information about the Eclipse version
|
||||
*/
|
||||
private void initVersionInfo(File pluginDirectory) {
|
||||
File eclipseRoot = pluginDirectory.getParentFile();
|
||||
File[] contents = eclipseRoot.listFiles();
|
||||
Assertions.productionAssertion(contents != null, "no files in eclipse root " + eclipseRoot);
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
File content = contents[i];
|
||||
if (content.getName().equals(ECLIPSE_PRODUCT_NAME)) {
|
||||
Properties props = new Properties();
|
||||
try {
|
||||
props.load(new FileInputStream(content));
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("EclipseAnalysisScopeBuilder: File " + ECLIPSE_PRODUCT_NAME
|
||||
+ " not found in Eclipse root directory, " + eclipseRoot.getName() + ".");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("EclipseAnalysisScopeBuilder: File " + ECLIPSE_PRODUCT_NAME
|
||||
+ " could not be accessed in Eclipse root directory, " + eclipseRoot.getName() + ".");
|
||||
}
|
||||
String eclipseVersion = (String) props.get("version");
|
||||
if (eclipseVersion == null) {
|
||||
throw new RuntimeException("EclipseAnalysisScopeBuilder: Unable to detect Eclipse version from file "
|
||||
+ ECLIPSE_PRODUCT_NAME + " in directory " + eclipseRoot.getName() + ".");
|
||||
}
|
||||
eclipseVersion = eclipseVersion.replace(".", ":"); // "." is not
|
||||
// accepted as a
|
||||
// separator
|
||||
String[] versions = eclipseVersion.split(":");
|
||||
version = (new Byte(versions[0])).byteValue();
|
||||
if (versions.length >= 2) {
|
||||
subversion = (new Byte(versions[1])).byteValue();
|
||||
}
|
||||
break; // We found what we needed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* printConfigurationInformation - Print out the contents of the specified
|
||||
* Properties object.
|
||||
*
|
||||
* @param p
|
||||
* (in) - The configuration properties file for the
|
||||
* EclipseAnalysisScopeBuilder.
|
||||
*/
|
||||
private static void printConfigurationInformation(AnalysisScope scope) {
|
||||
System.out.println("CONFIGURATION INFORMATION:");
|
||||
Set modules;
|
||||
// Primordial
|
||||
modules = scope.getModules(ClassLoaderReference.Primordial);
|
||||
System.out.println("PRIMORDIAL:\n" + modules);
|
||||
// Extension
|
||||
modules = scope.getModules(ClassLoaderReference.Extension);
|
||||
System.out.println("EXTENSION:\n" + modules);
|
||||
// Application
|
||||
modules = scope.getModules(ClassLoaderReference.Application);
|
||||
System.out.println("APPLICATION:\n" + modules);
|
||||
}
|
||||
|
||||
/**
|
||||
* findRequiredPluginsFragmentsAndBundles - Find all the plugins necessary to
|
||||
* the analysis scope.
|
||||
*
|
||||
* @param workQ
|
||||
* A list of plugins and fragments which are required by the plugin
|
||||
* being analyzed.
|
||||
*/
|
||||
private Collection<JarFile> findRequiredPluginsFragmentsAndBundles(File plugIn, File pluginDirectory) {
|
||||
Collection<JarFile> result = HashSetFactory.make();
|
||||
FifoQueueNoDuplicates<File> workQ = new FifoQueueNoDuplicates<File>();
|
||||
// Find all the plugins necessary to the analysis scope.
|
||||
workQ.push(plugIn);
|
||||
while (!workQ.isEmpty()) {
|
||||
File f = workQ.pop();
|
||||
Manifest mf = null;
|
||||
try {
|
||||
if (f.isDirectory()) {
|
||||
Set<JarFile> plugInJars = findJars(f);
|
||||
result.addAll(plugInJars);
|
||||
mf = new Manifest(getInputStream(f.getPath() + File.separator + "META-INF" + File.separator + "MANIFEST.MF"));
|
||||
} else {
|
||||
JarFile plugInJar = new JarFile(f);
|
||||
mf = plugInJar.getManifest();
|
||||
result.add(plugInJar);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("EclipseAnalysisScopebuilder: Unable to access manifest file for " + f.getName());
|
||||
continue;
|
||||
}
|
||||
Set<File> requiredPlugins = findRequiredBundles(mf, pluginsDirName, pluginDirectory);
|
||||
if (requiredPlugins != null) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: " + f.getName() + " requires bundles:");
|
||||
Iterator requiredPluginsIter = requiredPlugins.iterator();
|
||||
while (requiredPluginsIter.hasNext()) {
|
||||
File requiredPlugIn = (File) requiredPluginsIter.next();
|
||||
System.out.println(" " + requiredPlugIn.getName());
|
||||
}
|
||||
}
|
||||
if (requiredPlugins != null) {
|
||||
workQ.push(requiredPlugins.iterator());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a plugin name into an actual name in the file system. For example,
|
||||
* "org.eclipse.help.appserver" would be converted to something like
|
||||
* "E:\eclipse3.0M7\eclipse\plugins\org.eclipse.help.appserver_3.0.0" if the
|
||||
* plugin is available in a directory or
|
||||
* "E:\eclipse3.0M7\eclipse\plugins\org.eclipse.help.appserver_3.0.0.jar" if
|
||||
* the plugin is available as a JAR file.
|
||||
*
|
||||
* @param libName
|
||||
* a String representing the name of a plugin
|
||||
* @return a File representing the directory or JAR file containing the
|
||||
* plugin. This method returns <code>null</code> if no directory or
|
||||
* JAR file was found for this plugin.
|
||||
* @throws IllegalArgumentException
|
||||
* if pluginDirectory is null
|
||||
*/
|
||||
public static File findPluginDirOrJAR(String libName, String pluginsDirName, File pluginDirectory)
|
||||
throws IllegalArgumentException {
|
||||
if (pluginDirectory == null) {
|
||||
throw new IllegalArgumentException("pluginDirectory is null");
|
||||
}
|
||||
String pathName = pluginsDirName + "/" + libName;
|
||||
File path = new File(pathName);
|
||||
if (path.isDirectory()) // libName corresponds to a real directory
|
||||
return path;
|
||||
// libName does not corresponds to a real directory. Search the
|
||||
// plugins directory for a corresponding subdirectory containing
|
||||
// this plugin.
|
||||
File[] contents = pluginDirectory.listFiles();
|
||||
if (contents == null) {
|
||||
throw new IllegalArgumentException("bad plugin directory " + pluginDirectory.getAbsolutePath());
|
||||
}
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
String subName = contents[i].getName();
|
||||
if (subName.startsWith(libName + "_"))
|
||||
return contents[i]; // found
|
||||
}
|
||||
return null; // the plugin directory was not found
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all the JAR files in a given directory and all its subdirectories
|
||||
* recursively.
|
||||
*
|
||||
* @param baseDir
|
||||
* a File representing the base directory of the plugin.
|
||||
* @return a Set of Strings, each of which represents the name of a JAR file
|
||||
* in the given directory.
|
||||
*/
|
||||
public static Set<JarFile> findJars(File baseDir) throws IllegalArgumentException {
|
||||
FifoQueueNoDuplicates<File> workQueue = new FifoQueueNoDuplicates<File>();
|
||||
Set<JarFile> jars = HashSetFactory.make();
|
||||
workQueue.push(baseDir);
|
||||
while (!workQueue.isEmpty()) {
|
||||
File dir = workQueue.pop();
|
||||
File[] contents = dir.listFiles();
|
||||
if (contents == null) {
|
||||
throw new IllegalArgumentException("bad file " + dir.getAbsolutePath());
|
||||
}
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
if (contents[i].isDirectory()) {
|
||||
workQueue.push(contents[i]);
|
||||
} else if (contents[i].getName().endsWith(".jar")) {
|
||||
try {
|
||||
jars.add(new JarFile(contents[i]));
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("EclipseAnalysisScopeBuilder: File " + contents[i].getName() + " is not a valid JAR file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return jars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the name of an Eclipse 3.0 fragment host plugin from the value
|
||||
* returned by the manifest.
|
||||
*
|
||||
* e.g. if value contains: BadPlugin2;bundle-version="1.0.0" this method
|
||||
* returns "BadPlugin2".
|
||||
*
|
||||
* @param value
|
||||
* @return String - the name of the fragment's plugin host.
|
||||
*
|
||||
*/
|
||||
private static String parseFragmentHost(String value) {
|
||||
String result = null;
|
||||
String elements[] = value.split(";");
|
||||
if (elements != null)
|
||||
result = elements[0];
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all the bundles required by a given bundle or fragment as specified
|
||||
* in its MANIFEST.MF file.
|
||||
*
|
||||
* @param manifestFileName
|
||||
* a String representing the fully qualified name of a manifest
|
||||
* file.
|
||||
* @return a TreeSet of Strings each of which represents the fully qualified
|
||||
* name of a required plugin's directory. The returned TreeSet is
|
||||
* <code>null</code> if it was not possible to have access to the
|
||||
* XML file.
|
||||
*/
|
||||
private Set<File> findRequiredBundles(Manifest mf, String pluginDirsName, File pluginDirectory) {
|
||||
Set<File> requiredBundles = HashSetFactory.make();
|
||||
Attributes a = mf.getMainAttributes();
|
||||
String pluginId = a.getValue(Constants.BUNDLE_SYMBOLICNAME);
|
||||
if (pluginId != null) {
|
||||
// save off the plugin IDs, so that contributing fragments can be
|
||||
// found.
|
||||
pluginId = parseFragmentHost(pluginId);
|
||||
pluginIds.add(pluginId);
|
||||
}
|
||||
String requireBundle = a.getValue(Constants.REQUIRE_BUNDLE);
|
||||
if (requireBundle != null) {
|
||||
String splittingFactor = ",";
|
||||
String requiredArray[] = requireBundle.split(splittingFactor);
|
||||
if (requiredArray != null) {
|
||||
for (int i = 0; i < requiredArray.length; i++) {
|
||||
String requiredBundleName = (requiredArray[i].trim()).split(";")[0];
|
||||
if ((version > 3 || version == 3 && subversion >= 2) && Character.isDigit(requiredBundleName.charAt(0)))
|
||||
continue;
|
||||
File requiredBundle = findPluginDirOrJAR(requiredBundleName, pluginDirsName, pluginDirectory);
|
||||
if (requiredBundle == null) {
|
||||
System.err.println("EclipseAnalysisScopeBuilder: " + requiredBundleName + " was not found.");
|
||||
continue;
|
||||
}
|
||||
requiredBundles.add(requiredBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If FRAGMENT_HOST is set, then this is a fragment, not a plugin.
|
||||
String fragmentHost = a.getValue(Constants.FRAGMENT_HOST);
|
||||
if (fragmentHost != null) {
|
||||
String hostPluginName = parseFragmentHost(fragmentHost);
|
||||
if (hostPluginName != null) {
|
||||
// If this is a fragment, add the plugin that hosts the fragment to the
|
||||
// list.
|
||||
File hostPlugIn = findPluginDirOrJAR(hostPluginName, pluginDirsName, pluginDirectory);
|
||||
if (hostPlugIn == null) {
|
||||
System.err.println("EclipseAnalysisScopeBuilder: " + hostPluginName + " was not found.");
|
||||
} else {
|
||||
requiredBundles.add(hostPlugIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
return requiredBundles;
|
||||
}
|
||||
|
||||
/**
|
||||
* findManifests - Find all MANIFEST.MF files under specified base directory.
|
||||
*
|
||||
* @param baseDirName
|
||||
* @return Set - A set of full paths to manifest files.
|
||||
*/
|
||||
private static Set<String> findManifests(String baseDirName) {
|
||||
FifoQueueNoDuplicates<File> workQueue = new FifoQueueNoDuplicates<File>();
|
||||
Set<String> manifests = HashSetFactory.make();
|
||||
workQueue.push(new File(baseDirName));
|
||||
while (!workQueue.isEmpty()) {
|
||||
File dir = workQueue.pop();
|
||||
String dirName = dir.getAbsolutePath().replace('\\', '/');
|
||||
String[] contents = dir.list();
|
||||
for (int i = 0; i < contents.length; i++) {
|
||||
String fullName = dirName + "/" + contents[i];
|
||||
if (contents[i].equalsIgnoreCase("MANIFEST.MF")) {
|
||||
manifests.add(fullName);
|
||||
continue;
|
||||
}
|
||||
File file = new File(fullName);
|
||||
if (file.isDirectory())
|
||||
workQueue.push(file);
|
||||
}
|
||||
}
|
||||
return manifests;
|
||||
}
|
||||
|
||||
/**
|
||||
* getContributingFragments - Using the pluginIds Set find all fragments which
|
||||
* contribute to the list of loaded plugins, and add their associated jars to
|
||||
* the analysisScopeJars Set.
|
||||
*/
|
||||
private Collection<JarFile> getContributingFragments(File pluginDirectory) {
|
||||
Collection<JarFile> result = HashSetFactory.make();
|
||||
Set manifests = findManifests(pluginsDirName);
|
||||
Iterator manifestsIter = manifests.iterator();
|
||||
while (manifestsIter.hasNext()) {
|
||||
String manifestName = (String) manifestsIter.next();
|
||||
Iterator pluginIdsIter = pluginIds.iterator();
|
||||
while (pluginIdsIter.hasNext()) {
|
||||
String fragmentHost = (String) pluginIdsIter.next();
|
||||
result.addAll(getContributingFragment(fragmentHost, manifestName, pluginDirectory));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* addContributingFragment - Determine if the supplied manifest.mf file
|
||||
* contributes to the specified fragmentHost. If so, add the associated jar,
|
||||
* and any required jars to the analysisScopeJars Set.
|
||||
*
|
||||
* @param fragmentHost -
|
||||
* The plugin id value to search for in fragment manifests.
|
||||
* @param manifestFileName -
|
||||
* The name of the current manifest file being scanned.
|
||||
*
|
||||
*/
|
||||
private Collection<JarFile> getContributingFragment(String fragmentHost, String manifestFileName,
|
||||
File pluginDirectory) {
|
||||
Collection<JarFile> result = HashSetFactory.make();
|
||||
InputStream is = getInputStream(manifestFileName);
|
||||
if (is == null) {
|
||||
System.err.println("EclipseAnalysisScopeBuilder: " + manifestFileName + " was not found.");
|
||||
} else {
|
||||
try {
|
||||
Manifest m = new Manifest(is);
|
||||
Attributes a = m.getMainAttributes();
|
||||
// If FRAGMENT_HOST is set, then this is a fragment, not a plugin.
|
||||
String hostPlugin = a.getValue(Constants.FRAGMENT_HOST);
|
||||
|
||||
if (hostPlugin != null) {
|
||||
hostPlugin = parseFragmentHost(hostPlugin);
|
||||
if (hostPlugin.equalsIgnoreCase(fragmentHost)) {
|
||||
String requireBundle = a.getValue(Constants.REQUIRE_BUNDLE);
|
||||
if (requireBundle != null) {
|
||||
String requiredArray[] = requireBundle.split(",");
|
||||
if (requiredArray != null) {
|
||||
for (int i = 0; i < requiredArray.length; i++) {
|
||||
String pluginName = (requiredArray[i].trim()).split(";")[0];
|
||||
File plugIn = findPluginDirOrJAR(pluginName, pluginsDirName, pluginDirectory);
|
||||
if (plugIn == null) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: " + pluginName + " was not found.");
|
||||
continue;
|
||||
}
|
||||
Set<JarFile> pluginJars = findJars(plugIn);
|
||||
if (pluginJars == null || pluginJars.isEmpty()) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: Informational: no jars found in plugin root folder.");
|
||||
} else
|
||||
result.addAll(pluginJars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add all jars for this plugin to the analysis scope since it
|
||||
// contributes as a fragment.
|
||||
String fragmentSymbolicName = a.getValue(Constants.BUNDLE_SYMBOLICNAME);
|
||||
fragmentSymbolicName = parseFragmentHost(fragmentSymbolicName);
|
||||
if (fragmentSymbolicName != null) {
|
||||
File plugIn = findPluginDirOrJAR(fragmentSymbolicName, pluginsDirName, pluginDirectory);
|
||||
if (plugIn == null) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: " + hostPlugin + " was not found.");
|
||||
} else {
|
||||
Set<JarFile> pluginJars = findJars(plugIn);
|
||||
result.addAll(pluginJars);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an InputStream to the <code>plugin.xml</code> file describing the
|
||||
* plugin configuration. The InputStream returned is <code>null</code> if
|
||||
* the XML file does not exist or cannot be opened.
|
||||
*
|
||||
* @param xmlFileName
|
||||
* a String representing the name of the <code>plugin.xml</code>
|
||||
* file describing the plugin configuration.
|
||||
* @return an InputStream to the <code>plugin.xml</code> file.
|
||||
*/
|
||||
public static InputStream getInputStream(String xmlFileName) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(xmlFileName);
|
||||
} catch (IOException e) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: Unable to access file " + xmlFileName + ": " + e);
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClassFileToScope(ClassLoaderReference loader, File file) {
|
||||
delegate.addClassFileToScope(loader, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSourceFileToScope(ClassLoaderReference loader, File file, String fileName) {
|
||||
delegate.addSourceFileToScope(loader, file, fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToScope(ClassLoaderReference loader, JarFile file) {
|
||||
delegate.addToScope(loader, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToScope(ClassLoaderReference loader, Module m) {
|
||||
delegate.addToScope(loader, m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return delegate.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodReference findMethod(Atom loader, String klass, Atom name, ImmutableByteArray desc) {
|
||||
return delegate.findMethod(loader, klass, name, desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoaderReference getApplicationLoader() {
|
||||
return delegate.getApplicationLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayClassLoader getArrayClassLoader() {
|
||||
return delegate.getArrayClassLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetOfClasses getExclusions() {
|
||||
return delegate.getExclusions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoaderReference getExtensionLoader() {
|
||||
return delegate.getExtensionLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJavaLibraryVersion() {
|
||||
return delegate.getJavaLibraryVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoaderReference getLoader(Atom name) {
|
||||
return delegate.getLoader(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLoaderImpl(ClassLoaderReference ref) {
|
||||
return delegate.getLoaderImpl(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ClassLoaderReference> getLoaders() {
|
||||
return delegate.getLoaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Module> getModules(ClassLoaderReference loader) {
|
||||
return delegate.getModules(loader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfLoaders() {
|
||||
return delegate.getNumberOfLoaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoaderReference getPrimordialLoader() {
|
||||
return delegate.getPrimordialLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassLoaderReference getSyntheticLoader() {
|
||||
return delegate.getSyntheticLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJava14Libraries() {
|
||||
return delegate.isJava14Libraries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJava15Libraries() {
|
||||
return delegate.isJava15Libraries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExclusions(SetOfClasses classes) {
|
||||
delegate.setExclusions(classes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return delegate.toString();
|
||||
}
|
||||
|
||||
public String getPluginName() {
|
||||
return pluginName;
|
||||
}
|
||||
|
||||
public String getPluginsDirName() {
|
||||
return pluginsDirName;
|
||||
}
|
||||
}
|
|
@ -1,308 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 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.util.scope;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import org.osgi.framework.Constants;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ArgumentTypeEntrypoint;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.util.StringStuff;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
import com.ibm.wala.util.warnings.WalaException;
|
||||
|
||||
/**
|
||||
*
|
||||
* All public and protected methods in the "root packages" are considered
|
||||
* entrypoints, except not inner classes
|
||||
*
|
||||
* @author pistoia
|
||||
* @author sfink
|
||||
*/
|
||||
@Deprecated
|
||||
public class EclipseEntrypoints extends HashSet<Entrypoint> {
|
||||
|
||||
private final static boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* @param scope
|
||||
* governing analysis scope
|
||||
* @param cha
|
||||
* governing class hierarchy
|
||||
* @param internalEntrypoints
|
||||
* This boolean flag is used to decide whether internal packages
|
||||
* (those containing the substring ".internal" in their names) should
|
||||
* contribute entry points to the analysis (value <code>true</code>)
|
||||
* or not (value <code>false</code>). The default value is
|
||||
* <code>false</code> because internal packages are not supposed to
|
||||
* be invoked from external bundles.
|
||||
* @throws WalaException
|
||||
* @throws IllegalArgumentException if cha is null
|
||||
* @throws IllegalArgumentException if scope is null
|
||||
*/
|
||||
public EclipseEntrypoints(EclipseAnalysisScope scope, final IClassHierarchy cha, boolean internalEntrypoints) throws WalaException {
|
||||
if (scope == null) {
|
||||
throw new IllegalArgumentException("scope is null");
|
||||
}
|
||||
if (cha == null) {
|
||||
throw new IllegalArgumentException("cha is null");
|
||||
}
|
||||
String pluginName = scope.getPluginName();
|
||||
String pluginsDirName = scope.getPluginsDirName();
|
||||
|
||||
// Build the set of root packages
|
||||
Set<JarFile> rootJars = findRootJars(pluginName, pluginsDirName);
|
||||
// Build a set of root packages.
|
||||
Set rootPackages = findRootPackages(internalEntrypoints, rootJars);
|
||||
for (IClass klass : cha) {
|
||||
String className = StringStuff.jvmToReadableType(klass.getName().toString());
|
||||
if (className.contains("$")) {
|
||||
continue;
|
||||
}
|
||||
String packageName = computePackageName(className);
|
||||
if (!rootPackages.contains(packageName)) {
|
||||
continue;
|
||||
}
|
||||
if (!klass.isInterface()) {
|
||||
if (isApplicationClass(scope, klass)) {
|
||||
for (Iterator methodIt = klass.getDeclaredMethods().iterator(); methodIt.hasNext();) {
|
||||
IMethod method = (IMethod) methodIt.next();
|
||||
if (!method.isAbstract() && method.isPublic() || method.isProtected()) {
|
||||
add(new ArgumentTypeEntrypoint(method, cha));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG) {
|
||||
Trace.println(getClass() + "Number of EntryPoints:" + size());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param scope
|
||||
* an <code>AnalysisScope</code> object representing the governing
|
||||
* analysis scope
|
||||
* @param klass
|
||||
* the <code>IClass</code> object whose class loading membership is
|
||||
* being tested
|
||||
* @return <code>true</code> iff <code>klass</code> is loaded by the
|
||||
* application loader.
|
||||
*/
|
||||
private boolean isApplicationClass(AnalysisScope scope, IClass klass) {
|
||||
return scope.getApplicationLoader().equals(klass.getClassLoader().getReference());
|
||||
}
|
||||
|
||||
private String computePackageName(String className) {
|
||||
int lastDot = className.lastIndexOf('.');
|
||||
if (lastDot == -1) {
|
||||
return "";
|
||||
}
|
||||
return className.substring(0, lastDot);
|
||||
}
|
||||
|
||||
/**
|
||||
* findRootJars - All the plugins listed in the configuration file must be
|
||||
* considered for the analysis scope as well as for finding the root nodes.
|
||||
*
|
||||
* @param p
|
||||
* The configuration properties file for the
|
||||
* EclipseAnalysisScopeBuilder.
|
||||
* @return A Set containing entry <code>JARFile</code> objects. An <i>entry
|
||||
* JAR file</i> is a JAR file containing some class files whose
|
||||
* methods could be used as entry points. By default, all the public
|
||||
* and protected methods in non-internal packages are considered entry
|
||||
* points.
|
||||
* @throws WalaException
|
||||
*/
|
||||
private static Set<JarFile> findRootJars(String pluginName, String pluginsDirName) throws WalaException {
|
||||
Set<JarFile> rootJars = HashSetFactory.make();
|
||||
|
||||
File pluginDirectory = new File(pluginsDirName);
|
||||
File plugIn = EclipseAnalysisScope.findPluginDirOrJAR(pluginName, pluginsDirName, pluginDirectory);
|
||||
if (plugIn == null) {
|
||||
throw new WalaException("EclipseAnalysisScopeBuilder: Unable to identify " + pluginName);
|
||||
}
|
||||
String realName = plugIn.getPath();
|
||||
if (plugIn.isDirectory()) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: " + pluginName + " converted to " + realName);
|
||||
// Find all the JAR files in the plugin directory
|
||||
Set<JarFile> pluginAllJars = EclipseAnalysisScope.findJars(plugIn);
|
||||
// Among them, find the root JAR files for this plugin
|
||||
Set<JarFile> pluginRootJars = findBundleRootJars(realName, pluginAllJars);
|
||||
// Add the root JARs for this plugin to the set of all the root
|
||||
// JAR files for the whole analysis
|
||||
if (pluginRootJars == null || pluginRootJars.isEmpty()) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: Plugin or fragment contains no JAR files. Nothing to analyze.");
|
||||
} else {
|
||||
rootJars.addAll(pluginRootJars);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
JarFile jarFile = new JarFile(plugIn);
|
||||
System.out.println("EclipseAnalysisScopeBuilder: JAR file " + pluginsDirName + "/" + pluginName + ".jar found");
|
||||
rootJars.add(jarFile);
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: JAR file " + pluginsDirName + "/" + pluginName + ".jar not found");
|
||||
}
|
||||
}
|
||||
return rootJars;
|
||||
}
|
||||
|
||||
/**
|
||||
* findRootPackages - Builds up a list of package names from the rootJars Set
|
||||
* and saves the results in private TreeSet var rootPackages.
|
||||
*
|
||||
* @return A Set containing String objects, each String object representing
|
||||
* the name of a package that should be considered a root package. A
|
||||
* <i>root package </i> is a package such that all its classes' public
|
||||
* and protected methods are considered root methods. By default, a
|
||||
* root package does not contain the String ".internal." in its name.
|
||||
*/
|
||||
private static Set<String> findRootPackages(boolean internalEntrypoints, Set<JarFile> rootJars) {
|
||||
Set<String> rootPackages = HashSetFactory.make();
|
||||
if (DEBUG) {
|
||||
System.out.println("ROOT JARS:");
|
||||
}
|
||||
for (JarFile rootJarFile : rootJars) {
|
||||
if (DEBUG) {
|
||||
System.out.println(rootJarFile.getName());
|
||||
}
|
||||
Enumeration entries = rootJarFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = (JarEntry) entries.nextElement();
|
||||
String entryName = entry.getName();
|
||||
// Filter out the internal packages, which should not
|
||||
// be invoked by client code.
|
||||
|
||||
if (!internalEntrypoints && entryName.indexOf("/internal/") != -1) {
|
||||
continue;
|
||||
}
|
||||
if (entryName.endsWith(".class")) {
|
||||
// Indentify the package name
|
||||
int lastSlash = entryName.lastIndexOf('/');
|
||||
String tempPackageName = entryName.substring(0, lastSlash);
|
||||
String packageName = tempPackageName.replace('/', '.');
|
||||
rootPackages.add(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rootPackages.isEmpty()) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int numberOfRootJars = rootJars.size();
|
||||
buf.append("EclipseAnalysisScopeBuilder: No entry points in JAR file");
|
||||
buf.append((numberOfRootJars == 1) ? ":\n" : "s:\n");
|
||||
Iterator<JarFile> rootJarsIter = rootJars.iterator();
|
||||
while (rootJarsIter.hasNext()) {
|
||||
buf.append("\t" + rootJarsIter.next() + "\n");
|
||||
}
|
||||
buf.append("The analysis is terminating.");
|
||||
System.out.println(buf.toString());
|
||||
System.exit(0);
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println("ROOT PACKAGES: " + rootPackages);
|
||||
}
|
||||
return rootPackages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the root JAR files for a plugin, given the plugin directory. The
|
||||
* root JAR files are returned as String objects, each String representing the
|
||||
* fully qualified name of the JAR file. The information is based on the
|
||||
* plugin configuration file.
|
||||
*
|
||||
* @param dirName
|
||||
* a String representing the fully qualified name of the directory
|
||||
* where a plugin is stored.
|
||||
* @param pluginAllJars
|
||||
* all the JAR files found in the plugin directory.
|
||||
* @return a TreeSet of String object, each object representing the fully
|
||||
* qualified name of a plugin JAR file.
|
||||
*/
|
||||
private static Set<JarFile> findBundleRootJars(String dirName, Set<JarFile> pluginAllJars) {
|
||||
String manifestFileName = dirName + File.separator + "META-INF" + File.separator + "MANIFEST.MF";
|
||||
Set<JarFile> pluginRootJars = HashSetFactory.make();
|
||||
InputStream is = EclipseAnalysisScope.getInputStream(manifestFileName);
|
||||
if (is == null) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: " + manifestFileName + " was not found.");
|
||||
return pluginAllJars;
|
||||
} else {
|
||||
try {
|
||||
Manifest m = new Manifest(is);
|
||||
Attributes a = m.getMainAttributes();
|
||||
// If FRAGMENT_HOST is set, then this is a fragment, not a plugin.
|
||||
String hostPlugin = a.getValue(Constants.FRAGMENT_HOST);
|
||||
if (hostPlugin != null) {
|
||||
hostPlugin = parseFragmentHost(hostPlugin);
|
||||
}
|
||||
String bundleClasspath = a.getValue(Constants.BUNDLE_CLASSPATH);
|
||||
if (bundleClasspath != null) {
|
||||
String requiredArray[] = bundleClasspath.split(",");
|
||||
if (requiredArray != null) {
|
||||
for (int i = 0; i < requiredArray.length; i++) {
|
||||
String libraryName = (requiredArray[i].trim()).split(";")[0];
|
||||
// Verify that the JAR file is really there
|
||||
String fullLibraryName = dirName + File.separator + libraryName;
|
||||
Iterator pluginAllJarsIter = pluginAllJars.iterator();
|
||||
while (pluginAllJarsIter.hasNext()) {
|
||||
JarFile jarFile = (JarFile) pluginAllJarsIter.next();
|
||||
String jarFileName = jarFile.getName();
|
||||
if (jarFileName.equals(fullLibraryName)) {
|
||||
pluginRootJars.add(jarFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("EclipseAnalysisScopeBuilder: " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
return pluginRootJars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the name of an Eclipse 3.0 fragment host plugin from the value
|
||||
* returned by the manifest.
|
||||
*
|
||||
* e.g. if value contains: BadPlugin2;bundle-version="1.0.0" this method
|
||||
* returns "BadPlugin2".
|
||||
*
|
||||
* @param value
|
||||
* @return String - the name of the fragment's plugin host.
|
||||
*
|
||||
*/
|
||||
private static String parseFragmentHost(String value) {
|
||||
String result = null;
|
||||
String elements[] = value.split(";");
|
||||
if (elements != null)
|
||||
result = elements[0];
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue