Java tutorial
/* Soot - a J*va Optimization Framework * Copyright (C) 2004 Jennifer Lhotak * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package ca.mcgill.sable.soot.callgraph; import org.eclipse.ui.*; import org.eclipse.jface.action.*; import org.eclipse.jface.viewers.*; import ca.mcgill.sable.graph.*; import ca.mcgill.sable.graph.model.*; import org.eclipse.core.runtime.*; import java.util.*; import java.lang.reflect.*; import soot.jimple.toolkits.annotation.callgraph.*; import soot.*; import soot.tagkit.*; import ca.mcgill.sable.soot.interaction.*; import ca.mcgill.sable.soot.*; import org.eclipse.swt.widgets.*; import org.eclipse.ui.plugin.*; import soot.toolkits.graph.interaction.*; import org.eclipse.core.resources.*; import org.eclipse.jdt.core.*; import org.eclipse.ui.texteditor.*; import org.eclipse.ui.part.*; public class CallGraphGenerator { private CallGraphInfo info; private Graph graph; private InteractionController controller; private ArrayList centerList; public CallGraphGenerator() { } public void run() { IWorkbench workbench = SootPlugin.getDefault().getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); IWorkbenchPage page = window.getActivePage(); ; try { if (graph == null) { setGraph(new Graph()); graph.setName("CallGraph"); } else { graph.removeAllChildren(); } IEditorPart part = page.openEditor(graph, "ca.mcgill.sable.graph.GraphEditor", true); ((GraphEditor) part).setPartFactory(new CallGraphPartFactory()); addActions((GraphEditor) part); ((GraphEditor) part) .setMenuProvider(new CGMenuProvider(((GraphEditor) part).getGraphEditorGraphicalViewer(), ((GraphEditor) part).getGraphEditorActionRegistry(), part)); buildModel(); } catch (PartInitException e3) { e3.printStackTrace(); } catch (Exception e2) { e2.printStackTrace(); } } public void addActions(GraphEditor part) { ShowCodeAction showCode = new ShowCodeAction((IWorkbenchPart) part); part.getGraphEditorActionRegistry().registerAction(showCode); part.getGraphEditorSelectionActions().add(showCode.getId()); ExpandAction expand = new ExpandAction((IWorkbenchPart) part); part.getGraphEditorActionRegistry().registerAction(expand); part.getGraphEditorSelectionActions().add(expand.getId()); CollapseAction collapse = new CollapseAction((IWorkbenchPart) part); part.getGraphEditorActionRegistry().registerAction(collapse); part.getGraphEditorSelectionActions().add(collapse.getId()); } public void buildModel() { CallGraphNode cgn = new CallGraphNode(); getGraph().addChild(cgn); cgn.setGenerator(this); cgn.setData(getInfo().getCenter()); cgn.setExpand(false); makeCons(getInfo(), cgn); } private CallGraphNode getNodeForMethod(SootMethod meth) { CallGraphNode node = null; Iterator it = getGraph().getChildren().iterator(); while (it.hasNext()) { CallGraphNode next = (CallGraphNode) it.next(); if (next.getData().equals(meth)) { node = next; } } if (node == null) { node = new CallGraphNode(); getGraph().addChild(node); node.setData(meth); } return node; } private void makeCons(CallGraphInfo info, CallGraphNode center) { Iterator it1 = info.getInputs().iterator(); while (it1.hasNext()) { MethInfo mInfo = (MethInfo) it1.next(); SootMethod sm = mInfo.method(); CallGraphNode inNode = getNodeForMethod(sm); inNode.setGenerator(this); Edge inEdge = new Edge(inNode, center); inEdge.setLabel(mInfo.edgeKind().name()); } Iterator it2 = info.getOutputs().iterator(); while (it2.hasNext()) { MethInfo mInfo = (MethInfo) it2.next(); SootMethod sm = mInfo.method(); CallGraphNode outNode = getNodeForMethod(sm); outNode.setGenerator(this); Edge inEdge = new Edge(center, outNode); inEdge.setLabel(mInfo.edgeKind().name()); } } public void collapseGraph(CallGraphNode node) { // need to undo (remove in and out nodes // who are not in center list) ArrayList inputsToRemove = new ArrayList(); ArrayList outputsToRemove = new ArrayList(); ArrayList nodesToRemove = new ArrayList(); if (node.getInputs() != null) { Iterator inIt = node.getInputs().iterator(); while (inIt.hasNext()) { Edge next = (Edge) inIt.next(); CallGraphNode src = (CallGraphNode) next.getSrc(); if (src.isLeaf()) { inputsToRemove.add(next); nodesToRemove.add(src); } } } if (node.getOutputs() != null) { Iterator outIt = node.getOutputs().iterator(); while (outIt.hasNext()) { Edge next = (Edge) outIt.next(); CallGraphNode tgt = (CallGraphNode) next.getTgt(); if (tgt.isLeaf()) { outputsToRemove.add(next); nodesToRemove.add(tgt); } } } Iterator inRIt = inputsToRemove.iterator(); while (inRIt.hasNext()) { Edge temp = (Edge) inRIt.next(); node.removeInput(temp); } Iterator outRIt = outputsToRemove.iterator(); while (outRIt.hasNext()) { Edge temp = (Edge) outRIt.next(); node.removeInput(temp); } Iterator nodeRIt = nodesToRemove.iterator(); while (nodeRIt.hasNext()) { CallGraphNode temp = (CallGraphNode) nodeRIt.next(); temp.removeAllInputs(); temp.removeAllOutputs(); getGraph().removeChild(temp); } node.setExpand(true); } public void expandGraph(CallGraphNode node) { getController() .setEvent(new InteractionEvent(IInteractionConstants.CALL_GRAPH_NEXT_METHOD, node.getData())); getController().handleEvent(); } public void showInCode(CallGraphNode node) { SootMethod meth = (SootMethod) node.getData(); String sootClassName = meth.getDeclaringClass().getName(); sootClassName = sootClassName.replaceAll("\\.", System.getProperty("file.separator")); sootClassName = sootClassName + ".java"; String sootMethName = meth.getName(); IProject[] progs = SootPlugin.getWorkspace().getRoot().getProjects(); IResource fileToOpen = null; for (int i = 0; i < progs.length; i++) { IProject project = progs[i]; IJavaProject jProj = JavaCore.create(project); try { IPackageFragmentRoot[] roots = jProj.getAllPackageFragmentRoots(); for (int j = 0; j < roots.length; j++) { if (!(roots[j].getResource() instanceof IContainer)) continue; fileToOpen = ((IContainer) roots[j].getResource()).findMember(sootClassName); if (fileToOpen == null) continue; else break; } } catch (Exception e) { } if (fileToOpen != null) break; } IWorkbench workbench = SootPlugin.getDefault().getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); IWorkbenchPage page = window.getActivePage(); ; try { IEditorPart part = page.openEditor(new FileEditorInput((IFile) fileToOpen), org.eclipse.jdt.ui.JavaUI.ID_CU_EDITOR); SourceLnPosTag methTag = (SourceLnPosTag) meth.getTag("SourceLnPosTag"); if (methTag != null) { int selOffset = ((AbstractTextEditor) part).getDocumentProvider().getDocument(part.getEditorInput()) .getLineOffset(methTag.startLn() - 1); ((AbstractTextEditor) SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow() .getActivePage().getActiveEditor()).selectAndReveal(selOffset, 0); } } catch (PartInitException e3) { e3.printStackTrace(); } catch (Exception e2) { e2.printStackTrace(); } } public void addToGraph(Object info) { CallGraphInfo cgInfo = (CallGraphInfo) info; SootMethod center = cgInfo.getCenter(); // find the center who is already in the graph CallGraphNode centerNode = getNodeForMethod(cgInfo.getCenter()); //addToCenterList(cgInfo.getCenter()); centerNode.setExpand(false); // make connections to all the children makeCons(cgInfo, centerNode); } /** * @return */ public Graph getGraph() { return graph; } /** * @param graph */ public void setGraph(Graph graph) { this.graph = graph; } /** * @return */ public CallGraphInfo getInfo() { return info; } /** * @param info */ public void setInfo(CallGraphInfo info) { this.info = info; } /** * @return */ public InteractionController getController() { return controller; } /** * @param controller */ public void setController(InteractionController controller) { this.controller = controller; } public void addToCenterList(Object obj) { if (getCenterList() == null) { setCenterList(new ArrayList()); } getCenterList().add(obj); } /** * @return */ public ArrayList getCenterList() { return centerList; } /** * @param list */ public void setCenterList(ArrayList list) { centerList = list; } }