1 4 package com.tc.aspectwerkz.reflect; 5 6 7 import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo; 8 import com.tc.aspectwerkz.transform.TransformationConstants; 9 10 import java.util.ArrayList ; 11 import java.util.HashMap ; 12 import java.util.HashSet ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 import java.util.Map ; 16 import java.util.Set ; 17 18 24 public class ClassInfoHelper { 25 private static final List EMPTY_ARRAY_LIST = new ArrayList (); 26 private static final String OBJECT_CLASS_NAME = "java.lang.Object"; 27 28 35 public static boolean instanceOf(final ClassInfo classInfo, final String superclassName) { 36 return implementsInterface(classInfo, superclassName) || extendsSuperClass(classInfo, superclassName); 37 } 38 39 47 public static boolean implementsInterface(final ClassInfo classInfo, final String interfaceName) { 48 if ((classInfo == null) || (interfaceName == null)) { 49 return false; 50 } else { 51 ClassInfo[] interfaces = classInfo.getInterfaces(); 53 for (int i = 0; i < interfaces.length; i++) { 54 ClassInfo anInterface = interfaces[i]; 55 if (interfaceName.equals(anInterface.getName())) { 56 return true; 57 } else if (ClassInfoHelper.implementsInterface(anInterface, interfaceName)) { 58 return true; 59 } 60 } 61 return ClassInfoHelper.implementsInterface(classInfo.getSuperclass(), interfaceName); 62 } 63 } 64 65 72 public static boolean extendsSuperClass(final ClassInfo classInfo, final String className) { 73 if ((classInfo == null) || (className == null)) { 74 return false; 75 } else if (className.equals(classInfo.getName())) { 79 return true; 80 } else { 81 return ClassInfoHelper.extendsSuperClass(classInfo.getSuperclass(), className); 82 } 83 } 84 85 92 public static List createMethodList(final ClassInfo klass) { 93 if (klass == null) { 94 return EMPTY_ARRAY_LIST; 95 } 96 97 List methods = new ArrayList (); 99 MethodInfo[] methodInfos = klass.getMethods(); 100 for (int i = 0; i < methodInfos.length; i++) { 101 MethodInfo methodInfo = methodInfos[i]; 102 if (isUserDefinedMethod(methodInfo)) { 103 methods.add(methodInfo); 104 } 105 } 106 107 ClassInfo superClass = klass.getSuperclass(); 109 if (superClass != null && !superClass.getName().equals(OBJECT_CLASS_NAME)) { 110 List parentMethods = createMethodList(superClass); 111 for (Iterator iterator = parentMethods.iterator(); iterator.hasNext();) { 113 MethodInfo parentMethod = (MethodInfo) iterator.next(); 114 if (!methods.contains(parentMethod)) { methods.add(parentMethod); 116 } 117 } 118 } 119 return methods; 120 } 121 122 128 public static List collectMethodsFromInterface(final ClassInfo interfaceClassInfo) { 129 final List interfaceDeclaredMethods = new ArrayList (); 130 final List sortedMethodList = createMethodList(interfaceClassInfo); 131 for (Iterator it = sortedMethodList.iterator(); it.hasNext();) { 132 MethodInfo methodInfo = (MethodInfo) it.next(); 133 if (methodInfo.getDeclaringType().getName().equals(OBJECT_CLASS_NAME)) { 134 continue; 135 } 136 interfaceDeclaredMethods.add(methodInfo); 137 } 138 ClassInfo superClass = interfaceClassInfo.getSuperclass(); 140 if (superClass != null && !superClass.getName().equals(OBJECT_CLASS_NAME)) { 141 interfaceDeclaredMethods.addAll(collectMethodsFromInterfacesImplementedBy(superClass)); 142 } 143 return interfaceDeclaredMethods; 144 } 145 146 152 public static List collectMethodsFromInterfacesImplementedBy(final ClassInfo classInfo) { 153 final List interfaceDeclaredMethods = new ArrayList (); 154 ClassInfo[] interfaces = classInfo.getInterfaces(); 155 156 for (int i = 0; i < interfaces.length; i++) { 158 final List sortedMethodList = createMethodList(interfaces[i]); 159 for (Iterator it = sortedMethodList.iterator(); it.hasNext();) { 160 MethodInfo methodInfo = (MethodInfo) it.next(); 161 if (methodInfo.getDeclaringType().getName().equals(OBJECT_CLASS_NAME)) { 162 continue; 163 } 164 interfaceDeclaredMethods.add(methodInfo); 165 } 166 } 167 ClassInfo superClass = classInfo.getSuperclass(); 169 if (superClass != null && !superClass.getName().equals(OBJECT_CLASS_NAME)) { 170 interfaceDeclaredMethods.addAll(collectMethodsFromInterfacesImplementedBy(superClass)); 171 } 172 return interfaceDeclaredMethods; 173 } 174 175 183 public static List createInterfaceDefinedMethodList(final ClassInfo klass, 184 final List interfaceDeclaredMethods) { 185 if (klass == null) { 186 throw new IllegalArgumentException ("class to sort method on can not be null"); 187 } 188 List methodList = new ArrayList (); 190 for (Iterator iterator = createMethodList(klass).iterator(); iterator.hasNext();) { 191 MethodInfo methodInfo = (MethodInfo) iterator.next(); 192 if (isDeclaredByInterface(methodInfo, interfaceDeclaredMethods)) { 193 methodList.add(methodInfo); 194 } 195 } 196 return methodList; 197 } 198 199 205 private static boolean isUserDefinedMethod(final MethodInfo method) { 206 if (!method.getName().startsWith(TransformationConstants.SYNTHETIC_MEMBER_PREFIX) 207 && !method.getName().startsWith(TransformationConstants.ORIGINAL_METHOD_PREFIX) 208 && !method.getName().startsWith(TransformationConstants.ASPECTWERKZ_PREFIX)) { 209 return true; 210 } else { 211 return false; 212 } 213 } 214 215 222 private static boolean isDeclaredByInterface(final MethodInfo method, final List interfaceDeclaredMethods) { 223 boolean match = false; 224 for (Iterator iterator = interfaceDeclaredMethods.iterator(); iterator.hasNext();) { 225 MethodInfo methodIt = (MethodInfo) iterator.next(); 226 if (method.getName().equals(methodIt.getName())) { 227 if (method.getParameterTypes().length == methodIt.getParameterTypes().length) { 229 boolean matchArgs = true; 230 for (int i = 0; i < method.getParameterTypes().length; i++) { 231 ClassInfo parameterType = method.getParameterTypes()[i]; 232 if (parameterType.getName().equals(methodIt.getParameterTypes()[i].getName())) { 233 ; 234 } else { 235 matchArgs = false; 236 break; 237 } 238 } 239 if (matchArgs) { 240 match = true; 241 break; 242 } 243 } 244 } 245 } 246 return match; 247 } 248 249 255 public static List collectInterfaces(final ClassInfo classInfo) { 256 final List interfaceList = new ArrayList (); 257 final Set interfaceNames = new HashSet (); 258 for (int i = 0; i < classInfo.getInterfaces().length; i++) { 259 ClassInfo interfaceInfo = classInfo.getInterfaces()[i]; 260 interfaceList.add(interfaceInfo); 261 interfaceNames.add(interfaceInfo.getName()); 262 } 263 for (ClassInfo superClass = classInfo.getSuperclass(); superClass != null; superClass = 264 superClass.getSuperclass()) { 265 for (int i = 0; i < superClass.getInterfaces().length; i++) { 266 ClassInfo interfaceInfo = superClass.getInterfaces()[i]; 267 if (!interfaceNames.contains(interfaceInfo.getName())) { 268 interfaceList.add(interfaceInfo); 269 interfaceNames.add(interfaceInfo.getName()); 270 } 271 } 272 } 273 return interfaceList; 274 } 275 276 283 public static boolean hasMethodClash(final Set interfacesToAdd, final ClassLoader loader) { 284 Map methodMap = new HashMap (); 286 for (Iterator it = interfacesToAdd.iterator(); it.hasNext();) { 287 ClassInfo classInfo = AsmClassInfo.getClassInfo((String ) it.next(), loader); 288 289 List methods = collectMethodsFromInterface(classInfo); 290 291 for (Iterator it2 = methods.iterator(); it2.hasNext();) { 292 MethodInfo methodInfo = (MethodInfo) it2.next(); 293 String key = methodInfo.getName() + ':' + methodInfo.getSignature(); 294 if (!methodMap.containsKey(key)) { 295 methodMap.put(key, new ArrayList ()); 296 } 297 ((List ) methodMap.get(key)).add(classInfo.getName()); 298 } 299 } 300 301 for (Iterator it = methodMap.entrySet().iterator(); it.hasNext();) { 303 Map.Entry entry = (Map.Entry ) it.next(); 304 String key = (String ) entry.getKey(); 305 List interfaceNames = (List ) entry.getValue(); 306 if (interfaceNames.size() > 1) { 307 StringBuffer msg = new StringBuffer (); 308 msg.append("can not add interfaces ["); 309 for (Iterator it2 = interfaceNames.iterator(); it2.hasNext();) { 310 String interfaceName = (String ) it2.next(); 311 msg.append(interfaceName); 312 if (it2.hasNext()) { 313 msg.append(','); 314 } 315 } 316 msg.append("] since they all have method ["); 317 msg.append(key); 318 msg.append(']'); 319 System.out.println("AW::WARNING - " + msg.toString()); 320 return true; 321 } 322 } 323 return false; 324 } 325 } | Popular Tags |