Skip to content

Instantly share code, notes, and snippets.

@pvlasov
Created May 10, 2017 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pvlasov/88b7f66d372bb553cfba415afaab1e9c to your computer and use it in GitHub Desktop.
Save pvlasov/88b7f66d372bb553cfba415afaab1e9c to your computer and use it in GitHub Desktop.
Call graph visualization with Gephi
/*
Dependencies:
- Java Call Graph - https://github.com/gousiosg/java-callgraph.
- Gexf4j - https://github.com/francesco-ficarola/gexf4j (download all dependencies with mvn dependency:copy-dependencies)
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Writer;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import it.uniroma1.dis.wsngroup.gexf4j.core.EdgeType;
import it.uniroma1.dis.wsngroup.gexf4j.core.Gexf;
import it.uniroma1.dis.wsngroup.gexf4j.core.Graph;
import it.uniroma1.dis.wsngroup.gexf4j.core.Mode;
import it.uniroma1.dis.wsngroup.gexf4j.core.Node;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.Attribute;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeClass;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeList;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeType;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.GexfImpl;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.StaxGraphWriter;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.data.AttributeListImpl;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.viz.ColorImpl;
import it.uniroma1.dis.wsngroup.gexf4j.core.viz.Color;
public class CallGraphScanner {
public static void main(String[] args) throws Exception {
for (String callGraph: args) {
Gexf gexf = new GexfImpl();
Calendar date = Calendar.getInstance();
gexf.getMetadata()
.setLastModified(date.getTime())
.setCreator("Nasdanika.org")
.setDescription("Route and Renderer call graph");
gexf.setVisualization(true);
Graph graph = gexf.getGraph();
graph.setDefaultEdgeType(EdgeType.DIRECTED).setMode(Mode.DYNAMIC);
AttributeList attrList = new AttributeListImpl(AttributeClass.NODE);
Attribute attFullName = attrList.createAttribute("0", AttributeType.STRING, "fullName");
graph.getAttributeLists().add(attrList);
Map<String, Node> methodNodes = new HashMap<>();
Set<String> idSet = new HashSet<>();
try (BufferedReader br = new BufferedReader(new FileReader(callGraph))) {
String line;
while ((line = br.readLine()) != null) {
String[] dep = line.split(" ");
String source = dep[0];
if (source.startsWith("M:org.nasdanika.cdo.web.routes.app.Renderer:") || source.startsWith("M:org.nasdanika.cdo.web.routes.app.Route:") || source.startsWith("M:org.nasdanika.cdo.web.routes.app.EOperationTarget:")) {
int lpidx = source.indexOf("(");
if (lpidx != -1) {
source = source.substring(0, lpidx);
source = source.substring(source.lastIndexOf('.')+1);
if (!source.endsWith(":<clinit>")) {
String target = dep[1].substring(3);
if (target.startsWith("org.nasdanika.cdo.web.routes.app.Renderer:") || target.startsWith("org.nasdanika.cdo.web.routes.app.Route:") || source.startsWith("M:org.nasdanika.cdo.web.routes.app.EOperationTarget:")) {
int tlpidx = target.indexOf("(");
if (tlpidx != -1) {
target = target.substring(0, tlpidx);
target = target.substring(target.lastIndexOf('.')+1);
if (!source.equals(target)) {
Node sourceNode = getMethodNode(graph, source, methodNodes, attFullName);
Node targetNode = getMethodNode(graph, target, methodNodes, attFullName);
if (idSet.add(sourceNode.getId()+":"+targetNode.getId())) {
sourceNode.connectTo(String.valueOf(idSet.size()), targetNode).setEdgeType(EdgeType.DIRECTED);
}
}
}
}
}
}
}
}
}
StaxGraphWriter graphWriter = new StaxGraphWriter();
File f = new File(callGraph+".gexf");
try (Writer out = new FileWriter(f, false)) {
graphWriter.writeToStream(gexf, out, "UTF-8");
System.out.println(f.getAbsolutePath());
}
}
}
private static Node getMethodNode(Graph graph, String method, Map<String, Node> methodNodes, Attribute attFullName) {
int colonIdx = method.indexOf(":");
String methodName = method.substring(colonIdx+1);
Node methodNode = methodNodes.get(methodName);
if (methodNode == null) {
methodNode = graph.createNode(String.valueOf(methodNodes.size()));
Color color = new ColorImpl(127, 127, 127);
if (method.startsWith("Renderer")) {
color.setG(255);
} else if (method.startsWith("Route")) {
color.setB(255);
} else {
color.setR(255);
}
methodNode.setLabel(methodName).setColor(color);
methodNode.getAttributeValues().addValue(attFullName, method);
methodNodes.put(methodName, methodNode);
}
return methodNode;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment