1 19 20 package ca.mcgill.sable.soot.cfg; 21 22 import soot.toolkits.graph.*; 23 import ca.mcgill.sable.soot.cfg.model.*; 24 import java.util.*; 25 import ca.mcgill.sable.soot.*; 26 import org.eclipse.ui.*; 27 import org.eclipse.core.runtime.*; 28 import org.eclipse.core.resources.*; 29 import soot.toolkits.graph.interaction.*; 30 import soot.toolkits.scalar.*; 31 import soot.*; 32 33 34 35 public class ModelCreator { 36 37 private DirectedGraph sootGraph; 38 private CFGGraph model; 39 private IResource resource; 40 private String edName = "CFG Editor"; 41 private HashMap nodeMap = new HashMap(); 42 43 44 public ModelCreator() { 45 } 46 47 public void buildModel(CFGGraph cfgGraph){ 48 cfgGraph.setResource(getResource()); 49 Iterator nodesIt = getSootGraph().iterator(); 50 ArrayList nodeList = new ArrayList(); 51 ArrayList edgeList = new ArrayList(); 52 53 boolean isExceptions = false; 54 ArrayList exceptHeads = null; 55 if (getSootGraph().getHeads().size() > 1) { 56 isExceptions = true; 57 } 58 if (getSootGraph() instanceof UnitGraph){ 60 UnitGraph unitGraph = (UnitGraph)getSootGraph(); 61 if (isExceptions){ 62 exceptHeads = findExceptionBlockHeads(unitGraph.getBody()); 63 } 64 } 65 while (nodesIt.hasNext()){ 66 Object node = nodesIt.next(); 67 CFGNode cfgNode; 68 if (!getNodeMap().containsKey(node)){ 69 cfgNode = new CFGNode(); 70 initializeNode(node, cfgNode, cfgGraph); 71 getNodeMap().put(node, cfgNode); 72 } 73 else { 74 cfgNode = (CFGNode)getNodeMap().get(node); 75 } 76 Iterator succIt = getSootGraph().getSuccsOf(node).iterator(); 77 while (succIt.hasNext()){ 78 Object succ = succIt.next(); 79 CFGNode cfgSucc; 80 if (!getNodeMap().containsKey(succ)){ 81 cfgSucc = new CFGNode(); 82 initializeNode(succ, cfgSucc, cfgGraph); 83 getNodeMap().put(succ, cfgSucc); 84 } 85 else { 86 cfgSucc = (CFGNode)getNodeMap().get(succ); 87 } 88 CFGEdge cfgEdge = new CFGEdge(cfgNode, cfgSucc); 89 90 } 91 } 92 Iterator headsIt = getSootGraph().getHeads().iterator(); 93 while (headsIt.hasNext()){ 94 Object next = headsIt.next(); 95 CFGNode node = (CFGNode)getNodeMap().get(next); 96 if ((exceptHeads != null) && exceptHeads.contains(next)) continue; 97 node.getData().setHead(true); 98 } 99 Iterator tailsIt = getSootGraph().getTails().iterator(); 100 while (tailsIt.hasNext()){ 101 Object next = tailsIt.next(); 102 CFGNode node = (CFGNode)getNodeMap().get(next); 103 node.getData().setTail(true); 104 } 105 106 setModel(cfgGraph); 107 108 } 109 110 private boolean canFit(CFGPartialFlowData pFlow, int length){ 111 Iterator it = pFlow.getChildren().iterator(); 112 int total = 0; 113 while (it.hasNext()){ 114 String next = ((CFGFlowInfo)it.next()).getText(); 115 total += next.length(); 116 } 117 if (total + length < 60) return true; 118 return false; 119 } 120 121 public void highlightNode(soot.Unit u){ 122 Iterator it = getNodeMap().keySet().iterator(); 123 while (it.hasNext()){ 124 Object next = it.next(); 125 if (next.equals(u)){ 126 CFGNode node = (CFGNode)getNodeMap().get(next); 127 node.handleHighlightEvent(next); 128 } 129 } 130 } 131 132 public ArrayList findExceptionBlockHeads(Body b){ 133 ArrayList exceptHeads = new ArrayList(); 134 Iterator trapsIt = b.getTraps().iterator(); 135 while (trapsIt.hasNext()){ 136 Trap trap = (Trap)trapsIt.next(); 137 exceptHeads.add(trap.getBeginUnit()); 138 } 139 return exceptHeads; 140 } 141 142 public void updateNode(FlowInfo fi){ 143 Iterator it = getNodeMap().keySet().iterator(); 144 while (it.hasNext()){ 145 Object next = it.next(); 146 if (next.equals(fi.unit())){ 147 CFGNode node = (CFGNode)getNodeMap().get(next); 148 getModel().newFlowData(); 149 CFGFlowData data = new CFGFlowData(); 150 if (fi.isBefore()){ 151 node.setBefore(data); 152 } 153 else{ 154 node.setAfter(data); 155 } 156 if (fi.info() instanceof FlowSet){ 157 FlowSet fs = (FlowSet)fi.info(); 158 Iterator fsIt = fs.iterator(); 159 CFGFlowInfo startBrace = new CFGFlowInfo(); 160 CFGPartialFlowData nextFlow = new CFGPartialFlowData(); 161 data.addChild(nextFlow); 162 nextFlow.addChild(startBrace); 163 startBrace.setText("{"); 164 165 while (fsIt.hasNext()){ 166 Object elem = fsIt.next(); 167 CFGFlowInfo info = new CFGFlowInfo(); 168 if (canFit(nextFlow, elem.toString().length())){ 169 nextFlow.addChild(info); 170 } 171 else { 172 nextFlow = new CFGPartialFlowData(); 173 data.addChild(nextFlow); 174 nextFlow.addChild(info); 175 } 176 177 info.setText(elem.toString()); 178 if(fsIt.hasNext()){ 179 CFGFlowInfo comma = new CFGFlowInfo(); 180 nextFlow.addChild(comma); 181 comma.setText(", "); 182 } 183 } 184 CFGFlowInfo endBrace = new CFGFlowInfo(); 185 nextFlow.addChild(endBrace); 186 endBrace.setText("}"); 187 } 188 else { 189 String text = fi.info().toString(); 190 ArrayList textGroups = new ArrayList(); 191 int last = 0; 192 for (int i = 0; i < text.length()/50; i++){ 193 if (last+50 < text.length()){ 194 int nextComma = text.indexOf(",", last+50); 195 if (nextComma != -1){ 196 textGroups.add(text.substring(last, nextComma+1)); 197 last = nextComma+2; 198 } 199 } 200 } 201 if (last < text.length()){ 202 textGroups.add(text.substring(last)); 203 } 204 205 Iterator itg = textGroups.iterator(); 206 while (itg.hasNext()){ 207 String nextGroup = (String )itg.next(); 208 CFGFlowInfo info = new CFGFlowInfo(); 209 CFGPartialFlowData pFlow = new CFGPartialFlowData(); 210 data.addChild(pFlow); 211 pFlow.addChild(info); 212 info.setText(nextGroup); 213 } 214 } 215 216 } 217 } 218 } 219 220 private void initializeNode(Object sootNode, CFGNode cfgNode, CFGGraph cfgGraph){ 221 ArrayList textList = new ArrayList(); 222 int width = 0; 223 if (sootNode instanceof soot.toolkits.graph.Block){ 224 soot.toolkits.graph.Block block = (soot.toolkits.graph.Block)sootNode; 225 Iterator it = block.iterator(); 226 while (it.hasNext()){ 227 soot.Unit u = (soot.Unit)it.next(); 228 if (width < u.toString().length()){ 229 width = u.toString().length(); 230 } 231 textList.add(u); 232 } 233 } 234 else { 235 textList.add(sootNode); 236 width = sootNode.toString().length(); 237 } 238 239 cfgGraph.addChild(cfgNode); 240 241 CFGNodeData nodeData = new CFGNodeData(); 242 cfgNode.setData(nodeData); 243 244 nodeData.setText(textList); 245 } 246 247 IEditorPart part; 248 249 public void displayModel(){ 250 IWorkbenchPage page = SootPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getActivePage(); 251 try{ 252 CFGGraph cfgGraph = new CFGGraph(); 253 cfgGraph.setName("cfgGraph"); 254 255 part = page.openEditor(cfgGraph, "ca.mcgill.sable.soot.cfg.CFGEditor"); 256 if (part instanceof CFGEditor){ 257 ((CFGEditor)part).setTitle(getEdName()); 258 ((CFGEditor)part).setTitleTooltip(getEdName()); 259 } 260 buildModel(cfgGraph); 261 } 262 catch (PartInitException ex){ 263 System.out.println("error message: "+ex.getMessage()); 264 System.out.println("part kind: "+part.getClass()); 265 ex.printStackTrace(); 266 } 267 catch(Exception e){ 268 System.out.println("exception error msg: "+e.getMessage()); 269 System.out.println("error type: "+e.getClass()); 270 e.printStackTrace(); 271 } 272 } 273 274 public void setEditorName(String name){ 275 edName = name; 276 } 277 278 public String getEditorName(){ 279 return edName; 280 } 281 282 285 public DirectedGraph getSootGraph() { 286 return sootGraph; 287 } 288 289 292 public void setSootGraph(DirectedGraph graph) { 293 sootGraph = graph; 294 } 295 296 299 public CFGGraph getModel() { 300 return model; 301 } 302 303 306 public void setModel(CFGGraph graph) { 307 model = graph; 308 } 309 310 313 public IResource getResource() { 314 return resource; 315 } 316 317 320 public void setResource(IResource resource) { 321 this.resource = resource; 322 } 323 324 327 public String getEdName() { 328 return edName; 329 } 330 331 334 public HashMap getNodeMap() { 335 return nodeMap; 336 } 337 338 341 public void setEdName(String string) { 342 edName = string; 343 } 344 345 348 public void setNodeMap(HashMap map) { 349 nodeMap = map; 350 } 351 352 } 353 | Popular Tags |