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.annotation;
9
10 import org.codehaus.aspectwerkz.reflect.MethodInfo;
11 import org.codehaus.aspectwerkz.reflect.ClassInfo;
12 import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
13 import org.codehaus.aspectwerkz.reflect.FieldInfo;
14 import org.codehaus.aspectwerkz.reflect.ReflectHelper;
15 import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;
16 import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotations;
17
18 import java.lang.reflect.Constructor;
19 import java.lang.reflect.Field;
20 import java.lang.reflect.Method;
21 import java.util.List;
22 import java.util.ArrayList;
23
24 /***
25 * Utility class for annotation retrieval.
26 * <br/>Note: Annotations are extracted out of ASMClassInfo
27 * <br/>Note: caution when changing that to use reflection, since it might lead to load target class during aspect
28 * system startup.
29 *
30 * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
31 */
32 public final class Annotations {
33
34 private final static List EMPTY_LIST = new ArrayList();
35
36 /***
37 * Return the annotation with a specific name for a specific class.
38 *
39 * @param annotationName the annotation name
40 * @param klass the java.lang.Class object to find the annotation on.
41 * @return the annotation or null
42 */
43 public static Annotation getAnnotation(final String annotationName, final Class klass) {
44 ClassInfo classInfo = AsmClassInfo.getClassInfo(klass.getName(), klass.getClassLoader());
45 return AsmAnnotations.getAnnotation(annotationName, classInfo);
46 }
47
48 /***
49 * Return the annotation with a specific name for a specific class.
50 *
51 * @param annotation the annotation class
52 * @param klass the java.lang.Class object to find the annotation on.
53 * @return the annotation or null
54 */
55 public static Annotation getAnnotation(final Class annotation, final Class klass) {
56 return getAnnotation(getAnnnotationName(annotation), klass);
57 }
58
59 /***
60 * Return the annotation with a specific name for a specific method.
61 *
62 * @param annotationName the annotation name
63 * @param method the java.lang.refect.Method object to find the annotation on.
64 * @return the annotation or null
65 */
66 public static Annotation getAnnotation(final String annotationName, final Method method) {
67 ClassLoader loader = method.getDeclaringClass().getClassLoader();
68 ClassInfo classInfo = AsmClassInfo.getClassInfo(method.getDeclaringClass().getName(), loader);
69 MethodInfo methodInfo = classInfo.getMethod(ReflectHelper.calculateHash(method));
70 return AsmAnnotations.getAnnotation(annotationName, methodInfo);
71 }
72
73 /***
74 * Return the annotation with a specific name for a specific method.
75 *
76 * @param annotation the annotation class
77 * @param method the java.lang.refect.Method object to find the annotation on.
78 * @return the annotation or null
79 */
80 public static Annotation getAnnotation(final Class annotation, final Method method) {
81 return getAnnotation(getAnnnotationName(annotation), method);
82 }
83
84 /***
85 * Return the annotation with a specific name for a specific constructor.
86 *
87 * @param annotationName the annotation name
88 * @param constructor the java.lang.refect.Constructor object to find the annotation on.
89 * @return the annotation or null
90 */
91 public static Annotation getAnnotation(final String annotationName, final Constructor constructor) {
92 ClassLoader loader = constructor.getDeclaringClass().getClassLoader();
93 ClassInfo classInfo = AsmClassInfo.getClassInfo(constructor.getDeclaringClass().getName(), loader);
94 ConstructorInfo constructorInfo = classInfo.getConstructor(ReflectHelper.calculateHash(constructor));
95 return AsmAnnotations.getAnnotation(annotationName, constructorInfo);
96 }
97
98 /***
99 * Return the annotation with a specific name for a specific constructor.
100 *
101 * @param annotation the annotation class
102 * @param constructor the java.lang.refect.Constructor object to find the annotation on.
103 * @return the annotation or null
104 */
105 public static Annotation getAnnotation(final Class annotation, final Constructor constructor) {
106 return getAnnotation(getAnnnotationName(annotation), constructor);
107 }
108
109 /***
110 * Return the annotation with a specific name for a specific field.
111 *
112 * @param annotationName the annotation name
113 * @param field the java.lang.reflect.Field object to find the annotation on.
114 * @return the annotation or null
115 */
116 public static Annotation getAnnotation(final String annotationName, final Field field) {
117 ClassLoader loader = field.getDeclaringClass().getClassLoader();
118 ClassInfo classInfo = AsmClassInfo.getClassInfo(field.getDeclaringClass().getName(), loader);
119 FieldInfo fieldInfo = classInfo.getField(ReflectHelper.calculateHash(field));
120 return AsmAnnotations.getAnnotation(annotationName, fieldInfo);
121 }
122
123 /***
124 * Return the annotation with a specific name for a specific field.
125 *
126 * @param annotation the annotation class
127 * @param field the java.lang.reflect.Field object to find the annotation on.
128 * @return the annotation or null
129 */
130 public static Annotation getAnnotation(final Class annotation, final Field field) {
131 return getAnnotation(getAnnnotationName(annotation), field);
132 }
133
134 /***
135 * Return a list with the annotations with a specific name for a specific class.
136 *
137 * @param annotationName the annotation name
138 * @param klass the java.lang.Class object to find the annotation on.
139 * @return the annotations in a list (can be empty)
140 */
141 public static List getAnnotations(final String annotationName, final Class klass) {
142 ClassInfo classInfo = AsmClassInfo.getClassInfo(klass.getName(), klass.getClassLoader());
143 return AsmAnnotations.getAnnotations(annotationName, classInfo);
144 }
145
146 /***
147 * Return a list with the annotations with a specific name for a specific class.
148 *
149 * @param annotation the annotation class
150 * @param klass the java.lang.Class object to find the annotation on.
151 * @return the annotations in a list (can be empty)
152 */
153 public static List getAnnotations(final Class annotation, final Class klass) {
154 return getAnnotations(getAnnnotationName(annotation), klass);
155 }
156
157 /***
158 * Return a list with the annotations with a specific name for a specific method.
159 *
160 * @param annotationName the annotation name
161 * @param method the java.lang.refect.Method object to find the annotation on.
162 * @return the annotations in a list (can be empty)
163 */
164 public static List getAnnotations(final String annotationName, final Method method) {
165 ClassLoader loader = method.getDeclaringClass().getClassLoader();
166 ClassInfo classInfo = AsmClassInfo.getClassInfo(method.getDeclaringClass().getName(), loader);
167 MethodInfo methodInfo = classInfo.getMethod(ReflectHelper.calculateHash(method));
168 return AsmAnnotations.getAnnotations(annotationName, methodInfo);
169 }
170
171 /***
172 * Return a list with the annotations with a specific name for a specific method.
173 *
174 * @param annotation the annotation class
175 * @param method the java.lang.refect.Method object to find the annotation on.
176 * @return the annotations in a list (can be empty)
177 */
178 public static List getAnnotations(final Class annotation, final Method method) {
179 return getAnnotations(getAnnnotationName(annotation), method);
180 }
181
182 /***
183 * Return a list with the annotations with a specific name for a specific constructor.
184 *
185 * @param annotationName the annotation name
186 * @param constructor the java.lang.refect.Constructor object to find the annotation on.
187 * @return the annotations in a list (can be empty)
188 */
189 public static List getAnnotations(final String annotationName, final Constructor constructor) {
190 ClassLoader loader = constructor.getDeclaringClass().getClassLoader();
191 ClassInfo classInfo = AsmClassInfo.getClassInfo(constructor.getDeclaringClass().getName(), loader);
192 ConstructorInfo constructorInfo = classInfo.getConstructor(ReflectHelper.calculateHash(constructor));
193 return AsmAnnotations.getAnnotations(annotationName, constructorInfo);
194 }
195
196 /***
197 * Return a list with the annotations with a specific name for a specific constructor.
198 *
199 * @param annotation the annotation class
200 * @param constructor the java.lang.refect.Constructor object to find the annotation on.
201 * @return the annotations in a list (can be empty)
202 */
203 public static List getAnnotations(final Class annotation, final Constructor constructor) {
204 return getAnnotations(getAnnnotationName(annotation), constructor);
205 }
206
207 /***
208 * Return a list with the annotations with a specific name for a specific field.
209 *
210 * @param annotationName the annotation name
211 * @param field the java.lang.reflect.Field object to find the annotation on.
212 * @return the annotations in a list (can be empty)
213 */
214 public static List getAnnotations(final String annotationName, final Field field) {
215 ClassLoader loader = field.getDeclaringClass().getClassLoader();
216 ClassInfo classInfo = AsmClassInfo.getClassInfo(field.getDeclaringClass().getName(), loader);
217 FieldInfo fieldInfo = classInfo.getField(ReflectHelper.calculateHash(field));
218 return AsmAnnotations.getAnnotations(annotationName, fieldInfo);
219 }
220
221 /***
222 * Return a list with the annotations with a specific name for a specific field.
223 *
224 * @param annotation the annotation class
225 * @param field the java.lang.reflect.Field object to find the annotation on.
226 * @return the annotations in a list (can be empty)
227 */
228 public static List getAnnotations(final Class annotation, final Field field) {
229 return getAnnotations(getAnnnotationName(annotation), field);
230 }
231
232 /***
233 * Return a list with the annotations for a specific class. <p/>Each annotation is wrapped in {@link
234 * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
235 *
236 * @param klass the java.lang.Class object to find the annotation on.
237 * @return a list with the annotations
238 */
239 public static List getAnnotationInfos(final Class klass) {
240 return AsmClassInfo.getClassInfo(klass.getName(), klass.getClassLoader()).getAnnotations();
241 }
242
243 /***
244 * Return the annotations for a specific method. <p/>Each annotation is wrapped in {@link
245 * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
246 *
247 * @param method the java.lang.refect.Method object to find the annotation on.
248 * @return a list with the annotations
249 */
250 public static List getAnnotationInfos(final Method method) {
251 ClassLoader loader = method.getDeclaringClass().getClassLoader();
252 ClassInfo classInfo = AsmClassInfo.getClassInfo(method.getDeclaringClass().getName(), loader);
253
254 MethodInfo methodInfo = classInfo.getMethod(ReflectHelper.calculateHash(method));
255 if (methodInfo != null) {
256 return methodInfo.getAnnotations();
257 } else {
258 return EMPTY_LIST;
259 }
260 }
261
262 /***
263 * Return the annotations for a specific constructor. <p/>Each annotation is wrapped in {@link
264 * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
265 *
266 * @param constructor the java.lang.reflect.Constructor object to find the annotation on.
267 * @return a list with the annotations
268 */
269 public static List getAnnotationInfos(final Constructor constructor) {
270 ClassLoader loader = constructor.getDeclaringClass().getClassLoader();
271 ClassInfo classInfo = AsmClassInfo.getClassInfo(constructor.getDeclaringClass().getName(), loader);
272 return classInfo.getConstructor(ReflectHelper.calculateHash(constructor)).getAnnotations();
273 }
274
275 /***
276 * Return the annotations for a specific field. <p/>Each annotation is wrapped in {@link
277 * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
278 *
279 * @param field the java.lang.reflect.Field object to find the annotation on.
280 * @return a list with the annotations
281 */
282 public static List getAnnotationInfos(final Field field) {
283 ClassLoader loader = field.getDeclaringClass().getClassLoader();
284 ClassInfo classInfo = AsmClassInfo.getClassInfo(field.getDeclaringClass().getName(), loader);
285
286 FieldInfo fieldInfo = classInfo.getField(ReflectHelper.calculateHash(field));
287 if (fieldInfo != null) {
288 return fieldInfo.getAnnotations();
289 } else {
290 return EMPTY_LIST;
291 }
292 }
293
294 /***
295 // * Returns the annotation proxy class for a specific annotation loaded in a specific loader.
296 // *
297 // * @param annotationName
298 // * @param loader
299 // * @return
300 // */
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323 private static String getAnnnotationName(Class annotation) {
324 return annotation.getName().replace('/', '.');
325 }
326 }