Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* Soot - a J*va Optimization Framework
   * Copyright (C) 2004 Jennifer Lhotak
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
 package soot.jimple.toolkits.annotation.qualifiers;
 
 import soot.*;
 
 import java.util.*;
 import soot.tagkit.*;
 import soot.jimple.*;
a scene transformer that add tags to indicate the tightest qualifies possible for fields and methods (ie: private, protected or public)
 
 public class TightestQualifiersTagger extends SceneTransformer {
     
     public TightestQualifiersTagger(Singletons.Global g) {}
 
     public final static int RESULT_PUBLIC = 0;
     public final static int RESULT_PACKAGE = 1;
     public final static int RESULT_PROTECTED = 2;
     public final static int RESULT_PRIVATE = 3;
     
     private final HashMap<SootMethodIntegermethodResultsMap = new HashMap<SootMethodInteger>();
     private final HashMap<SootFieldIntegerfieldResultsMap = new HashMap<SootFieldInteger>();
 
     protected void internalTransform(String phaseNameMap options){
     
         handleMethods();
         handleFields();
     }
 
     private void handleMethods() {
         Iterator classesIt = Scene.v().getApplicationClasses().iterator();
         while (classesIt.hasNext()){
             SootClass appClass = (SootClass)classesIt.next();
             Iterator methsIt = appClass.getMethods().iterator();
             while (methsIt.hasNext()){
                 SootMethod sm = (SootMethod)methsIt.next();
                 // for now if its unreachable do nothing
                 if (!Scene.v().getReachableMethods().contains(sm)) continue;
                 analyzeMethod(sm);
             }
         }
 
         Iterator<SootMethodmethStatIt = .keySet().iterator();
         while (methStatIt.hasNext()) {
             SootMethod meth = methStatIt.next();
             int result = .get(meth).intValue();
             String sRes = "Public";
             if (result == ){
                 sRes = "Public";
             }
             else if (result == ){
                 sRes = "Protected";
             }
             else if (result == ){
                 sRes = "Package";
             }
             else if (result == ){
                 sRes = "Private";
             }
             
             String actual = null;
             if (Modifier.isPublic(meth.getModifiers())){
                 actual = "Public";
             }
             else if (Modifier.isProtected(meth.getModifiers())){
                 actual = "Protected";
             }
             else if (Modifier.isPrivate(meth.getModifiers())){
                 actual = "Private";
             }
             else {    
                 actual = "Package";
             }
             
             //System.out.println("Method: "+meth.getName()+" has "+actual+" level access, can have: "+sRes+" level access.");
         
             if (!sRes.equals(actual)) {
                if (meth.getName().equals("<init>")){
                    meth.addTag(new StringTag("Constructor: "+meth.getDeclaringClass().getName()+" has "+actual+" level access, can have: "+sRes+" level access.""Tightest Qualifiers"));
                }
                else {
                    meth.addTag(new StringTag("Method: "+meth.getName()+" has "+actual+" level access, can have: "+sRes+" level access.""Tightest Qualifiers"));
                }
                meth.addTag(new ColorTag(255, 10, 0, true"Tightest Qualifiers"));
            }
        }
    }
    
    private void analyzeMethod(SootMethod sm){
       
        CallGraph cg = Scene.v().getCallGraph();
        //Iterator eIt = Scene.v().getEntryPoints().iterator();
        //while (eIt.hasNext()){
        //    System.out.println(eIt.next());
        //}
        
        if == null ) {
             = new MethodToContexts( Scene.v().getReachableMethods().listener() );
        }
        
        forIterator momcIt = .get(sm).iterator(); momcIt.hasNext(); ) {
            final MethodOrMethodContext momc = (MethodOrMethodContextmomcIt.next();
            Iterator callerEdges = cg.edgesInto(momc);
            while (callerEdges.hasNext()){
                Edge callEdge = (Edge)callerEdges.next();
                if (!callEdge.isExplicit()) continue;
                SootMethod methodCaller = callEdge.src();
                //System.out.println("Caller edge type: "+Edge.kindToString(callEdge.kind()));
                SootClass callingClass = methodCaller.getDeclaringClass();
                // public methods
                if (Modifier.isPublic(sm.getModifiers())){
                    analyzePublicMethod(smcallingClass); 
                }
                // protected methods
                else if (Modifier.isProtected(sm.getModifiers())){
                    analyzeProtectedMethod(smcallingClass); 
                }
                // private methods - do nothing
                else if (Modifier.isPrivate(sm.getModifiers())){
                }
                // package level methods
                else {
                    analyzePackageMethod(smcallingClass);
                }
                
            }
        }
        
    }
    private boolean analyzeProtectedMethod(SootMethod smSootClass callingClass){
        SootClass methodClass = sm.getDeclaringClass();
        
        //System.out.println("protected method: "+sm.getName()+" in class: "+methodClass.getName()+" calling class: "+callingClass.getName());
        boolean insidePackageAccess = isCallSamePackage(callingClassmethodClass);
        boolean subClassAccess = isCallClassSubClass(callingClassmethodClass);
        boolean sameClassAccess = isCallClassMethodClass(callingClassmethodClass);
        
        if (!insidePackageAccess && subClassAccess) {
            .put(smnew Integer());
            return true;
        }
        else if (insidePackageAccess && !sameClassAccess) {
            updateToPackage(sm);
            return false;
        }
        else {
            updateToPrivate(sm);
            return false;
        }    
    }
        
    private boolean analyzePackageMethod(SootMethod smSootClass callingClass){
        SootClass methodClass = sm.getDeclaringClass();
        //System.out.println("package method: "+sm.getName()+" in class: "+methodClass.getName()+" calling class: "+callingClass.getName());
        boolean insidePackageAccess = isCallSamePackage(callingClassmethodClass);
        boolean subClassAccess = isCallClassSubClass(callingClassmethodClass);
        boolean sameClassAccess = isCallClassMethodClass(callingClassmethodClass);
        
        if (insidePackageAccess && !sameClassAccess) {
            updateToPackage(sm);
            return true;
        }
        else {
            updateToPrivate(sm);
            return false;
        }
    }
    
    private boolean analyzePublicMethod(SootMethod smSootClass callingClass){
        
        SootClass methodClass = sm.getDeclaringClass();
        
        //System.out.println("public method: "+sm.getName()+" in class: "+methodClass.getName()+" calling class: "+callingClass.getName());
           
        boolean insidePackageAccess = isCallSamePackage(callingClassmethodClass);
        boolean subClassAccess = isCallClassSubClass(callingClassmethodClass);
        boolean sameClassAccess = isCallClassMethodClass(callingClassmethodClass);
                
        if (!insidePackageAccess && !subClassAccess){
            .put(smnew Integer());
            return true;
        }
        else if (!insidePackageAccess && subClassAccess) {
            updateToProtected(sm);
            return false;
        }
        else if (insidePackageAccess && !sameClassAccess) {
            updateToPackage(sm);
            return false;
        }
        else {
            updateToPrivate(sm);
            return false;
        }
                
    }
    private void updateToProtected(SootMethod sm){
        if (!.containsKey(sm)){
            .put(smnew Integer());
        }
        else {
            if (.get(sm).intValue() != ){
                .put(smnew Integer());
            }
        }
    }
    
    private void updateToPackage(SootMethod sm){
        if (!.containsKey(sm)){
            .put(smnew Integer());
        }
        else {
            if (.get(sm).intValue() == ){
                .put(smnew Integer());
            }
        }
    }
    
    private void updateToPrivate(SootMethod sm){
        if (!.containsKey(sm)) {
            .put(smnew Integer());
        }
    }
    
    private boolean isCallClassMethodClass(SootClass callSootClass check){
        if (call.equals(check)) return true;
        return false;
    }
    private boolean isCallClassSubClass(SootClass callSootClass check){
        if (!call.hasSuperclass()) return false;
        if (call.getSuperclass().equals(check)) return true;
        return false;
    }
    private boolean isCallSamePackage(SootClass callSootClass check){
        if (call.getPackageName().equals(check.getPackageName())) return true;
        return false;
    }
    private void handleFields(){
        Iterator classesIt = Scene.v().getApplicationClasses().iterator();
        while (classesIt.hasNext()){
            SootClass appClass = (SootClass)classesIt.next();
            Iterator fieldsIt = appClass.getFields().iterator();
            while (fieldsIt.hasNext()){
                SootField sf = (SootField)fieldsIt.next();
                analyzeField(sf);
            }
        }
        
        Iterator<SootFieldfieldStatIt = .keySet().iterator();
        while (fieldStatIt.hasNext()) {
            SootField f = fieldStatIt.next();
            int result = .get(f).intValue();
            String sRes = "Public";
            if (result == ){
                sRes = "Public";
            }
            else if (result == ){
                sRes = "Protected";
            }
            else if (result == ){
                sRes = "Package";
            }
            else if (result == ){
                sRes = "Private";
            }
            
            String actual = null;
            if (Modifier.isPublic(f.getModifiers())){
                //System.out.println("Field: "+f.getName()+" is public");
                actual = "Public";
            }
            else if (Modifier.isProtected(f.getModifiers())){
                actual = "Protected";
            }
            else if (Modifier.isPrivate(f.getModifiers())){
                actual = "Private";
            }
            else {    
                actual = "Package";
            }
            
            //System.out.println("Field: "+f.getName()+" has "+actual+" level access, can have: "+sRes+" level access.");
        
            if (!sRes.equals(actual)){
                f.addTag(new StringTag("Field: "+f.getName()+" has "+actual+" level access, can have: "+sRes+" level access.""Tightest Qualifiers"));
                f.addTag(new ColorTag(255, 10, 0, true"Tightest Qualifiers"));
            }
        }
    }
    
    private void analyzeField(SootField sf){
       
        // from all bodies get all use boxes and eliminate used fields
        Iterator classesIt = Scene.v().getApplicationClasses().iterator();
        while (classesIt.hasNext()) {
            SootClass appClass = (SootClass)classesIt.next();
            Iterator mIt = appClass.getMethods().iterator();
            while (mIt.hasNext()) {
                SootMethod sm = (SootMethod)mIt.next();
                if (!sm.hasActiveBody()) continue;
                if (!Scene.v().getReachableMethods().contains(sm)) continue;
                Body b = sm.getActiveBody();
                Iterator usesIt = b.getUseBoxes().iterator();
                while (usesIt.hasNext()) {
                    ValueBox vBox = (ValueBox)usesIt.next();
                    Value v = vBox.getValue();
                    if (v instanceof FieldRef) {
                        FieldRef fieldRef = (FieldRef)v;
                        SootField f = fieldRef.getField();
                        if (f.equals(sf)) {
                            if (Modifier.isPublic(sf.getModifiers())) {
                                if (analyzePublicField(sfappClass)) return;
                            }
                            else if (Modifier.isProtected(sf.getModifiers())) {
                                analyzeProtectedField(sfappClass);
                            }
                            else if(Modifier.isPrivate(sf.getModifiers())) {
                            }
                            else {
                                analyzePackageField(sfappClass);
                            }
                        }
                    }
                }
            }
        }
    }
    private boolean analyzePublicField(SootField sfSootClass callingClass){
        SootClass fieldClass = sf.getDeclaringClass();
        
           
        boolean insidePackageAccess = isCallSamePackage(callingClassfieldClass);
        boolean subClassAccess = isCallClassSubClass(callingClassfieldClass);
        boolean sameClassAccess = isCallClassMethodClass(callingClassfieldClass);
                
        if (!insidePackageAccess && !subClassAccess){
            .put(sfnew Integer());
            return true;
        }
        else if (!insidePackageAccess && subClassAccess) {
            updateToProtected(sf);
            return false;
        }
        else if (insidePackageAccess && !sameClassAccess) {
            updateToPackage(sf);
            return false;
        }
        else {
            updateToPrivate(sf);
            return false;
        }
        
    }
    private boolean analyzeProtectedField(SootField sfSootClass callingClass){
        SootClass fieldClass = sf.getDeclaringClass();
        boolean insidePackageAccess = isCallSamePackage(callingClassfieldClass);
        boolean subClassAccess = isCallClassSubClass(callingClassfieldClass);
        boolean sameClassAccess = isCallClassMethodClass(callingClassfieldClass);
        
        if (!insidePackageAccess && subClassAccess) {
            .put(sfnew Integer());
            return true;
        }
        else if (insidePackageAccess && !sameClassAccess) {
            updateToPackage(sf);
            return false;
        }
        else {
            updateToPrivate(sf);
            return false;
        }    
    }
    private boolean analyzePackageField(SootField sfSootClass callingClass){
        SootClass fieldClass = sf.getDeclaringClass();
        boolean insidePackageAccess = isCallSamePackage(callingClassfieldClass);
        boolean subClassAccess = isCallClassSubClass(callingClassfieldClass);
        boolean sameClassAccess = isCallClassMethodClass(callingClassfieldClass);
        
        if (insidePackageAccess && !sameClassAccess) {
            updateToPackage(sf);
            return true;
        }
        else {
            updateToPrivate(sf);
            return false;
        }
    }
    
    private void updateToProtected(SootField sf){
        if (!.containsKey(sf)){
            .put(sfnew Integer());
        }
        else {
            if (.get(sf).intValue() != ){
                .put(sfnew Integer());
            }
        }
    }
    
    private void updateToPackage(SootField sf){
        if (!.containsKey(sf)){
            .put(sfnew Integer());
        }
        else {
            if (.get(sf).intValue() == ){
                .put(sfnew Integer());
            }
        }
    }
    
    private void updateToPrivate(SootField sf){
        if (!.containsKey(sf)) {
            .put(sfnew Integer());
        }
    }
New to GrepCode? Check out our FAQ X