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 }