KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > xml > XMLPrinter


1 /* Soot - a J*va Optimization Framework
2  * Copyright (C) 2002 David Eng
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  * Modified by the Sable Research Group and others 1997-1999.
22  * See the 'credits' file distributed with Soot for the complete list of
23  * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
24  */

25
26 package soot.xml;
27 import soot.*;
28 import java.util.*;
29 import soot.util.*;
30 import soot.toolkits.graph.*;
31 import soot.toolkits.scalar.*;
32 import soot.jimple.InvokeExpr;
33 import soot.jimple.SpecialInvokeExpr;
34 import soot.jimple.StaticInvokeExpr;
35 import soot.jimple.Stmt;
36 import soot.jimple.toolkits.invoke.*;
37 import java.io.*;
38
39 /** XML printing routines all XML output comes through here */
40 public class XMLPrinter {
41     // xml and dtd header
42
public static final String JavaDoc xmlHeader = "<?xml version=\"1.0\" ?>\n";
43     public static final String JavaDoc dtdHeader =
44         "<!DOCTYPE jil SYSTEM \"http://www.sable.mcgill.ca/~flynn/jil/jil10.dtd\">\n";
45
46     // xml tree
47
public XMLRoot root;
48
49     // returns the buffer - this is the XML output
50
public String JavaDoc toString() {
51         if (root != null)
52             return root.toString();
53         else
54             throw new RuntimeException JavaDoc("Error generating XML!");
55     }
56
57     // add single element <...>...</...>
58
public XMLNode addElement(String JavaDoc name) {
59         return addElement(name, "", "", "");
60     }
61     public XMLNode addElement(String JavaDoc name, String JavaDoc value) {
62         return addElement(name, value, "", "");
63     }
64     public XMLNode addElement(String JavaDoc name, String JavaDoc value, String JavaDoc[] attributes) {
65         return addElement(name, value, attributes, null);
66     }
67     public XMLNode addElement(
68         String JavaDoc name,
69         String JavaDoc value,
70         String JavaDoc attribute,
71         String JavaDoc attributeValue) {
72         return addElement(
73             name,
74             value,
75             new String JavaDoc[] { attribute },
76             new String JavaDoc[] { attributeValue });
77     }
78     public XMLNode addElement(
79         String JavaDoc name,
80         String JavaDoc value,
81         String JavaDoc[] attributes,
82         String JavaDoc[] values) {
83         return root.addElement(name, value, attributes, values);
84     }
85
86     public XMLPrinter(Singletons.Global g) {
87     }
88     public static XMLPrinter v() {
89         return G.v().soot_xml_XMLPrinter();
90     }
91
92     private XMLNode xmlNode = null;
93     public XMLNode setXMLNode(XMLNode node) {
94         return (this.xmlNode = node);
95     }
96
97     /** Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>. */
98     private void printStatementsInBody(Body body, java.io.PrintWriter JavaDoc out) {
99     LabeledUnitPrinter up = new NormalUnitPrinter(body);
100         Map stmtToName = up.labels();
101
102         Chain units = body.getUnits();
103
104         //UnitGraph unitGraph = new soot.toolkits.graph.BriefUnitGraph( body );
105
ExceptionalUnitGraph exceptionalUnitGraph =
106             new soot.toolkits.graph.ExceptionalUnitGraph(body);
107
108         // include any analysis which will be used in the xml output
109
LiveLocals sll = new SimpleLiveLocals(exceptionalUnitGraph);
110
111         // iterate through each statement
112
String JavaDoc cleanMethodName = cleanMethod(body.getMethod().getName());
113         Iterator unitIt = units.iterator();
114         Unit currentStmt = null;
115         Unit previousStmt;
116         String JavaDoc indent = " ";
117         String JavaDoc currentLabel = "default";
118         long statementCount = 0;
119         long labelCount = 0;
120         long labelID = 0;
121         int index = 0;
122
123         // lists
124
Vector useList = new Vector();
125         Vector useDataList = new Vector();
126         Vector defList = new Vector();
127         Vector defDataList = new Vector();
128         Vector paramData = new Vector();
129         Vector xmlLabelsList = new Vector();
130         long maxStmtCount = 0;
131
132         /*
133         // for invokes, add a list of potential targets
134         if (!Scene.v().hasActiveInvokeGraph()) {
135             InvokeGraphBuilder.v().transform("jil.igb");
136         }
137
138         // build an invoke graph based on class hiearchy analysis
139         InvokeGraph igCHA = Scene.v().getActiveInvokeGraph();
140
141         // build an invoke graph based on variable type analysis
142         InvokeGraph igVTA = Scene.v().getActiveInvokeGraph();
143         try {
144             VariableTypeAnalysis vta = null;
145             int VTApasses = 1;
146             //Options.getInt( PackManager.v().getPhaseOptions( "jil.igb" ), "VTA-passes" );
147             for (int i = 0; i < VTApasses; i++) {
148                 vta = new VariableTypeAnalysis(igVTA);
149                 vta.trimActiveInvokeGraph();
150                 igVTA.refreshReachableMethods();
151             }
152         } catch (RuntimeException re) {
153             // this will fail if the --analyze-context flag is not specified
154             // G.v().out.println( "JIL VTA FAILED: " + re );
155             igVTA = null;
156         }
157         */

158
159         // add method node
160
XMLNode methodNode =
161             xmlNode.addChild(
162                 "method",
163                 new String JavaDoc[] { "name", "returntype", "class" },
164                 new String JavaDoc[] {
165                     cleanMethodName,
166                     body.getMethod().getReturnType().toString(),
167                     body.getMethod().getDeclaringClass().getName().toString()});
168         String JavaDoc declarationStr =
169             body.getMethod().getDeclaration().toString().trim();
170         methodNode.addChild(
171             "declaration",
172             toCDATA(declarationStr),
173             new String JavaDoc[] { "length" },
174             new String JavaDoc[] { declarationStr.length() + "" });
175
176         // create references to parameters, locals, labels, stmts nodes
177
XMLNode parametersNode =
178             methodNode.addChild(
179                 "parameters",
180                 new String JavaDoc[] { "method" },
181                 new String JavaDoc[] { cleanMethodName });
182         XMLNode localsNode = methodNode.addChild("locals");
183         XMLNode labelsNode = methodNode.addChild("labels");
184         XMLNode stmtsNode = methodNode.addChild("statements");
185
186         // create default label
187
XMLLabel xmlLabel =
188             new XMLLabel(labelCount, cleanMethodName, currentLabel);
189         labelsNode.addChild(
190             "label",
191             new String JavaDoc[] { "id", "name", "method" },
192             new String JavaDoc[] {(labelCount++) + "", currentLabel, cleanMethodName });
193
194         // for each statement...
195
while (unitIt.hasNext()) {
196             previousStmt = currentStmt;
197             currentStmt = (Unit) unitIt.next();
198             Stmt stmtCurrentStmt = (Stmt) currentStmt;
199
200             // new label
201
if (stmtToName.containsKey(currentStmt)) {
202                 currentLabel = stmtToName.get(currentStmt).toString();
203
204                 // fill in the stmt count for the previous label
205
//index = xmlLabels.indexOf( "%s" );
206
//if( index != -1 )
207
// xmlLabels = xmlLabels.substring( 0, index ) + ( labelID ) + xmlLabels.substring( index + 2 );
208
//index = xmlLabels.indexOf( "%d" );
209
//if( index != -1 )
210
// xmlLabels = xmlLabels.substring( 0, index ) + new Float( ( new Float( labelID ).floatValue() / new Float( units.size() ).intValue() ) * 100.0 ).intValue() + xmlLabels.substring( index + 2 );
211

212                 xmlLabel.stmtCount = labelID;
213                 xmlLabel.stmtPercentage =
214                     new Float JavaDoc(
215                         (new Float JavaDoc(labelID).floatValue()
216                             / new Float JavaDoc(units.size()).intValue())
217                             * 100.0)
218                         .longValue();
219                 if (xmlLabel.stmtPercentage > maxStmtCount)
220                     maxStmtCount = xmlLabel.stmtPercentage;
221
222                 xmlLabelsList.addElement(xmlLabel);
223                 //xmlLabel.clear();
224

225                 xmlLabel =
226                     new XMLLabel(labelCount, cleanMethodName, currentLabel);
227                 labelsNode.addChild(
228                     "label",
229                     new String JavaDoc[] { "id", "name", "method" },
230                     new String JavaDoc[] {
231                         labelCount + "",
232                         currentLabel,
233                         cleanMethodName });
234                 labelCount++;
235                 labelID = 0;
236             }
237
238             // examine each statement
239
XMLNode stmtNode =
240                 stmtsNode.addChild(
241                     "statement",
242                     new String JavaDoc[] { "id", "label", "method", "labelid" },
243                     new String JavaDoc[] {
244                         statementCount + "",
245                         currentLabel,
246                         cleanMethodName,
247                         labelID + "" });
248             XMLNode sootstmtNode =
249                 stmtNode.addChild(
250                     "soot_statement",
251                     new String JavaDoc[] { "branches", "fallsthrough" },
252                     new String JavaDoc[] {
253                         boolToString(currentStmt.branches()),
254                         boolToString(currentStmt.fallsThrough())});
255
256             // uses for each statement
257
int j = 0;
258             Iterator boxIt = currentStmt.getUseBoxes().iterator();
259             while (boxIt.hasNext()) {
260                 ValueBox box = (ValueBox) boxIt.next();
261                 if (box.getValue() instanceof Local) {
262                     String JavaDoc local =
263                         cleanLocal(((Local) box.getValue()).toString());
264                     sootstmtNode.addChild(
265                         "uses",
266                         new String JavaDoc[] { "id", "local", "method" },
267                         new String JavaDoc[] { j + "", local, cleanMethodName });
268                     j++;
269
270                     Vector tempVector = null;
271                     int useIndex = useList.indexOf(local);
272                     if (useIndex == -1) {
273                         useDataList.addElement(tempVector);
274                         useList.addElement(local);
275                         useIndex = useList.indexOf(local);
276                     }
277
278                     if (useDataList.size() > useIndex) {
279                         tempVector = (Vector) useDataList.elementAt(useIndex);
280                         if (tempVector == null) {
281                             tempVector = new Vector();
282                         }
283                         tempVector.addElement(new Long JavaDoc(statementCount));
284                         useDataList.setElementAt(tempVector, useIndex);
285                     }
286                 }
287             }
288
289             // defines for each statement
290
j = 0;
291             boxIt = currentStmt.getDefBoxes().iterator();
292             while (boxIt.hasNext()) {
293                 ValueBox box = (ValueBox) boxIt.next();
294                 if (box.getValue() instanceof Local) {
295                     String JavaDoc local =
296                         cleanLocal(((Local) box.getValue()).toString());
297                     sootstmtNode.addChild(
298                         "defines",
299                         new String JavaDoc[] { "id", "local", "method" },
300                         new String JavaDoc[] { j + "", local, cleanMethodName });
301                     j++;
302
303                     Vector tempVector = null;
304                     int defIndex = defList.indexOf(local);
305                     if (defIndex == -1) {
306                         defDataList.addElement(tempVector);
307                         defList.addElement(local);
308                         defIndex = defList.indexOf(local);
309                     }
310
311                     if (defDataList.size() > defIndex) {
312                         tempVector = (Vector) defDataList.elementAt(defIndex);
313                         if (tempVector == null) {
314                             tempVector = new Vector();
315                         }
316                         tempVector.addElement(new Long JavaDoc(statementCount));
317                         defDataList.setElementAt(tempVector, defIndex);
318                     }
319                 }
320             }
321
322             /*
323             // for invokes, add a list of potential targets
324             if (stmtCurrentStmt.containsInvokeExpr()) {
325                 // default analysis is CHA
326                 if (igCHA != null) {
327                     try {
328                         List targets = igCHA.getTargetsOf(stmtCurrentStmt);
329                         XMLNode CHAinvoketargetsNode =
330                             sootstmtNode.addChild(
331                                 "invoketargets",
332                                 new String[] { "analysis", "count" },
333                                 new String[] { "CHA", targets.size() + "" });
334                         for (int i = 0; i < targets.size(); i++) {
335                             SootMethod meth = (SootMethod) targets.get(i);
336                             CHAinvoketargetsNode.addChild(
337                                 "target",
338                                 new String[] { "id", "class", "method" },
339                                 new String[] {
340                                     i + "",
341                                     meth.getDeclaringClass().getFullName(),
342                                     cleanMethod(meth.getName())});
343                         }
344                     } catch (RuntimeException re) {
345                         //G.v().out.println( "XML: " + re + " (" + stmtCurrentStmt + ")" );
346                     }
347                 }
348
349                 // now try VTA, which will only work if the -a or --analyze-context switch is specified
350                 if (igVTA != null) {
351                     InvokeExpr ie =
352                         (InvokeExpr) stmtCurrentStmt.getInvokeExpr();
353                     if (!(ie instanceof StaticInvokeExpr)
354                         && !(ie instanceof SpecialInvokeExpr)) {
355                         try {
356                             List targets = igVTA.getTargetsOf(stmtCurrentStmt);
357                             XMLNode VTAinvoketargetsNode =
358                                 sootstmtNode.addChild(
359                                     "invoketargets",
360                                     new String[] { "analysis", "count" },
361                                     new String[] {
362                                         "VTA",
363                                         targets.size() + "" });
364                             for (int i = 0; i < targets.size(); i++) {
365                                 SootMethod meth = (SootMethod) targets.get(i);
366                                 VTAinvoketargetsNode.addChild(
367                                     "target",
368                                     new String[] { "id", "class", "method" },
369                                     new String[] {
370                                         i + "",
371                                         meth.getDeclaringClass().getFullName(),
372                                         cleanMethod(meth.getName())});
373                             }
374                         } catch (RuntimeException re) {
375                             //G.v().out.println( "XML: " + re + " (" + stmtCurrentStmt + ")" );
376                         }
377                     }
378                 }
379             }
380             */

381
382             // simple live locals
383
List liveLocalsIn = sll.getLiveLocalsBefore(currentStmt);
384             List liveLocalsOut = sll.getLiveLocalsAfter(currentStmt);
385             XMLNode livevarsNode =
386                 sootstmtNode.addChild(
387                     "livevariables",
388                     new String JavaDoc[] { "incount", "outcount" },
389                     new String JavaDoc[] {
390                         liveLocalsIn.size() + "",
391                         liveLocalsOut.size() + "" });
392             for (int i = 0; i < liveLocalsIn.size(); i++) {
393                 livevarsNode.addChild(
394                     "in",
395                     new String JavaDoc[] { "id", "local", "method" },
396                     new String JavaDoc[] {
397                         i + "",
398                         cleanLocal(liveLocalsIn.get(i).toString()),
399                         cleanMethodName });
400             }
401             for (int i = 0; i < liveLocalsOut.size(); i++) {
402                 livevarsNode.addChild(
403                     "out",
404                     new String JavaDoc[] { "id", "local", "method" },
405                     new String JavaDoc[] {
406                         i + "",
407                         cleanLocal(liveLocalsOut.get(i).toString()),
408                         cleanMethodName });
409             }
410
411             // parameters
412
for (int i = 0;
413                 i < body.getMethod().getParameterTypes().size();
414                 i++) {
415                 Vector tempVec = new Vector();
416                 paramData.addElement(tempVec);
417             }
418
419             // parse any info from the statement code
420
currentStmt.toString(up);
421             String JavaDoc jimpleStr = up.toString().trim();
422             if (currentStmt instanceof soot.jimple.IdentityStmt &&
423         jimpleStr.indexOf("@parameter") != -1) {
424                 // this line is a use of a parameter
425
String JavaDoc tempStr =
426                     jimpleStr.substring(jimpleStr.indexOf("@parameter") + 10);
427                 if (tempStr.indexOf(":") != -1)
428                     tempStr = tempStr.substring(0, tempStr.indexOf(":")).trim();
429                 if (tempStr.indexOf(" ") != -1)
430                     tempStr = tempStr.substring(0, tempStr.indexOf(" ")).trim();
431                 int paramIndex = new Integer JavaDoc(tempStr).intValue();
432                 Vector tempVec = (Vector) paramData.elementAt(paramIndex);
433                 if (tempVec != null)
434                     tempVec.addElement(Long.toString(statementCount));
435                 paramData.setElementAt(tempVec, paramIndex);
436             }
437
438             // add plain jimple representation of each statement
439
sootstmtNode.addChild(
440                 "jimple",
441                 toCDATA(jimpleStr),
442                 new String JavaDoc[] { "length" },
443                 new String JavaDoc[] {(jimpleStr.length() + 1) + "" });
444
445             // increment statement counters
446
labelID++;
447             statementCount++;
448         }
449
450         // add count to statments
451
stmtsNode.addAttribute("count", statementCount + "");
452
453         // method parameters
454
parametersNode.addAttribute(
455             "count",
456             body.getMethod().getParameterCount() + "");
457         for (int i = 0; i < body.getMethod().getParameterTypes().size(); i++) {
458             XMLNode paramNode =
459                 parametersNode.addChild(
460                     "parameter",
461                     new String JavaDoc[] { "id", "type", "method", "name" },
462                     new String JavaDoc[] {
463                         i + "",
464                         body.getMethod().getParameterTypes().get(i).toString(),
465                         cleanMethodName,
466                         "_parameter" + i });
467             XMLNode sootparamNode = paramNode.addChild("soot_parameter");
468
469             Vector tempVec = (Vector) paramData.elementAt(i);
470             for (int k = 0; k < tempVec.size(); k++) {
471                 sootparamNode.addChild(
472                     "use",
473                     new String JavaDoc[] { "id", "line", "method" },
474                     new String JavaDoc[] {
475                         k + "",
476                         String.valueOf(tempVec.elementAt(k)) + "",
477                         cleanMethodName });
478             }
479             sootparamNode.addAttribute("uses", tempVec.size() + "");
480         }
481
482         /*
483                 index = xmlLabels.indexOf( "%s" );
484         if( index != -1 )
485                     xmlLabels = xmlLabels.substring( 0, index ) + ( labelID ) + xmlLabels.substring( index + 2 );
486         index = xmlLabels.indexOf( "%d" );
487         if( index != -1 )
488                     xmlLabels = xmlLabels.substring( 0, index ) + new Float( ( new Float( labelID ).floatValue() / new Float( units.size() ).floatValue() ) * 100.0 ).intValue() + xmlLabels.substring( index + 2 );
489         */

490
491         xmlLabel.stmtCount = labelID;
492         xmlLabel.stmtPercentage =
493             new Float JavaDoc(
494                 (new Float JavaDoc(labelID).floatValue()
495                     / new Float JavaDoc(units.size()).floatValue())
496                     * 100.0)
497                 .longValue();
498         if (xmlLabel.stmtPercentage > maxStmtCount)
499             maxStmtCount = xmlLabel.stmtPercentage;
500         xmlLabelsList.addElement(xmlLabel);
501
502         // print out locals
503
Chain locals = body.getLocals();
504         Iterator localsIterator = locals.iterator();
505         Vector localTypes = new Vector();
506         Vector typedLocals = new Vector();
507         Vector typeCounts = new Vector();
508         String JavaDoc xmlLongLocals = "";
509         int j = 0;
510         int currentType = 0;
511
512         while (localsIterator.hasNext()) {
513             int useCount = 0;
514             int defineCount = 0;
515             Local localData = (Local) localsIterator.next();
516             String JavaDoc local = cleanLocal((String JavaDoc) localData.toString());
517             String JavaDoc localType = localData.getType().toString();
518
519             // collect the local types
520
if (!localTypes.contains(localType)) {
521                 localTypes.addElement(localType);
522                 typedLocals.addElement(new Vector());
523                 typeCounts.addElement(new Integer JavaDoc(0));
524             }
525
526             // create a reference to the local node
527
XMLNode localNode =
528                 new XMLNode(
529                     "local",
530                     "",
531                     new String JavaDoc[] { "id", "method", "name", "type" },
532                     new String JavaDoc[] { j + "", cleanMethodName, local, localType });
533             XMLNode sootlocalNode = localNode.addChild("soot_local");
534             currentType = 0;
535
536             for (int k = 0; k < localTypes.size(); k++) {
537                 if (localType
538                     .equalsIgnoreCase((String JavaDoc) localTypes.elementAt(k))) {
539                     currentType = k;
540                     Integer JavaDoc tempInt =
541                         new Integer JavaDoc(
542                             ((Integer JavaDoc) typeCounts.elementAt(k)).intValue() + 1);
543                     typeCounts.setElementAt(tempInt, k);
544                     break;
545                 }
546             }
547
548             // add all uses to this local
549
for (int k = 0; k < useList.size(); k++) {
550                 String JavaDoc query = (String JavaDoc) useList.elementAt(k);
551                 if (query.equalsIgnoreCase(local)) {
552                     Vector tempVector =
553                         (Vector) useDataList.elementAt(useList.indexOf(local));
554
555                     for (int i = 0; i < tempVector.size(); i++) {
556                         sootlocalNode.addChild(
557                             "use",
558                             new String JavaDoc[] { "id", "line", "method" },
559                             new String JavaDoc[] {
560                                 i + "",
561                                 ((Long JavaDoc) tempVector.elementAt(i)).toString(),
562                                 cleanMethodName });
563                     }
564                     useCount = tempVector.size();
565                     break;
566                 }
567             }
568
569             // add all definitions to this local
570
for (int k = 0; k < defList.size(); k++) {
571                 String JavaDoc query = (String JavaDoc) (defList.elementAt(k));
572                 if (query.equalsIgnoreCase(local)) {
573                     Vector tempVector =
574                         (Vector) defDataList.elementAt(defList.indexOf(local));
575
576                     for (int i = 0; i < tempVector.size(); i++) {
577                         sootlocalNode.addChild(
578                             "definition",
579                             new String JavaDoc[] { "id", "line", "method" },
580                             new String JavaDoc[] {
581                                 i + "",
582                                 ((Long JavaDoc) tempVector.elementAt(i)).toString(),
583                                 cleanMethodName });
584                     }
585                     defineCount = tempVector.size();
586                     break;
587                 }
588             }
589
590             // add number of uses and defines to this local
591
sootlocalNode.addAttribute("uses", useCount + "");
592             sootlocalNode.addAttribute("defines", defineCount + "");
593
594             //create a list of locals sorted by type
595
Vector list = (Vector) typedLocals.elementAt(currentType);
596             list.addElement(localNode);
597             typedLocals.setElementAt(list, currentType);
598
599             // add local to locals node
600
localsNode.addChild((XMLNode) localNode.clone());
601             j++;
602
603         }
604
605         // add count to the locals node
606
localsNode.addAttribute("count", locals.size() + "");
607
608         // add types node to locals node, and each type with each local per type
609
XMLNode typesNode =
610             localsNode.addChild(
611                 "types",
612                 new String JavaDoc[] { "count" },
613                 new String JavaDoc[] { localTypes.size() + "" });
614
615         for (int i = 0; i < localTypes.size(); i++) {
616             String JavaDoc type = (String JavaDoc) localTypes.elementAt(i);
617             XMLNode typeNode =
618                 typesNode.addChild(
619                     "type",
620                     new String JavaDoc[] { "id", "type", "count" },
621                     new String JavaDoc[] {
622                         i + "",
623                         type,
624                         (Integer JavaDoc) typeCounts.elementAt(i) + "" });
625
626             Vector list = (Vector) typedLocals.elementAt(i);
627             for (j = 0; j < list.size(); j++) {
628                 typeNode.addChild((XMLNode) list.elementAt(j));
629             }
630         }
631
632         // add count attribute to labels node, and stmtcount, and stmtpercentage attributes to each label node
633
labelsNode.addAttribute("count", labelCount + "");
634         XMLNode current = labelsNode.child;
635         for (int i = 0; i < xmlLabelsList.size(); i++) {
636             XMLLabel tempLabel = (XMLLabel) xmlLabelsList.elementAt(i);
637             tempLabel.stmtPercentage =
638                 new Float JavaDoc(
639                     (new Float JavaDoc(tempLabel.stmtPercentage).floatValue()
640                         / new Float JavaDoc(maxStmtCount).floatValue())
641                         * 100.0)
642                     .longValue();
643
644             if (current != null) {
645                 current.addAttribute("stmtcount", tempLabel.stmtCount + "");
646                 current.addAttribute(
647                     "stmtpercentage",
648                     tempLabel.stmtPercentage + "");
649                 current = current.next;
650             }
651         }
652
653         // Print out exceptions
654
statementCount = 0;
655         XMLNode exceptionsNode = methodNode.addChild("exceptions");
656         Iterator trapIt = body.getTraps().iterator();
657         if (trapIt.hasNext()) {
658             while (trapIt.hasNext()) {
659                 Trap trap = (Trap) trapIt.next();
660
661                 // catch java.io.IOException from label0 to label1 with label2;
662
XMLNode catchNode =
663                     exceptionsNode.addChild(
664                         "exception",
665                         new String JavaDoc[] { "id", "method", "type" },
666                         new String JavaDoc[] {
667                             (statementCount++) + "",
668                             cleanMethodName,
669                             Scene.v().quotedNameOf(
670                                 trap.getException().getName())});
671                 catchNode.addChild(
672                     "begin",
673                     new String JavaDoc[] { "label" },
674                     new String JavaDoc[] {
675                          stmtToName.get(trap.getBeginUnit()).toString()});
676                 catchNode.addChild(
677                     "end",
678                     new String JavaDoc[] { "label" },
679                     new String JavaDoc[] {
680                          stmtToName.get(trap.getEndUnit()).toString()});
681                 catchNode.addChild(
682                     "handler",
683                     new String JavaDoc[] { "label" },
684                     new String JavaDoc[] {
685                          stmtToName.get(trap.getHandlerUnit()).toString()});
686             }
687         }
688
689         exceptionsNode.addAttribute(
690             "count",
691             exceptionsNode.getNumberOfChildren() + "");
692
693         //Scene.v().releaseActiveInvokeGraph();
694

695         return;
696     }
697
698     private String JavaDoc cleanMethod(String JavaDoc str) {
699         // method names can be filtered here, for example replacing < and > with _ to comply with XML name tokens
700
return str.trim().replace('<', '_').replace('>', '_');
701     }
702
703     private String JavaDoc cleanLocal(String JavaDoc str) {
704         // local names can be filtered here, for example replacing $ with _ to comply with XML name tokens
705
return str.trim(); //.replace( '$', '_' );
706
}
707
708     private String JavaDoc toCDATA(String JavaDoc str) {
709         // wrap a string in CDATA markup - str can contain anything and will pass XML validation
710
str = StringTools.replaceAll(str, "]]>", "]]&gt;");
711         return "<![CDATA[" + str + "]]>";
712     }
713
714     private String JavaDoc boolToString(boolean bool) {
715         if (bool)
716             return "true";
717         return "false";
718     }
719
720     class XMLLabel {
721         public long id;
722         public String JavaDoc methodName;
723         public String JavaDoc label;
724         public long stmtCount;
725         public long stmtPercentage;
726
727         public XMLLabel(long in_id, String JavaDoc in_methodName, String JavaDoc in_label) {
728             id = in_id;
729             methodName = in_methodName;
730             label = in_label;
731         }
732     }
733
734     private void printXMLTo(SootClass cl, PrintWriter out) {
735         root = new XMLRoot();
736         XMLNode xmlRootNode = null;
737         XMLNode xmlHistoryNode = null;
738         XMLNode xmlClassNode = null;
739         XMLNode xmlTempNode = null;
740
741         // Print XML class output
742
{
743             // add header nodes
744
xmlRootNode = root.addElement("jil");
745
746             // add history node
747
// TODO: grab the software version and command line
748
String JavaDoc cmdlineStr = "";
749             for (int i = 0; i < Main.v().cmdLineArgs.length; i++) {
750                 cmdlineStr += Main.v().cmdLineArgs[i] + " ";
751             }
752             String JavaDoc dateStr = new Date().toString();
753             xmlHistoryNode = xmlRootNode.addChild("history");
754             xmlHistoryNode.addAttribute("created", dateStr);
755             xmlHistoryNode.addChild(
756                 "soot",
757                 new String JavaDoc[] { "version", "command", "timestamp" },
758                 new String JavaDoc[] {
759                     Main.v().versionString,
760                     cmdlineStr.trim(),
761                     dateStr });
762
763             // add class root node
764
xmlClassNode =
765                 xmlRootNode.addChild(
766                     "class",
767                     new String JavaDoc[] { "name" },
768                     new String JavaDoc[] {
769                          Scene.v().quotedNameOf(cl.getName()).toString()});
770             if (cl.getPackageName().length() > 0)
771                 xmlClassNode.addAttribute("package", cl.getPackageName());
772             if (cl.hasSuperclass())
773                 xmlClassNode.addAttribute(
774                     "extends",
775                     Scene
776                         .v()
777                         .quotedNameOf(cl.getSuperclass().getName())
778                         .toString());
779
780             // add modifiers subnode
781
xmlTempNode = xmlClassNode.addChild("modifiers");
782             StringTokenizer st =
783                 new StringTokenizer(Modifier.toString(cl.getModifiers()));
784             while (st.hasMoreTokens())
785                 xmlTempNode.addChild(
786                     "modifier",
787                     new String JavaDoc[] { "name" },
788                     new String JavaDoc[] { st.nextToken() + "" });
789             xmlTempNode.addAttribute(
790                 "count",
791                 xmlTempNode.getNumberOfChildren() + "");
792         }
793
794         // Print interfaces
795
{
796             xmlTempNode =
797                 xmlClassNode.addChild(
798                     "interfaces",
799                     "",
800                     new String JavaDoc[] { "count" },
801                     new String JavaDoc[] { cl.getInterfaceCount() + "" });
802
803             Iterator interfaceIt = cl.getInterfaces().iterator();
804             if (interfaceIt.hasNext()) {
805                 while (interfaceIt.hasNext())
806                     xmlTempNode.addChild(
807                         "implements",
808                         "",
809                         new String JavaDoc[] { "class" },
810                         new String JavaDoc[] {
811                             Scene
812                                 .v()
813                                 .quotedNameOf(
814                                     ((SootClass) interfaceIt.next()).getName())
815                                 .toString()});
816             }
817         }
818
819         // Print fields
820
{
821             xmlTempNode =
822                 xmlClassNode.addChild(
823                     "fields",
824                     "",
825                     new String JavaDoc[] { "count" },
826                     new String JavaDoc[] { cl.getFieldCount() + "" });
827
828             Iterator fieldIt = cl.getFields().iterator();
829             if (fieldIt.hasNext()) {
830                 int i = 0;
831                 while (fieldIt.hasNext()) {
832                     SootField f = (SootField) fieldIt.next();
833
834                     if (f.isPhantom())
835                         continue;
836
837                     String JavaDoc type = f.getType().toString();
838                     String JavaDoc name = f.getName().toString();
839
840                     // add the field node
841
XMLNode xmlFieldNode =
842                         xmlTempNode.addChild(
843                             "field",
844                             "",
845                             new String JavaDoc[] { "id", "name", "type" },
846                             new String JavaDoc[] {(i++) + "", name, type });
847                     XMLNode xmlModifiersNode =
848                         xmlFieldNode.addChild("modifiers");
849
850                     StringTokenizer st =
851                         new StringTokenizer(
852                             Modifier.toString(f.getModifiers()));
853                     while (st.hasMoreTokens())
854                         xmlModifiersNode.addChild(
855                             "modifier",
856                             new String JavaDoc[] { "name" },
857                             new String JavaDoc[] { st.nextToken() + "" });
858
859                     xmlModifiersNode.addAttribute(
860                         "count",
861                         xmlModifiersNode.getNumberOfChildren() + "");
862                 }
863             }
864         }
865
866         // Print methods
867
{
868             Iterator methodIt = cl.methodIterator();
869
870             setXMLNode(
871                 xmlClassNode.addChild(
872                     "methods",
873                     new String JavaDoc[] { "count" },
874                     new String JavaDoc[] { cl.getMethodCount() + "" }));
875
876             while (methodIt.hasNext()) {
877                 SootMethod method = (SootMethod) methodIt.next();
878
879                 if (method.isPhantom())
880                     continue;
881
882                 if (!Modifier.isAbstract(method.getModifiers())
883                     && !Modifier.isNative(method.getModifiers())) {
884                     if (!method.hasActiveBody())
885                         throw new RuntimeException JavaDoc(
886                             "method "
887                                 + method.getName()
888                                 + " has no active body!");
889                     else
890                         printTo(method.getActiveBody(), out);
891                 }
892             }
893         }
894         out.println(toString());
895     }
896
897     public void printJimpleStyleTo(SootClass cl, PrintWriter out) {
898         // write cl class as XML
899
printXMLTo(cl, out);
900         return;
901     }
902
903     /**
904      * Prints out the method corresponding to b Body, (declaration and body),
905      * in the textual format corresponding to the IR used to encode b body.
906      *
907      * @param out a PrintWriter instance to print to.
908      */

909     private void printTo(Body b, PrintWriter out) {
910         b.validate();
911
912         printStatementsInBody(b, out);
913
914     }
915 }
916
Popular Tags