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:
sjfink 2007-10-22 16:32:38 +00:00
parent 0074f4e6c5
commit 9eb07d255e
2 changed files with 0 additions and 972 deletions

View File

@ -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;
}
}

View File

@ -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;
}
}