changes to ease use of WALA from an executable jar. also some very
basic support for GXL, a graph format used by some software engineering tools.
This commit is contained in:
parent
837528592a
commit
310d0fff25
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="source"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/js.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
|
|
|
@ -35,5 +35,5 @@ Export-Package: com.ibm.wala.cast.js.translator,
|
|||
org.mozilla.javascript.xml,
|
||||
org.mozilla.javascript.xml.impl.xmlbeans,
|
||||
org.mozilla.javascript.xmlimpl
|
||||
Bundle-ClassPath: lib/rhino-1.7R3.jar,
|
||||
.
|
||||
Bundle-ClassPath: .,
|
||||
lib/js.jar
|
||||
|
|
|
@ -2,5 +2,5 @@ source.. = source/
|
|||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
lib/rhino-1.7R3.jar
|
||||
lib/js.jar
|
||||
jars.extra.classpath = lib/rhino-1.7R3.jar
|
||||
|
|
|
@ -9,33 +9,43 @@ import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
|||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.Entrypoint;
|
||||
import com.ibm.wala.ipa.callgraph.cha.CHACallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.impl.AllApplicationEntrypoints;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Util;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchy;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.functions.Function;
|
||||
|
||||
public class CHACallGraphTest {
|
||||
|
||||
@Test public void testJava_cup() throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
testCHA(TestConstants.JAVA_CUP, TestConstants.JAVA_CUP_MAIN);
|
||||
testCHA(TestConstants.JAVA_CUP, TestConstants.JAVA_CUP_MAIN, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
|
||||
}
|
||||
|
||||
public static CallGraph testCHA(String scopeFile, final String mainClass, final String exclusionsFile) throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
return testCHA(scopeFile, exclusionsFile, new Function<IClassHierarchy, Iterable<Entrypoint>>() {
|
||||
@Override
|
||||
public Iterable<Entrypoint> apply(IClassHierarchy cha) {
|
||||
return Util.makeMainEntrypoints(cha.getScope(), cha, mainClass);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static CallGraph testCHA(String scopeFile, String mainClass) throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(scopeFile, CallGraphTestUtil.REGRESSION_EXCLUSIONS);
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
Iterable<Entrypoint> entrypoints;
|
||||
if (mainClass == null) {
|
||||
entrypoints = new AllApplicationEntrypoints(scope, cha);
|
||||
} else {
|
||||
entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, mainClass);
|
||||
}
|
||||
public static CallGraph testCHA(String scopeFile,
|
||||
String exclusionsFile,
|
||||
Function<IClassHierarchy, Iterable<Entrypoint>> makeEntrypoints)
|
||||
throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException
|
||||
{
|
||||
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(scopeFile, exclusionsFile);
|
||||
IClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
|
||||
CHACallGraph CG = new CHACallGraph(cha);
|
||||
CG.init(entrypoints);
|
||||
CG.init(makeEntrypoints.apply(cha));
|
||||
|
||||
return CG;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ClassHierarchyException, IllegalArgumentException, CancelException, IOException {
|
||||
testCHA(args[0], args.length>1? args[1]: null);
|
||||
testCHA(args[0], args.length>1? args[1]: null, "Java60RegressionExclusions.txt");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
/*******************************************************************************
|
||||
* 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.classLoader;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.io.FileSuffixes;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
import com.ibm.wala.util.warnings.Warnings;
|
||||
|
||||
/**
|
||||
* A Jar file nested in a parent jar file
|
||||
*/
|
||||
public abstract class AbstractNestedJarFileModule implements Module {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* For efficiency, we cache the byte[] holding each ZipEntry's contents; this will help avoid multiple unzipping TODO: use a soft
|
||||
* reference?
|
||||
*/
|
||||
private HashMap<String, byte[]> cache = null;
|
||||
|
||||
protected abstract InputStream getNestedContents() throws IOException;
|
||||
|
||||
public InputStream getInputStream(String name) {
|
||||
populateCache();
|
||||
byte[] b = cache.get(name);
|
||||
return new ByteArrayInputStream(b);
|
||||
}
|
||||
|
||||
private void populateCache() {
|
||||
if (cache != null) {
|
||||
return;
|
||||
}
|
||||
cache = HashMapFactory.make();
|
||||
try {
|
||||
final JarInputStream stream = new JarInputStream(getNestedContents());
|
||||
for (ZipEntry z = stream.getNextEntry(); z != null; z = stream.getNextEntry()) {
|
||||
final String name = z.getName();
|
||||
if (DEBUG) {
|
||||
System.err.println(("got entry: " + name));
|
||||
}
|
||||
if (FileSuffixes.isClassFile(name) || FileSuffixes.isSourceFile(name)) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
byte[] temp = new byte[1024];
|
||||
int n = stream.read(temp);
|
||||
while (n != -1) {
|
||||
out.write(temp, 0, n);
|
||||
n = stream.read(temp);
|
||||
}
|
||||
byte[] bb = out.toByteArray();
|
||||
cache.put(name, bb);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// just go with what we have
|
||||
Warnings.add(new Warning() {
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return "could not read contents of nested jar file " + toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected long getEntrySize(String name) {
|
||||
populateCache();
|
||||
byte[] b = cache.get(name);
|
||||
return b.length;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.Module#getEntries()
|
||||
*/
|
||||
public Iterator<ModuleEntry> getEntries() {
|
||||
populateCache();
|
||||
final Iterator<String> it = cache.keySet().iterator();
|
||||
return new Iterator<ModuleEntry>() {
|
||||
String next = null;
|
||||
{
|
||||
advance();
|
||||
}
|
||||
|
||||
private void advance() {
|
||||
if (it.hasNext()) {
|
||||
next = it.next();
|
||||
} else {
|
||||
next = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return next != null;
|
||||
}
|
||||
|
||||
public ModuleEntry next() {
|
||||
ModuleEntry result = new Entry(next);
|
||||
advance();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink an entry in a nested jar file.
|
||||
*/
|
||||
private class Entry implements ModuleEntry {
|
||||
|
||||
private final String name;
|
||||
|
||||
Entry(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#isClassFile()
|
||||
*/
|
||||
public boolean isClassFile() {
|
||||
return FileSuffixes.isClassFile(getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#getInputStream()
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
return AbstractNestedJarFileModule.this.getInputStream(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#isModuleFile()
|
||||
*/
|
||||
public boolean isModuleFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#asModule()
|
||||
*/
|
||||
public Module asModule() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "nested entry: " + name;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#getClassName()
|
||||
*/
|
||||
public String getClassName() {
|
||||
return FileSuffixes.stripSuffix(getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#isSourceFile()
|
||||
*/
|
||||
public boolean isSourceFile() {
|
||||
return FileSuffixes.isSourceFile(getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + getOuterType().hashCode();
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Entry other = (Entry) obj;
|
||||
if (!getOuterType().equals(other.getOuterType()))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private AbstractNestedJarFileModule getOuterType() {
|
||||
return AbstractNestedJarFileModule.this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002 - 2006 IBM Corporation.
|
||||
* Copyright (c) 2007 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
|
||||
|
@ -11,37 +11,15 @@
|
|||
package com.ibm.wala.classLoader;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.io.FileSuffixes;
|
||||
import com.ibm.wala.util.warnings.Warning;
|
||||
import com.ibm.wala.util.warnings.Warnings;
|
||||
|
||||
/**
|
||||
* A Jar file nested in a parent jar file
|
||||
*/
|
||||
public class NestedJarFileModule implements Module {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
public class NestedJarFileModule extends AbstractNestedJarFileModule {
|
||||
|
||||
private final JarFileModule parent;
|
||||
|
||||
private final ZipEntry entry;
|
||||
|
||||
/**
|
||||
* For efficiency, we cache the byte[] holding each ZipEntry's contents; this will help avoid multiple unzipping TODO: use a soft
|
||||
* reference?
|
||||
*/
|
||||
private HashMap<String, byte[]> cache = null;
|
||||
|
||||
public NestedJarFileModule(JarFileModule parent, ZipEntry entry) {
|
||||
this.parent = parent;
|
||||
this.entry = entry;
|
||||
|
@ -53,190 +31,9 @@ public class NestedJarFileModule implements Module {
|
|||
}
|
||||
}
|
||||
|
||||
public InputStream getInputStream(String name) {
|
||||
populateCache();
|
||||
byte[] b = cache.get(name);
|
||||
return new ByteArrayInputStream(b);
|
||||
}
|
||||
|
||||
private void populateCache() {
|
||||
if (cache != null) {
|
||||
return;
|
||||
}
|
||||
cache = HashMapFactory.make();
|
||||
final byte[] b = parent.getContents(entry);
|
||||
try {
|
||||
final JarInputStream stream = new JarInputStream(new ByteArrayInputStream(b));
|
||||
for (ZipEntry z = stream.getNextEntry(); z != null; z = stream.getNextEntry()) {
|
||||
final String name = z.getName();
|
||||
if (DEBUG) {
|
||||
System.err.println(("got entry: " + name));
|
||||
}
|
||||
if (FileSuffixes.isClassFile(name) || FileSuffixes.isSourceFile(name)) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
byte[] temp = new byte[1024];
|
||||
int n = stream.read(temp);
|
||||
while (n != -1) {
|
||||
out.write(temp, 0, n);
|
||||
n = stream.read(temp);
|
||||
}
|
||||
byte[] bb = out.toByteArray();
|
||||
cache.put(name, bb);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// just go with what we have
|
||||
Warnings.add(new Warning() {
|
||||
|
||||
@Override
|
||||
public String getMsg() {
|
||||
return "could not read contents of nested jar file " + entry.getName() + ", parent " + parent.getAbsolutePath();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected long getEntrySize(String name) {
|
||||
populateCache();
|
||||
byte[] b = cache.get(name);
|
||||
return b.length;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.Module#getEntries()
|
||||
*/
|
||||
public Iterator<ModuleEntry> getEntries() {
|
||||
populateCache();
|
||||
final Iterator<String> it = cache.keySet().iterator();
|
||||
return new Iterator<ModuleEntry>() {
|
||||
String next = null;
|
||||
{
|
||||
advance();
|
||||
}
|
||||
|
||||
private void advance() {
|
||||
if (it.hasNext()) {
|
||||
next = it.next();
|
||||
} else {
|
||||
next = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return next != null;
|
||||
}
|
||||
|
||||
public ModuleEntry next() {
|
||||
ModuleEntry result = new Entry(next);
|
||||
advance();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @author sfink an entry in a nested jar file.
|
||||
*/
|
||||
private class Entry implements ModuleEntry {
|
||||
|
||||
private final String name;
|
||||
|
||||
Entry(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#isClassFile()
|
||||
*/
|
||||
public boolean isClassFile() {
|
||||
return FileSuffixes.isClassFile(getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#getInputStream()
|
||||
*/
|
||||
public InputStream getInputStream() {
|
||||
return NestedJarFileModule.this.getInputStream(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#isModuleFile()
|
||||
*/
|
||||
public boolean isModuleFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#asModule()
|
||||
*/
|
||||
public Module asModule() {
|
||||
Assertions.UNREACHABLE();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "nested entry: " + name;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#getClassName()
|
||||
*/
|
||||
public String getClassName() {
|
||||
return FileSuffixes.stripSuffix(getName());
|
||||
}
|
||||
|
||||
/*
|
||||
* @see com.ibm.wala.classLoader.ModuleEntry#isSourceFile()
|
||||
*/
|
||||
public boolean isSourceFile() {
|
||||
return FileSuffixes.isSourceFile(getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + getOuterType().hashCode();
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Entry other = (Entry) obj;
|
||||
if (!getOuterType().equals(other.getOuterType()))
|
||||
return false;
|
||||
if (name == null) {
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private NestedJarFileModule getOuterType() {
|
||||
return NestedJarFileModule.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getNestedContents() {
|
||||
return new ByteArrayInputStream(parent.getContents(entry));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -269,4 +66,4 @@ public class NestedJarFileModule implements Module {
|
|||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 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.classLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
|
||||
public class ResourceJarFileModule extends AbstractNestedJarFileModule {
|
||||
|
||||
private final URL resourceURL;
|
||||
|
||||
public ResourceJarFileModule(URL resourceURL) {
|
||||
this.resourceURL = resourceURL;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected InputStream getNestedContents() throws IOException {
|
||||
return resourceURL.openConnection().getInputStream();
|
||||
}
|
||||
|
||||
}
|
|
@ -23,6 +23,7 @@ import java.util.regex.Pattern;
|
|||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.ipa.callgraph.impl.SetOfClasses;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.io.FileProvider;
|
||||
|
||||
/**
|
||||
* An object which represents a set of classes read from a text file.
|
||||
|
@ -43,7 +44,7 @@ public class FileOfClasses extends SetOfClasses implements Serializable {
|
|||
private boolean needsCompile = false;
|
||||
|
||||
private FileOfClasses(File textFile) throws IOException {
|
||||
this(new FileInputStream(textFile));
|
||||
this(textFile.exists()? new FileInputStream(textFile): FileProvider.class.getClassLoader().getResourceAsStream(textFile.getName()));
|
||||
}
|
||||
|
||||
public static FileOfClasses createFileOfClasses(File textFile) throws IOException {
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.zip.ZipException;
|
|||
import com.ibm.wala.classLoader.JarFileModule;
|
||||
import com.ibm.wala.classLoader.Module;
|
||||
import com.ibm.wala.classLoader.NestedJarFileModule;
|
||||
import com.ibm.wala.classLoader.ResourceJarFileModule;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
|
||||
/**
|
||||
|
@ -35,7 +36,7 @@ import com.ibm.wala.util.debug.Assertions;
|
|||
public class FileProvider {
|
||||
|
||||
|
||||
private final static int DEBUG_LEVEL = 0;
|
||||
private final static int DEBUG_LEVEL = Integer.parseInt(System.getProperty("wala.debug.file", "0"));
|
||||
|
||||
/**
|
||||
* @param fileName
|
||||
|
@ -164,6 +165,8 @@ public class FileProvider {
|
|||
JarEntry entry = jc.getJarEntry();
|
||||
JarFileModule parent = new JarFileModule(f);
|
||||
return new NestedJarFileModule(parent, entry);
|
||||
} else if (url.getProtocol().equals("rsrc")) {
|
||||
return new ResourceJarFileModule(url);
|
||||
} else {
|
||||
String filePath = filePathFromURL(url);
|
||||
return new JarFileModule(new JarFile(filePath, false));
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package com.ibm.wala.util.graph;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.ibm.wala.util.functions.Function;
|
||||
|
||||
public class GXL {
|
||||
|
||||
public interface EntityTypes<T> {
|
||||
String type(T entity);
|
||||
String type(Graph<T> entity);
|
||||
String type(T from, T to);
|
||||
}
|
||||
|
||||
public static <T> String toGXL(Graph<T> G,
|
||||
EntityTypes<T> types,
|
||||
String graphId,
|
||||
Function<T,String> nodeIds,
|
||||
Function<T,Map<String,String>> nodeProperties)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
sb.append("<!DOCTYPE gxl SYSTEM \"http://www.gupro.de/GXL/gxl-1.0.dtd\">\n");
|
||||
sb.append("<gxl xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n");
|
||||
sb.append(" <graph id=\"" + graphId + "\" edgemode=\"directed\" hypergraph=\"false\">\n");
|
||||
sb.append(" <type xlink:href=\"" + types.type(G) + "\"/>\n");
|
||||
|
||||
for(T n : G) {
|
||||
sb.append(" <node id=\"" + nodeIds.apply(n) + "\">\n");
|
||||
sb.append(" <type xlink:href=\"" + types.type(n) + "\"/>\n");
|
||||
Map<String,String> props = nodeProperties.apply(n);
|
||||
if (props != null) {
|
||||
for(Map.Entry<String,String> e : props.entrySet()) {
|
||||
sb.append(" <attr name=\"" + e.getKey() + "\">\n");
|
||||
if (e.getValue() != null) {
|
||||
sb.append(" <string>" + e.getValue() + "</string>\n");
|
||||
} else {
|
||||
sb.append(" <string/>\n");
|
||||
}
|
||||
sb.append(" </attr>\n");
|
||||
}
|
||||
}
|
||||
sb.append(" </node>\n");
|
||||
}
|
||||
|
||||
for(T n : G) {
|
||||
Iterator<T> ss = G.getSuccNodes(n);
|
||||
while (ss.hasNext()) {
|
||||
T s = ss.next();
|
||||
sb.append(" <edge from=\"" + nodeIds.apply(n) + "\" to=\"" + nodeIds.apply(s) + "\">\n");
|
||||
sb.append(" <type xlink:href=\"" + types.type(n, s) + "\"/>\n");
|
||||
|
||||
sb.append(" </edge>\n");
|
||||
}
|
||||
}
|
||||
|
||||
sb.append(" </graph>\n");
|
||||
sb.append("</gxl>\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue