1
2
3
4
5
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
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 }