1 /*************************************************************************************** 2 * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. * 3 * http://aspectwerkz.codehaus.org * 4 * ---------------------------------------------------------------------------------- * 5 * The software in this package is published under the terms of the LGPL license * 6 * a copy of which has been included with this distribution in the license.txt file. * 7 **************************************************************************************/ 8 package org.codehaus.aspectwerkz.reflect.impl.java; 9 10 import org.codehaus.aspectwerkz.annotation.Annotations; 11 import org.codehaus.aspectwerkz.reflect.ClassInfo; 12 import org.codehaus.aspectwerkz.reflect.MethodInfo; 13 import org.codehaus.aspectwerkz.reflect.ReflectHelper; 14 15 import java.lang.reflect.Method; 16 import java.util.List; 17 18 /*** 19 * Implementation of the MethodInfo interface for java.lang.reflect.*. 20 * 21 * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a> 22 */ 23 public class JavaMethodInfo extends JavaMemberInfo implements MethodInfo { 24 25 /*** 26 * The return type. 27 */ 28 private ClassInfo m_returnType = null; 29 30 /*** 31 * A list with the parameter types. 32 */ 33 private ClassInfo[] m_parameterTypes = null; 34 35 /*** 36 * A list with the exception types. 37 */ 38 private ClassInfo[] m_exceptionTypes = null; 39 40 /*** 41 * The signature of the method. 42 */ 43 private String m_signature; 44 45 /*** 46 * Creates a new method meta data instance. 47 * 48 * @param method 49 * @param declaringType 50 */ 51 JavaMethodInfo(final Method method, final JavaClassInfo declaringType) { 52 super(method, declaringType); 53 m_signature = ReflectHelper.getMethodSignature(method); 54 } 55 56 /*** 57 * Returns the method info for the method specified. 58 * 59 * @param method the method 60 * @return the method info 61 */ 62 public static MethodInfo getMethodInfo(final Method method) { 63 Class declaringClass = method.getDeclaringClass(); 64 JavaClassInfoRepository repository = JavaClassInfoRepository.getRepository(declaringClass.getClassLoader()); 65 ClassInfo classInfo = repository.getClassInfo(declaringClass.getName()); 66 if (classInfo == null) { 67 classInfo = JavaClassInfo.getClassInfo(declaringClass); 68 } 69 return classInfo.getMethod(ReflectHelper.calculateHash(method)); 70 } 71 72 /*** 73 * Returns the signature for the element. 74 * 75 * @return the signature for the element 76 */ 77 public String getSignature() { 78 return m_signature; 79 } 80 81 /*** 82 * Returns the annotations. 83 * 84 * @return the annotations 85 */ 86 public List getAnnotations() { 87 if (m_annotations == null) { 88 m_annotations = Annotations.getAnnotationInfos((Method) m_member); 89 } 90 return m_annotations; 91 } 92 93 /*** 94 * Returns the return type. 95 * 96 * @return the return type 97 */ 98 public ClassInfo getReturnType() { 99 if (m_returnType == null) { 100 Class returnTypeClass = ((Method) m_member).getReturnType(); 101 if (m_classInfoRepository.hasClassInfo(returnTypeClass.getName())) { 102 m_returnType = m_classInfoRepository.getClassInfo(returnTypeClass.getName()); 103 } else { 104 m_returnType = JavaClassInfo.getClassInfo(returnTypeClass); 105 m_classInfoRepository.addClassInfo(m_returnType); 106 } 107 } 108 return m_returnType; 109 } 110 111 /*** 112 * Returns the parameter types. 113 * 114 * @return the parameter types 115 */ 116 public ClassInfo[] getParameterTypes() { 117 if (m_parameterTypes == null) { 118 Class[] parameterTypes = ((Method) m_member).getParameterTypes(); 119 m_parameterTypes = new ClassInfo[parameterTypes.length]; 120 for (int i = 0; i < parameterTypes.length; i++) { 121 Class parameterType = parameterTypes[i]; 122 ClassInfo metaData; 123 if (m_classInfoRepository.hasClassInfo(parameterType.getName())) { 124 metaData = m_classInfoRepository.getClassInfo(parameterType.getName()); 125 } else { 126 metaData = JavaClassInfo.getClassInfo(parameterType); 127 m_classInfoRepository.addClassInfo(metaData); 128 } 129 m_parameterTypes[i] = metaData; 130 } 131 } 132 return m_parameterTypes; 133 } 134 135 /*** 136 * Returns the parameter names as they appear in the source code. 137 * <p/> 138 * This information is not available from Reflect. 139 * We may use ASM to grab it - is that needed ? 140 * 141 * @return null / not supported for now. 142 */ 143 public String[] getParameterNames() { 144 return null; 145 } 146 147 /*** 148 * Returns the exception types. 149 * 150 * @return the exception types 151 */ 152 public ClassInfo[] getExceptionTypes() { 153 if (m_exceptionTypes == null) { 154 Class[] exceptionTypes = ((Method) m_member).getExceptionTypes(); 155 m_exceptionTypes = new ClassInfo[exceptionTypes.length]; 156 for (int i = 0; i < exceptionTypes.length; i++) { 157 Class exceptionType = exceptionTypes[i]; 158 ClassInfo metaData; 159 if (m_classInfoRepository.hasClassInfo(exceptionType.getName())) { 160 metaData = m_classInfoRepository.getClassInfo(exceptionType.getName()); 161 } else { 162 metaData = JavaClassInfo.getClassInfo(exceptionType); 163 m_classInfoRepository.addClassInfo(metaData); 164 } 165 m_exceptionTypes[i] = metaData; 166 } 167 } 168 return m_exceptionTypes; 169 } 170 171 public boolean equals(Object o) { 172 if (this == o) { 173 return true; 174 } 175 if (!(o instanceof MethodInfo)) { 176 return false; 177 } 178 MethodInfo methodInfo = (MethodInfo) o; 179 if (!m_declaringType.getName().equals(methodInfo.getDeclaringType().getName())) { 180 return false; 181 } 182 if (!m_member.getName().equals(methodInfo.getName())) { 183 return false; 184 } 185 Class[] parameterTypes1 = ((Method) m_member).getParameterTypes(); 186 ClassInfo[] parameterTypes2 = methodInfo.getParameterTypes(); 187 if (parameterTypes1.length != parameterTypes2.length) { 188 return false; 189 } 190 for (int i = 0; i < parameterTypes1.length; i++) { 191 if (!parameterTypes1[i].getName().equals(parameterTypes2[i].getName())) { 192 return false; 193 } 194 } 195 return true; 196 } 197 198 public int hashCode() { 199 int result = 29; 200 result = (29 * result) + m_declaringType.getName().hashCode(); 201 result = (29 * result) + m_member.getName().hashCode(); 202 Class[] parameterTypes = ((Method) m_member).getParameterTypes(); 203 for (int i = 0; i < parameterTypes.length; i++) { 204 result = (29 * result) + parameterTypes[i].getName().hashCode(); 205 } 206 return result; 207 } 208 209 public String toString() { 210 return m_member.toString(); 211 } 212 }