KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > soot > jimple > toolkits > annotation > qualifiers > TightestQualifiersTagger


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 package soot.jimple.toolkits.annotation.qualifiers;
21
22 import soot.*;
23 import java.util.*;
24 import soot.toolkits.graph.*;
25 import soot.toolkits.scalar.*;
26 import soot.tagkit.*;
27 import soot.jimple.*;
28 import soot.util.queue.*;
29 import soot.jimple.toolkits.callgraph.*;
30
31 /** a scene transformer that add tags to indicate the tightest qualifies
32  * possible for fields and methods (ie: private, protected or public)
33  */

34 public class TightestQualifiersTagger extends SceneTransformer {
35     
36     public TightestQualifiersTagger(Singletons.Global g) {}
37     public static TightestQualifiersTagger v() { return G.v().soot_jimple_toolkits_annotation_qualifiers_TightestQualifiersTagger();}
38
39     public final static int RESULT_PUBLIC = 0;
40     public final static int RESULT_PACKAGE = 1;
41     public final static int RESULT_PROTECTED = 2;
42     public final static int RESULT_PRIVATE = 3;
43     
44     private HashMap methodResultsMap = new HashMap();
45     private HashMap fieldResultsMap = new HashMap();
46     private MethodToContexts methodToContexts;
47
48     protected void internalTransform(String JavaDoc phaseName, Map options){
49     
50         handleMethods();
51         handleFields();
52     }
53
54     private void handleMethods() {
55         Iterator classesIt = Scene.v().getApplicationClasses().iterator();
56         while (classesIt.hasNext()){
57             SootClass appClass = (SootClass)classesIt.next();
58             Iterator methsIt = appClass.getMethods().iterator();
59             while (methsIt.hasNext()){
60                 SootMethod sm = (SootMethod)methsIt.next();
61                 // for now if its unreachable do nothing
62
if (!Scene.v().getReachableMethods().contains(sm)) continue;
63                 analyzeMethod(sm);
64             }
65         }
66
67         Iterator methStatIt = methodResultsMap.keySet().iterator();
68         while (methStatIt.hasNext()) {
69             SootMethod meth = (SootMethod)methStatIt.next();
70             int result = ((Integer JavaDoc)methodResultsMap.get(meth)).intValue();
71             String JavaDoc sRes = "Public";
72             if (result == RESULT_PUBLIC){
73                 sRes = "Public";
74             }
75             else if (result == RESULT_PROTECTED){
76                 sRes = "Protected";
77             }
78             else if (result == RESULT_PACKAGE){
79                 sRes = "Package";
80             }
81             else if (result == RESULT_PRIVATE){
82                 sRes = "Private";
83             }
84             
85             String JavaDoc actual = null;
86             if (Modifier.isPublic(meth.getModifiers())){
87                 actual = "Public";
88             }
89             else if (Modifier.isProtected(meth.getModifiers())){
90                 actual = "Protected";
91             }
92             else if (Modifier.isPrivate(meth.getModifiers())){
93                 actual = "Private";
94             }
95             else {
96                 actual = "Package";
97             }
98             
99             //System.out.println("Method: "+meth.getName()+" has "+actual+" level access, can have: "+sRes+" level access.");
100

101             if (!sRes.equals(actual)) {
102                 if (meth.getName().equals("<init>")){
103                     meth.addTag(new StringTag("Constructor: "+meth.getDeclaringClass().getName()+" has "+actual+" level access, can have: "+sRes+" level access.", "Tightest Qualifiers"));
104                 }
105                 else {
106                     meth.addTag(new StringTag("Method: "+meth.getName()+" has "+actual+" level access, can have: "+sRes+" level access.", "Tightest Qualifiers"));
107                 }
108                 meth.addTag(new ColorTag(255, 10, 0, true, "Tightest Qualifiers"));
109             }
110         }
111     }
112     
113
114     private void analyzeMethod(SootMethod sm){
115        
116         CallGraph cg = Scene.v().getCallGraph();
117
118         //Iterator eIt = Scene.v().getEntryPoints().iterator();
119
//while (eIt.hasNext()){
120
// System.out.println(eIt.next());
121
//}
122

123         if( methodToContexts == null ) {
124             methodToContexts = new MethodToContexts( Scene.v().getReachableMethods().listener() );
125         }
126         
127         for( Iterator momcIt = methodToContexts.get(sm).iterator(); momcIt.hasNext(); ) {
128             final MethodOrMethodContext momc = (MethodOrMethodContext) momcIt.next();
129             Iterator callerEdges = cg.edgesInto(momc);
130             while (callerEdges.hasNext()){
131                 Edge callEdge = (Edge)callerEdges.next();
132                 if (!callEdge.isExplicit()) continue;
133                 SootMethod methodCaller = callEdge.src();
134                 //System.out.println("Caller edge type: "+Edge.kindToString(callEdge.kind()));
135
SootClass callingClass = methodCaller.getDeclaringClass();
136                 // public methods
137
if (Modifier.isPublic(sm.getModifiers())){
138                     analyzePublicMethod(sm, callingClass);
139                 }
140                 // protected methods
141
else if (Modifier.isProtected(sm.getModifiers())){
142                     analyzeProtectedMethod(sm, callingClass);
143                 }
144                 // private methods - do nothing
145
else if (Modifier.isPrivate(sm.getModifiers())){
146                 }
147                 // package level methods
148
else {
149                     analyzePackageMethod(sm, callingClass);
150                 }
151                 
152             }
153         }
154         
155     }
156
157     private boolean analyzeProtectedMethod(SootMethod sm, SootClass callingClass){
158         SootClass methodClass = sm.getDeclaringClass();
159         
160         //System.out.println("protected method: "+sm.getName()+" in class: "+methodClass.getName()+" calling class: "+callingClass.getName());
161

162         boolean insidePackageAccess = isCallSamePackage(callingClass, methodClass);
163         boolean subClassAccess = isCallClassSubClass(callingClass, methodClass);
164         boolean sameClassAccess = isCallClassMethodClass(callingClass, methodClass);
165         
166         if (!insidePackageAccess && subClassAccess) {
167             methodResultsMap.put(sm, new Integer JavaDoc(RESULT_PROTECTED));
168             return true;
169         }
170         else if (insidePackageAccess && !sameClassAccess) {
171             updateToPackage(sm);
172             return false;
173         }
174         else {
175             updateToPrivate(sm);
176             return false;
177         }
178     }
179         
180     private boolean analyzePackageMethod(SootMethod sm, SootClass callingClass){
181         SootClass methodClass = sm.getDeclaringClass();
182
183         //System.out.println("package method: "+sm.getName()+" in class: "+methodClass.getName()+" calling class: "+callingClass.getName());
184
boolean insidePackageAccess = isCallSamePackage(callingClass, methodClass);
185         boolean subClassAccess = isCallClassSubClass(callingClass, methodClass);
186         boolean sameClassAccess = isCallClassMethodClass(callingClass, methodClass);
187         
188         if (insidePackageAccess && !sameClassAccess) {
189             updateToPackage(sm);
190             return true;
191         }
192         else {
193             updateToPrivate(sm);
194             return false;
195         }
196     }
197     
198     private boolean analyzePublicMethod(SootMethod sm, SootClass callingClass){
199         
200         SootClass methodClass = sm.getDeclaringClass();
201         
202         //System.out.println("public method: "+sm.getName()+" in class: "+methodClass.getName()+" calling class: "+callingClass.getName());
203

204         boolean insidePackageAccess = isCallSamePackage(callingClass, methodClass);
205         boolean subClassAccess = isCallClassSubClass(callingClass, methodClass);
206         boolean sameClassAccess = isCallClassMethodClass(callingClass, methodClass);
207                 
208         if (!insidePackageAccess && !subClassAccess){
209             methodResultsMap.put(sm, new Integer JavaDoc(RESULT_PUBLIC));
210             return true;
211         }
212         else if (!insidePackageAccess && subClassAccess) {
213             updateToProtected(sm);
214             return false;
215         }
216         else if (insidePackageAccess && !sameClassAccess) {
217             updateToPackage(sm);
218             return false;
219         }
220         else {
221             updateToPrivate(sm);
222             return false;
223         }
224                 
225     }
226
227     private void updateToProtected(SootMethod sm){
228         if (!methodResultsMap.containsKey(sm)){
229             methodResultsMap.put(sm, new Integer JavaDoc(RESULT_PROTECTED));
230         }
231         else {
232             if (((Integer JavaDoc)methodResultsMap.get(sm)).intValue() != RESULT_PUBLIC){
233                 methodResultsMap.put(sm, new Integer JavaDoc(RESULT_PROTECTED));
234             }
235         }
236     }
237     
238     private void updateToPackage(SootMethod sm){
239         if (!methodResultsMap.containsKey(sm)){
240             methodResultsMap.put(sm, new Integer JavaDoc(RESULT_PACKAGE));
241         }
242         else {
243             if (((Integer JavaDoc)methodResultsMap.get(sm)).intValue() == RESULT_PRIVATE){
244                 methodResultsMap.put(sm, new Integer JavaDoc(RESULT_PACKAGE));
245             }
246         }
247     }
248     
249     private void updateToPrivate(SootMethod sm){
250         if (!methodResultsMap.containsKey(sm)) {
251             methodResultsMap.put(sm, new Integer JavaDoc(RESULT_PRIVATE));
252         }
253     }
254     
255     private boolean isCallClassMethodClass(SootClass call, SootClass check){
256         if (call.equals(check)) return true;
257         return false;
258     }
259
260     private boolean isCallClassSubClass(SootClass call, SootClass check){
261         if (!call.hasSuperclass()) return false;
262         if (call.getSuperclass().equals(check)) return true;
263         return false;
264     }
265
266     private boolean isCallSamePackage(SootClass call, SootClass check){
267         if (call.getPackageName().equals(check.getPackageName())) return true;
268         return false;
269     }
270
271     private void handleFields(){
272         Iterator classesIt = Scene.v().getApplicationClasses().iterator();
273         while (classesIt.hasNext()){
274             SootClass appClass = (SootClass)classesIt.next();
275             Iterator fieldsIt = appClass.getFields().iterator();
276             while (fieldsIt.hasNext()){
277                 SootField sf = (SootField)fieldsIt.next();
278                 analyzeField(sf);
279             }
280         }
281         
282         Iterator fieldStatIt = fieldResultsMap.keySet().iterator();
283         while (fieldStatIt.hasNext()) {
284             SootField f = (SootField)fieldStatIt.next();
285             int result = ((Integer JavaDoc)fieldResultsMap.get(f)).intValue();
286             String JavaDoc sRes = "Public";
287             if (result == RESULT_PUBLIC){
288                 sRes = "Public";
289             }
290             else if (result == RESULT_PROTECTED){
291                 sRes = "Protected";
292             }
293             else if (result == RESULT_PACKAGE){
294                 sRes = "Package";
295             }
296             else if (result == RESULT_PRIVATE){
297                 sRes = "Private";
298             }
299             
300             String JavaDoc actual = null;
301             if (Modifier.isPublic(f.getModifiers())){
302                 //System.out.println("Field: "+f.getName()+" is public");
303
actual = "Public";
304             }
305             else if (Modifier.isProtected(f.getModifiers())){
306                 actual = "Protected";
307             }
308             else if (Modifier.isPrivate(f.getModifiers())){
309                 actual = "Private";
310             }
311             else {
312                 actual = "Package";
313             }
314             
315             //System.out.println("Field: "+f.getName()+" has "+actual+" level access, can have: "+sRes+" level access.");
316

317             if (!sRes.equals(actual)){
318                 f.addTag(new StringTag("Field: "+f.getName()+" has "+actual+" level access, can have: "+sRes+" level access.", "Tightest Qualifiers"));
319                 f.addTag(new ColorTag(255, 10, 0, true, "Tightest Qualifiers"));
320             }
321         }
322     }
323     
324     private void analyzeField(SootField sf){
325        
326         // from all bodies get all use boxes and eliminate used fields
327
Iterator classesIt = Scene.v().getApplicationClasses().iterator();
328         while (classesIt.hasNext()) {
329             SootClass appClass = (SootClass)classesIt.next();
330             Iterator mIt = appClass.getMethods().iterator();
331             while (mIt.hasNext()) {
332                 SootMethod sm = (SootMethod)mIt.next();
333                 if (!sm.hasActiveBody()) continue;
334                 if (!Scene.v().getReachableMethods().contains(sm)) continue;
335                 Body b = sm.getActiveBody();
336
337                 Iterator usesIt = b.getUseBoxes().iterator();
338                 while (usesIt.hasNext()) {
339                     ValueBox vBox = (ValueBox)usesIt.next();
340                     Value v = vBox.getValue();
341                     if (v instanceof FieldRef) {
342                         FieldRef fieldRef = (FieldRef)v;
343                         SootField f = fieldRef.getField();
344                         if (f.equals(sf)) {
345                             if (Modifier.isPublic(sf.getModifiers())) {
346                                 if (analyzePublicField(sf, appClass)) return;
347                             }
348                             else if (Modifier.isProtected(sf.getModifiers())) {
349                                 analyzeProtectedField(sf, appClass);
350                             }
351                             else if(Modifier.isPrivate(sf.getModifiers())) {
352                             }
353                             else {
354                                 analyzePackageField(sf, appClass);
355                             }
356                         }
357                     }
358                 }
359             }
360         }
361     }
362
363     private boolean analyzePublicField(SootField sf, SootClass callingClass){
364         SootClass fieldClass = sf.getDeclaringClass();
365         
366            
367         boolean insidePackageAccess = isCallSamePackage(callingClass, fieldClass);
368         boolean subClassAccess = isCallClassSubClass(callingClass, fieldClass);
369         boolean sameClassAccess = isCallClassMethodClass(callingClass, fieldClass);
370                 
371         if (!insidePackageAccess && !subClassAccess){
372             fieldResultsMap.put(sf, new Integer JavaDoc(RESULT_PUBLIC));
373             return true;
374         }
375         else if (!insidePackageAccess && subClassAccess) {
376             updateToProtected(sf);
377             return false;
378         }
379         else if (insidePackageAccess && !sameClassAccess) {
380             updateToPackage(sf);
381             return false;
382         }
383         else {
384             updateToPrivate(sf);
385             return false;
386         }
387         
388     }
389
390     private boolean analyzeProtectedField(SootField sf, SootClass callingClass){
391         SootClass fieldClass = sf.getDeclaringClass();
392
393         boolean insidePackageAccess = isCallSamePackage(callingClass, fieldClass);
394         boolean subClassAccess = isCallClassSubClass(callingClass, fieldClass);
395         boolean sameClassAccess = isCallClassMethodClass(callingClass, fieldClass);
396         
397         if (!insidePackageAccess && subClassAccess) {
398             fieldResultsMap.put(sf, new Integer JavaDoc(RESULT_PROTECTED));
399             return true;
400         }
401         else if (insidePackageAccess && !sameClassAccess) {
402             updateToPackage(sf);
403             return false;
404         }
405         else {
406             updateToPrivate(sf);
407             return false;
408         }
409     }
410
411     private boolean analyzePackageField(SootField sf, SootClass callingClass){
412         SootClass fieldClass = sf.getDeclaringClass();
413
414         boolean insidePackageAccess = isCallSamePackage(callingClass, fieldClass);
415         boolean subClassAccess = isCallClassSubClass(callingClass, fieldClass);
416         boolean sameClassAccess = isCallClassMethodClass(callingClass, fieldClass);
417         
418         if (insidePackageAccess && !sameClassAccess) {
419             updateToPackage(sf);
420             return true;
421         }
422         else {
423             updateToPrivate(sf);
424             return false;
425         }
426     }
427     
428     private void updateToProtected(SootField sf){
429         if (!fieldResultsMap.containsKey(sf)){
430             fieldResultsMap.put(sf, new Integer JavaDoc(RESULT_PROTECTED));
431         }
432         else {
433             if (((Integer JavaDoc)fieldResultsMap.get(sf)).intValue() != RESULT_PUBLIC){
434                 fieldResultsMap.put(sf, new Integer JavaDoc(RESULT_PROTECTED));
435             }
436         }
437     }
438     
439     private void updateToPackage(SootField sf){
440         if (!fieldResultsMap.containsKey(sf)){
441             fieldResultsMap.put(sf, new Integer JavaDoc(RESULT_PACKAGE));
442         }
443         else {
444             if (((Integer JavaDoc)fieldResultsMap.get(sf)).intValue() == RESULT_PRIVATE){
445                 fieldResultsMap.put(sf, new Integer JavaDoc(RESULT_PACKAGE));
446             }
447         }
448     }
449     
450     private void updateToPrivate(SootField sf){
451         if (!fieldResultsMap.containsKey(sf)) {
452             fieldResultsMap.put(sf, new Integer JavaDoc(RESULT_PRIVATE));
453         }
454     }
455 }
456
Popular Tags