View Javadoc

1   package org.kit.furia.fragment.soot;
2   
3   import java.io.File;
4   import java.io.FileNotFoundException;
5   import java.io.FileWriter;
6   import java.io.IOException;
7   import java.io.PrintStream;
8   import java.util.ArrayList;
9   import java.util.HashMap;
10  import java.util.Iterator;
11  import java.util.LinkedList;
12  import java.util.List;
13  import java.util.Map;
14  
15  import org.apache.log4j.Logger;
16  import org.kit.furia.exceptions.IRException;
17  import org.kit.furia.fragment.AbstractFragmentExtractor;
18  import org.kit.furia.fragment.FragmentExtractor;
19  import org.kit.furia.fragment.FragmentParseException;
20  import org.kit.furia.fragment.MTDFragmentAST;
21  import org.kit.furia.fragment.OBFragment;
22  import org.kit.furia.fragment.soot.representation.FrimpBody;
23  import org.kit.furia.misc.IntegerHolder;
24  
25  import soot.Body;
26  import soot.G;
27  import soot.PackManager;
28  import soot.Transform;
29  import soot.grimp.Grimp;
30  import soot.grimp.GrimpBody;
31  import soot.toolkits.graph.BlockGraph;
32  import soot.util.cfgcmd.CFGGraphType;
33  
34  /*
35   Furia-chan: An Open Source software license violation detector.    
36   Copyright (C) 2007 Kyushu Institute of Technology
37  
38   This program is free software: you can redistribute it and/or modify
39   it under the terms of the GNU General Public License as published by
40   the Free Software Foundation, either version 3 of the License, or
41   (at your option) any later version.
42  
43   This program is distributed in the hope that it will be useful,
44   but WITHOUT ANY WARRANTY; without even the implied warranty of
45   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
46   GNU General Public License for more details.
47  
48   You should have received a copy of the GNU General Public License
49   along with this program.  If not, see <http://www.gnu.org/licenses/>.
50   */
51  
52  /**
53   * FragmentExtractor takes a directory and loads SootFragmentBuilder objects for
54   * each method found. From the SootFragmentBuilder object, fragments can be
55   * extracted.
56   * @author Arnoldo Jose Muller Molina
57   * @since 0
58   */
59  
60  public class FragmentExtractorSoot extends AbstractFragmentExtractor implements FragmentExtractor {
61      private static final Logger logger = Logger
62              .getLogger(FragmentExtractorSoot.class);
63  
64      // this is the default graph type used in furia.
65      // TODO: We could try using some other (simpler) cfg without exceptions :)
66      public static final CFGGraphType defaultGraphType = CFGGraphType.EXCEPTIONAL_BLOCK_GRAPH;
67  
68      // public static final CFGGraphType defaultGraphType =
69      // CFGGraphType.BRIEF_BLOCK_GRAPH;
70      public FragmentExtractorSoot() {
71  
72      }
73  
74      public void extractMethodsFromDirectory(final String directory,
75              final int maxStructuresAllowed, final int minStructuresAllowed,
76              final String outputPath, String outputFile)
77              throws FileNotFoundException, NoClassesFound, IOException,
78              IRException, FragmentParseException {
79          extractMethodsFromDirectory(directory, defaultGraphType,
80                  maxStructuresAllowed, minStructuresAllowed, outputPath,
81                  outputFile);
82      }
83  
84      /**
85       * Extracts fragments from the given directory. Furia-chan's fragment file
86       * format is: <repetitions count>\t<fragment>
87       * @param directory
88       *                Directory from where we will extract fragments
89       * @param graphtype
90       *                The graph representation used to interpret the methods
91       * @param maxStructuresAllowed
92       *                maximum nodes per tree
93       * @param min_structures_allowed
94       *                minimum nodes per tree
95       * @param outputPath
96       *                Output path where logs will be written
97       * @param outputFile
98       *                The output fragment file that will be used
99       * @throws NoClassesFoundByStealer
100      * @throws FileNotFoundException
101      * @throws Exception
102      */
103     public void extractMethodsFromDirectory(final String directory,
104             final CFGGraphType graphtype, final int maxStructuresAllowed,
105             final int minStructuresAllowed, final String outputPath,
106             String outputFile) throws FileNotFoundException, NoClassesFound,
107             IOException, IRException, FragmentParseException {
108         final BodyStealer stealer = stealBodiesFromDir(directory, outputPath);
109 
110         if (!stealer.isFound()) {
111             throw new NoClassesFound("In directory:" + directory);
112         }
113         final Iterator < Body > it = stealer.getIterator();
114         FileWriter output = new FileWriter(outputFile);
115         // repetition counter
116         HashMap < String, IntegerHolder > repetitionCounts = new HashMap < String, IntegerHolder >();
117         while (it.hasNext()) {
118             final Body tempBody = it.next();
119             // logger.debug("Fragmenting method: " +
120             // tempBody.getMethod().toString());
121             FrimpBody fb = new FrimpBody(tempBody);
122             FragmentBuilder sootFragmentBuilder = new FragmentBuilder(fb,
123                     (BlockGraph) graphtype.buildGraph(fb),
124                     maxStructuresAllowed, minStructuresAllowed);
125             sootFragmentBuilder.fillRepetitionCounts(repetitionCounts);
126         }
127 
128         Iterator < Map.Entry < String, IntegerHolder >> itAll = repetitionCounts
129                 .entrySet().iterator();
130         while (itAll.hasNext()) {
131             Map.Entry < String, IntegerHolder > entry = itAll.next();
132 
133             MTDFragmentAST tree = OBFragment.parseTree(entry.getKey());
134             // process only if the tree has the expected size.
135             if (tree.getSize() >= minStructuresAllowed
136                     && tree.getSize() <= maxStructuresAllowed) {
137                 output.write(entry.getValue().getValue() + "\t"
138                         + entry.getKey() + "\n");
139             }
140         }
141         output.close();
142     }
143 
144     public BodyStealer stealBodiesFromDir(String dir, String outputPath)
145             throws FileNotFoundException, NoClassesFound {
146         List < String > argumentos = new LinkedList < String >();
147 
148         argumentos.add("-allow-phantom-refs");
149         // phantom refs
150         argumentos.add("-p"); // for supporting phantom refs
151         argumentos.add("jb.tr"); // for supporting phantom refs
152         argumentos.add("enabled:false"); // for supporting phantom refs
153         // phantom refs
154 
155         argumentos.add("--soot-class-path");
156         String cp = dir + File.pathSeparator + System.getProperty("java.home")
157                 + File.separator + "lib" + File.separator + "rt.jar";
158         logger.info("class path: " + cp);
159         argumentos.add(cp);
160         argumentos.add("-output-format");
161         argumentos.add("n");
162         argumentos.add("-output-dir");
163         argumentos.add(System.getProperty("user.home") + File.separator
164                 + "temp" + File.separator + "sootemptyness");
165         // argumentos.add("--soot-class-path");
166         // argumentos.add(dir);
167         // argumentos.add("-x");
168         // argumentos.add("java*");
169 
170         // argumentos.add("-process-dir");
171         // argumentos.add(dir);
172         int size = argumentos.size();
173         getClassFiles(new File(dir), argumentos, dir);
174         if (size == argumentos.size()) {
175             throw new NoClassesFound();
176         }
177 
178         // G.v().reset(); // reset soot
179         // G.reset(); // just in case.
180         G.v().out = new PrintStream(outputPath + File.separator + "sootLog.txt");
181         BodyStealer stealer = new BodyStealer();
182 
183         Transform stealerTransform = new Transform("jtp.stealerTransform",
184                 stealer);
185         stealerTransform.setDeclaredOptions("enabled");
186         stealerTransform.setDefaultOptions("enabled");
187         PackManager.v().getPack("jtp").add(stealerTransform);
188 
189         String[] sootArgs = new String[argumentos.size()];
190         argumentos.toArray(sootArgs);
191 
192         soot.Main.main(sootArgs);
193         logger.info("Extracted soot methods for: " + dir);
194         G.v().out.close();
195         return stealer;
196 
197     }
198 
199 }