View Javadoc

1   /*
2    * Created on 12.10.2004
3    *
4    * To change the template for this generated file go to
5    * Window>Preferences>Java>Code Generation>Code and Comments
6    */
7   package joeq.Compiler.Analysis.FlowInsensitive;
8   
9   import java.util.HashMap;
10  import java.util.Iterator;
11  import joeq.Class.jq_Class;
12  import joeq.Class.jq_Initializer;
13  import joeq.Class.jq_Method;
14  import joeq.Class.jq_Type;
15  import jwutil.util.Assert;
16  
17  public class BogusSummaryProvider {
18      HashMap classMap              = new HashMap();
19      HashMap methodMap             = new HashMap();
20      static boolean INLINE_MAPS = !System.getProperty("inline.maps", "no").equals("no");
21      
22      private static final boolean TRACE = !System.getProperty("pa.tracebogus", "no").equals("no");
23      private static jq_Class realString;
24      private static jq_Class realStringBuffer;
25      private static jq_Class realHashMap;
26      private static jq_Class realVector;
27      private static jq_Class realHashtable;
28      private static jq_Class realArrayList;
29      private static jq_Class realLinkedList;
30      private static jq_Class realCookie;
31      
32      private static jq_Class fakeString;
33      private static jq_Class fakeStringBuffer;
34      private static jq_Class fakeHashMap;
35      private static jq_Class fakeVector;
36      private static jq_Class fakeHashtable;
37      private static jq_Class fakeArrayList;
38      private static jq_Class fakeLinkedList;
39      private static jq_Class fakeCookie;
40      
41      public BogusSummaryProvider() {
42          realString       = getClassByName("java.lang.String");
43          realStringBuffer = getClassByName("java.lang.StringBuffer");
44          realHashMap      = getClassByName("java.util.HashMap");
45          realVector       = getClassByName("java.util.Vector");
46          realHashtable    = getClassByName("java.util.Hashtable");
47          realArrayList    = getClassByName("java.util.ArrayList");
48          realLinkedList   = getClassByName("java.util.LinkedList");
49          realCookie       = getClassByName("javax.servlet.http.Cookie");
50          Assert._assert(realString != null && realStringBuffer != null && realHashMap != null && realVector != null && realHashtable != null);
51          realString.prepare(); realStringBuffer.prepare(); realHashMap.prepare(); realVector.prepare(); realHashtable.prepare(); realArrayList.prepare(); realLinkedList.prepare();
52          
53          fakeString       = getClassByName("MyMockLib.MyString");
54          fakeStringBuffer = getClassByName("MyMockLib.MyStringBuffer");        
55          fakeHashMap      = getClassByName("MyMockLib.MyHashMap");
56          fakeVector       = getClassByName("MyMockLib.MyVector");
57          fakeHashtable    = getClassByName("MyMockLib.MyHashtable");
58          fakeArrayList    = getClassByName("MyMockLib.MyArrayList");
59          fakeLinkedList   = getClassByName("MyMockLib.MyLinkedList");
60          Assert._assert(fakeString != null && fakeStringBuffer != null && fakeHashMap != null && fakeVector != null && fakeHashtable != null);        
61          fakeString.prepare(); fakeStringBuffer.prepare(); fakeHashMap.prepare(); fakeVector.prepare(); fakeHashtable.prepare(); fakeArrayList.prepare(); fakeLinkedList.prepare();
62          if(fakeCookie != null) fakeCookie.prepare();
63          if(realCookie != null) realCookie.prepare();
64          
65          classMap.put(realString, fakeString);
66          classMap.put(realStringBuffer, fakeStringBuffer);
67          if(realCookie != null && fakeCookie != null) {
68              classMap.put(realCookie, fakeCookie);
69          }
70          if(INLINE_MAPS){
71              if(TRACE) {
72                  System.out.println("Inlining maps, etc.");
73              }
74              classMap.put(realHashMap, fakeHashMap);
75              classMap.put(realVector, fakeVector);
76              classMap.put(realHashtable, fakeHashtable);
77              classMap.put(realArrayList, fakeArrayList);
78          } else {
79              System.out.println("Not inlining maps, etc.");
80          }        
81      }
82      
83      public jq_Method getReplacementMethod(jq_Method m) {
84          return getReplacementMethod(m, null);
85      }
86      /***
87       * Caching method to return a replacement for @param m.
88       * @param type 
89       * 
90       * @return replacement for m.
91       * */
92      public jq_Method getReplacementMethod(jq_Method m, jq_Type type) {
93          jq_Method replacement = (jq_Method) methodMap.get(m);
94          
95          if(replacement == null) {
96                  jq_Class c = (jq_Class) classMap.get(m.getDeclaringClass());
97                  if(c == null && type != null) {
98                      c = (jq_Class) classMap.get(type);   
99                  }
100                 if(c != null) {
101                     replacement = findReplacementMethod(c, m);
102 
103                     if(replacement == null) {
104                         if(TRACE) System.err.println("No replacement for " + m + " found in " + c);
105                         return null;
106                     }
107                     methodMap.put(m, replacement);
108                     if(TRACE) System.out.println("Replaced " + m + " with " + replacement);
109                     return replacement;
110                 } else {
111                     return null;
112                 }
113         } else {
114             return replacement;
115         }
116     }
117     
118     private static jq_Method findReplacementMethod(jq_Class clazz, jq_Method originalMethod) {
119         for(Iterator iter = clazz.getMembers().iterator(); iter.hasNext();){
120             Object o = iter.next();
121             if(!(o instanceof jq_Method)) continue;
122             jq_Method m = (jq_Method) o;
123             
124             if(!m.getName().toString().equals(originalMethod.getName().toString())){
125                 continue;
126             }
127             
128             if(m.getParamTypes().length != originalMethod.getParamTypes().length){
129                 continue;            
130             }
131             
132             boolean allMatch = true;
133             int base = 0;
134             if(clazz != fakeString && clazz != fakeStringBuffer){
135                 base = 1;
136             }
137             if(originalMethod instanceof jq_Initializer){                
138                 base = 1;
139             }
140             for(int i = base; i < originalMethod.getParamTypes().length; i++){
141                 jq_Type type = m.getParamTypes()[i];
142                 jq_Type originalType = originalMethod.getParamTypes()[i];
143                 
144                 if(type != originalType){
145                     allMatch = false;
146                     break;
147                 }
148             }
149             if(!allMatch) {
150                 continue;
151             }
152          
153             // done with the tests: m is good
154             return m;
155         }
156         
157         return null;
158     }
159     
160     private static jq_Class getClassByName(String className, boolean strict) {
161         jq_Class theClass = (jq_Class)jq_Type.parseType(className);
162         if(strict) {
163             Assert._assert(theClass != null, className + " is not available.");
164         } else {
165             return null;
166         }
167         try {
168             theClass.prepare();
169         } catch (Exception e) {
170             if(strict) {
171                 e.printStackTrace();
172             }
173             return null;
174         }
175         
176         return theClass;
177     }
178     
179     private static jq_Class getClassByName(String className) {
180         return getClassByName(className, true);
181     }
182 
183     public boolean hasStaticReplacement(jq_Method replacement) {
184         jq_Class clazz = replacement.getDeclaringClass();
185         
186         return clazz == fakeString || clazz == fakeStringBuffer;
187     }
188 }