KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > ca > mcgill > sable > soot > callgraph > CallGraphGenerator


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2004 Jennifer Lhotak
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */

19
20
21 package ca.mcgill.sable.soot.callgraph;
22 import org.eclipse.ui.*;
23 import org.eclipse.jface.action.*;
24 import org.eclipse.jface.viewers.*;
25 import ca.mcgill.sable.graph.*;
26 import ca.mcgill.sable.graph.model.*;
27 import org.eclipse.core.runtime.*;
28 import java.util.*;
29 import java.lang.reflect.*;
30 import soot.jimple.toolkits.annotation.callgraph.*;
31 import soot.*;
32 import soot.tagkit.*;
33 import ca.mcgill.sable.soot.interaction.*;
34 import ca.mcgill.sable.soot.*;
35 import org.eclipse.swt.widgets.*;
36 import org.eclipse.ui.plugin.*;
37 import soot.toolkits.graph.interaction.*;
38 import org.eclipse.core.resources.*;
39 import org.eclipse.jdt.core.*;
40 import org.eclipse.ui.texteditor.*;
41 import org.eclipse.ui.part.*;
42
43 public class CallGraphGenerator {
44     
45     private CallGraphInfo info;
46     private Graph graph;
47     private InteractionController controller;
48     private ArrayList centerList;
49     
50
51     public CallGraphGenerator() {
52     }
53     
54     public void run(){
55         
56         IWorkbench workbench = SootPlugin.getDefault().getWorkbench();
57         IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
58         IWorkbenchPage page = window.getActivePage();;
59         
60         try{
61             if (graph == null){
62                 setGraph(new Graph());
63                 graph.setName("CallGraph");
64             }
65             else{
66                 graph.removeAllChildren();
67             }
68             IEditorPart part = page.openEditor(graph, "ca.mcgill.sable.graph.GraphEditor", true);
69             ((GraphEditor)part).setPartFactory(new CallGraphPartFactory());
70             addActions((GraphEditor)part);
71             ((GraphEditor)part).setMenuProvider(new CGMenuProvider(((GraphEditor)part).getGraphEditorGraphicalViewer(), ((GraphEditor)part).getGraphEditorActionRegistry(), part));
72             
73             buildModel();
74         }
75         catch (PartInitException e3){
76             e3.printStackTrace();
77         }
78         catch (Exception JavaDoc e2){
79             e2.printStackTrace();
80         }
81     }
82     
83     public void addActions(GraphEditor part){
84         ShowCodeAction showCode = new ShowCodeAction((IWorkbenchPart)part);
85         part.getGraphEditorActionRegistry().registerAction(showCode);
86         part.getGraphEditorSelectionActions().add(showCode.getId());
87     
88         ExpandAction expand = new ExpandAction((IWorkbenchPart)part);
89         part.getGraphEditorActionRegistry().registerAction(expand);
90         part.getGraphEditorSelectionActions().add(expand.getId());
91         
92         CollapseAction collapse = new CollapseAction((IWorkbenchPart)part);
93         part.getGraphEditorActionRegistry().registerAction(collapse);
94         part.getGraphEditorSelectionActions().add(collapse.getId());
95             
96     }
97     
98     public void buildModel(){
99         CallGraphNode cgn = new CallGraphNode();
100         getGraph().addChild(cgn);
101         cgn.setGenerator(this);
102         cgn.setData(getInfo().getCenter());
103
104         cgn.setExpand(false);
105         makeCons(getInfo(), cgn);
106             
107     }
108     
109     private CallGraphNode getNodeForMethod(SootMethod meth){
110         CallGraphNode node = null;
111         Iterator it = getGraph().getChildren().iterator();
112         while (it.hasNext()){
113             CallGraphNode next = (CallGraphNode)it.next();
114             if (next.getData().equals(meth)){
115                 node = next;
116             }
117         }
118         if (node == null){
119             node = new CallGraphNode();
120             getGraph().addChild(node);
121             node.setData(meth);
122         }
123         return node;
124     }
125     
126     private void makeCons(CallGraphInfo info, CallGraphNode center){
127         Iterator it1 = info.getInputs().iterator();
128         while (it1.hasNext()){
129             MethInfo mInfo = (MethInfo)it1.next();
130             SootMethod sm = mInfo.method();
131             CallGraphNode inNode = getNodeForMethod(sm);
132             inNode.setGenerator(this);
133             Edge inEdge = new Edge(inNode, center);
134             inEdge.setLabel(mInfo.edgeKind().name());
135         }
136         
137         Iterator it2 = info.getOutputs().iterator();
138         while (it2.hasNext()){
139             MethInfo mInfo = (MethInfo)it2.next();
140             SootMethod sm = mInfo.method();
141             CallGraphNode outNode = getNodeForMethod(sm);
142             outNode.setGenerator(this);
143             Edge inEdge = new Edge(center, outNode);
144             inEdge.setLabel(mInfo.edgeKind().name());
145         }
146     }
147     
148     public void collapseGraph(CallGraphNode node){
149         // need to undo (remove in and out nodes
150
// who are not in center list)
151
ArrayList inputsToRemove = new ArrayList();
152         ArrayList outputsToRemove = new ArrayList();
153         ArrayList nodesToRemove = new ArrayList();
154         
155         if (node.getInputs() != null){
156             Iterator inIt = node.getInputs().iterator();
157             while (inIt.hasNext()){
158                 Edge next = (Edge)inIt.next();
159                 CallGraphNode src = (CallGraphNode)next.getSrc();
160                 if (src.isLeaf()){
161                     inputsToRemove.add(next);
162                     nodesToRemove.add(src);
163                 }
164             }
165         }
166         
167         if (node.getOutputs() != null){
168             Iterator outIt = node.getOutputs().iterator();
169             while (outIt.hasNext()){
170                 Edge next = (Edge)outIt.next();
171                 CallGraphNode tgt = (CallGraphNode)next.getTgt();
172                 if (tgt.isLeaf()){
173                     outputsToRemove.add(next);
174                     nodesToRemove.add(tgt);
175                 }
176             }
177         }
178         
179         Iterator inRIt = inputsToRemove.iterator();
180         while (inRIt.hasNext()){
181             Edge temp = (Edge)inRIt.next();
182             node.removeInput(temp);
183         }
184         
185         Iterator outRIt = outputsToRemove.iterator();
186         while (outRIt.hasNext()){
187             Edge temp = (Edge)outRIt.next();
188             node.removeInput(temp);
189         }
190         
191         Iterator nodeRIt = nodesToRemove.iterator();
192         while (nodeRIt.hasNext()){
193             CallGraphNode temp = (CallGraphNode)nodeRIt.next();
194             temp.removeAllInputs();
195             temp.removeAllOutputs();
196             getGraph().removeChild(temp);
197         }
198         
199         node.setExpand(true);
200     }
201     
202     public void expandGraph(CallGraphNode node){
203         getController().setEvent(new InteractionEvent(IInteractionConstants.CALL_GRAPH_NEXT_METHOD, node.getData()));
204         getController().handleEvent();
205     
206     }
207     
208     public void showInCode(CallGraphNode node){
209         SootMethod meth = (SootMethod)node.getData();
210         String JavaDoc sootClassName = meth.getDeclaringClass().getName();
211         sootClassName = sootClassName.replaceAll("\\.", System.getProperty("file.separator"));
212         sootClassName = sootClassName + ".java";
213         String JavaDoc sootMethName = meth.getName();
214         
215         IProject [] progs = SootPlugin.getWorkspace().getRoot().getProjects();
216         IResource fileToOpen = null;
217         for (int i = 0; i < progs.length; i++){
218             IProject project = progs[i];
219             
220             IJavaProject jProj = JavaCore.create(project);
221             try {
222     
223                 IPackageFragmentRoot [] roots = jProj.getAllPackageFragmentRoots();
224                 for (int j = 0; j < roots.length; j++){
225                     if (!(roots[j].getResource() instanceof IContainer)) continue;
226                     fileToOpen = ((IContainer)roots[j].getResource()).findMember(sootClassName);
227                     if (fileToOpen == null) continue;
228                     else break;
229                 }
230             }
231             catch(Exception JavaDoc e){
232             }
233         
234             if (fileToOpen != null) break;
235         }
236         
237         
238         
239         IWorkbench workbench = SootPlugin.getDefault().getWorkbench();
240         IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
241         IWorkbenchPage page = window.getActivePage();;
242         
243         try{
244             IEditorPart part = page.openEditor(new FileEditorInput((IFile)fileToOpen), org.eclipse.jdt.ui.JavaUI.ID_CU_EDITOR);
245             SourceLnPosTag methTag = (SourceLnPosTag)meth.getTag("SourceLnPosTag");
246             if (methTag != null){
247                 
248                 int selOffset = ((AbstractTextEditor)part).getDocumentProvider().getDocument(part.getEditorInput()).getLineOffset(methTag.startLn()-1);
249             
250                 ((AbstractTextEditor)SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor()).selectAndReveal(selOffset, 0);
251             }
252                     
253         }
254         catch (PartInitException e3){
255             e3.printStackTrace();
256         }
257         
258         catch (Exception JavaDoc e2){
259             e2.printStackTrace();
260         }
261     }
262     
263     public void addToGraph(Object JavaDoc info){
264         CallGraphInfo cgInfo = (CallGraphInfo)info;
265         
266         SootMethod center = cgInfo.getCenter();
267         
268         // find the center who is already in the graph
269
CallGraphNode centerNode = getNodeForMethod(cgInfo.getCenter());
270         //addToCenterList(cgInfo.getCenter());
271
centerNode.setExpand(false);
272         // make connections to all the children
273
makeCons(cgInfo, centerNode);
274     }
275
276     /**
277      * @return
278      */

279     public Graph getGraph() {
280         return graph;
281     }
282
283     /**
284      * @param graph
285      */

286     public void setGraph(Graph graph) {
287         this.graph = graph;
288     }
289
290     /**
291      * @return
292      */

293     public CallGraphInfo getInfo() {
294         return info;
295     }
296
297     /**
298      * @param info
299      */

300     public void setInfo(CallGraphInfo info) {
301         this.info = info;
302     }
303
304     /**
305      * @return
306      */

307     public InteractionController getController() {
308         return controller;
309     }
310
311     /**
312      * @param controller
313      */

314     public void setController(InteractionController controller) {
315         this.controller = controller;
316     }
317     
318     public void addToCenterList(Object JavaDoc obj){
319         if (getCenterList() == null){
320             setCenterList(new ArrayList());
321         }
322         getCenterList().add(obj);
323     }
324
325     /**
326      * @return
327      */

328     public ArrayList getCenterList() {
329         return centerList;
330     }
331
332     /**
333      * @param list
334      */

335     public void setCenterList(ArrayList list) {
336         centerList = list;
337     }
338
339 }
340
Popular Tags