View Javadoc

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 }