1 8 package org.codehaus.aspectwerkz.reflect.impl.asm; 9 10 import org.codehaus.aspectwerkz.reflect.ClassInfo; 11 import org.codehaus.aspectwerkz.reflect.MethodInfo; 12 import org.codehaus.aspectwerkz.transform.inlining.AsmHelper; 13 import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotationHelper; 14 import org.codehaus.aspectwerkz.exception.DefinitionException; 15 import org.codehaus.aspectwerkz.proxy.ProxyCompiler; 16 import org.objectweb.asm.Type; 17 import org.objectweb.asm.ClassReader; 18 import org.objectweb.asm.attrs.Attributes; 19 20 import java.util.List ; 21 import java.util.ArrayList ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.lang.reflect.Modifier ; 25 26 31 public class AsmMethodInfo extends AsmMemberInfo implements MethodInfo { 32 33 36 private String m_returnTypeName = null; 37 38 42 protected String [] m_parameterNames = null; 43 44 47 private String [] m_parameterTypeNames = null; 48 49 52 private String [] m_exceptionTypeNames = null; 53 54 57 private ClassInfo m_returnType = null; 58 59 62 private ClassInfo[] m_parameterTypes = null; 63 64 67 private ClassInfo[] m_exceptionTypes = null; 68 69 76 AsmMethodInfo(final MethodStruct method, final String declaringType, final ClassLoader loader) { 77 super(method, declaringType, loader); 78 79 m_returnTypeName = Type.getReturnType(method.desc).getClassName(); 80 Type[] argTypes = Type.getArgumentTypes(method.desc); 81 m_parameterTypeNames = new String [argTypes.length]; 82 for (int i = 0; i < argTypes.length; i++) { 83 m_parameterTypeNames[i] = argTypes[i].getClassName(); 84 } 85 m_exceptionTypeNames = new String []{}; 87 } 88 89 98 public static MethodInfo getMethodInfo(final String methodName, 99 final String methodDesc, 100 final byte[] bytecode, 101 final ClassLoader loader) { 102 String className = AsmClassInfo.retrieveClassNameFromBytecode(bytecode); 103 AsmClassInfoRepository repository = AsmClassInfoRepository.getRepository(loader); 104 ClassInfo classInfo = repository.getClassInfo(className); 105 if (classInfo == null) { 106 classInfo = AsmClassInfo.getClassInfo(bytecode, loader); 107 } 108 return classInfo.getMethod(AsmHelper.calculateMethodHash(methodName, methodDesc)); 109 } 110 111 116 public String getSignature() { 117 return AsmHelper.getMethodDescriptor(this); 118 } 119 120 125 public ClassInfo getReturnType() { 126 if (m_returnType == null) { 127 m_returnType = AsmClassInfo.getClassInfo(m_returnTypeName, (ClassLoader ) m_loaderRef.get()); 128 } 129 return m_returnType; 130 } 131 132 137 public ClassInfo[] getParameterTypes() { 138 if (m_parameterTypes == null) { 139 m_parameterTypes = new ClassInfo[m_parameterTypeNames.length]; 140 for (int i = 0; i < m_parameterTypeNames.length; i++) { 141 m_parameterTypes[i] = AsmClassInfo.getClassInfo( 142 m_parameterTypeNames[i], 143 (ClassLoader ) m_loaderRef.get() 144 ); 145 } 146 } 147 return m_parameterTypes; 148 } 149 150 159 public String [] getParameterNames() { 160 return m_parameterNames; 161 } 162 163 168 public ClassInfo[] getExceptionTypes() { 169 if (m_exceptionTypes == null) { 170 m_exceptionTypes = new ClassInfo[m_exceptionTypeNames.length]; 171 for (int i = 0; i < m_exceptionTypeNames.length; i++) { 172 m_exceptionTypes[i] = AsmClassInfo.getClassInfo( 173 m_exceptionTypeNames[i], 174 (ClassLoader ) m_loaderRef.get() 175 ); 176 } 177 } 178 return m_exceptionTypes; 179 } 180 181 186 public List getAnnotations() { 187 if (m_annotations == null) { 188 try { 189 InputStream in = null; 190 ClassReader cr = null; 191 try { 192 if ((ClassLoader ) m_loaderRef.get() != null) { 193 in = ((ClassLoader ) m_loaderRef.get()).getResourceAsStream( 194 m_declaringTypeName.replace('.', '/') + ".class" 195 ); 196 } else { 197 in = ClassLoader.getSystemClassLoader().getResourceAsStream( 198 m_declaringTypeName.replace('.', '/') + ".class" 199 ); 200 } 201 if (in == null) { 202 in = ProxyCompiler.getProxyResourceAsStream((ClassLoader ) m_loaderRef.get(), m_declaringTypeName); 203 } 204 cr = new ClassReader(in); 205 } finally { 206 try { 207 in.close(); 208 } catch (Exception e) { 209 ; 210 } 211 } 212 List annotations = new ArrayList (); 213 cr.accept( 214 new AsmAnnotationHelper.MethodAnnotationExtractor( 215 annotations, m_member.name, m_member.desc, (ClassLoader ) m_loaderRef.get() 216 ), 217 Attributes.getDefaultAttributes(), 218 true 219 ); 220 m_annotations = annotations; 221 } catch (IOException e) { 222 System.err.println( 224 "WARN - could not load " + m_declaringTypeName + " as a resource to retrieve annotations" 225 ); 226 m_annotations = AsmClassInfo.EMPTY_LIST; 227 } 228 } 229 return m_annotations; 230 } 231 232 public boolean equals(Object o) { 233 if (this == o) { 234 return true; 235 } 236 if (!(o instanceof MethodInfo)) { 237 return false; 238 } 239 MethodInfo methodInfo = (MethodInfo) o; 240 if (!m_declaringTypeName.equals(methodInfo.getDeclaringType().getName())) { 241 return false; 242 } 243 if (!m_member.name.equals(methodInfo.getName())) { 244 return false; 245 } 246 ClassInfo[] parameterTypes = methodInfo.getParameterTypes(); 247 if (m_parameterTypeNames.length != parameterTypes.length) { return false; 249 } 250 for (int i = 0; i < m_parameterTypeNames.length; i++) { 251 if (!m_parameterTypeNames[i].equals(parameterTypes[i].getName())) { 252 return false; 253 } 254 } 255 return true; 256 } 257 258 public int hashCode() { 259 int result = 29; 260 result = (29 * result) + m_declaringTypeName.hashCode(); 261 result = (29 * result) + m_member.name.hashCode(); 262 for (int i = 0; i < m_parameterTypeNames.length; i++) { 263 result = (29 * result) + m_parameterTypeNames[i].hashCode(); 264 } 265 return result; 266 } 267 268 public String toString() { 269 StringBuffer sb = new StringBuffer (m_declaringTypeName); 270 sb.append('.').append(m_member.name); 271 sb.append(m_member.desc); 272 return sb.toString(); 273 } 274 275 282 public void pushParameterNameFromRegister(int registerIndex, String parameterName) { 283 int registerStart = 1; 284 if (Modifier.isStatic(m_member.modifiers)) { 285 registerStart = 0; 286 } 287 int registerIndexFrom0 = registerIndex - registerStart; 289 Type[] parameters = Type.getArgumentTypes(m_member.desc); 290 int typeIndex = AsmHelper.getTypeIndexOf(parameters, registerIndexFrom0); 291 if (typeIndex >= 0 && typeIndex < m_parameterNames.length) { 292 m_parameterNames[typeIndex] = parameterName; 293 } else { 294 throw new DefinitionException("Could not register parameter named " + parameterName 295 + " from register " + registerIndex + " for " + m_member.name + "." + m_member.desc); 296 } 297 } 298 } | Popular Tags |