001: /**************************************************************************************
002: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package org.codehaus.aspectwerkz.annotation;
008:
009: import org.codehaus.aspectwerkz.reflect.MethodInfo;
010: import org.codehaus.aspectwerkz.reflect.ClassInfo;
011: import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
012: import org.codehaus.aspectwerkz.reflect.FieldInfo;
013: import org.codehaus.aspectwerkz.reflect.ReflectHelper;
014: import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;
015: import org.codehaus.aspectwerkz.annotation.instrumentation.asm.AsmAnnotations;
016:
017: import java.lang.reflect.Constructor;
018: import java.lang.reflect.Field;
019: import java.lang.reflect.Method;
020: import java.util.List;
021: import java.util.ArrayList;
022:
023: /**
024: * Utility class for annotation retrieval.
025: * <br/>Note: Annotations are extracted out of ASMClassInfo
026: * <br/>Note: caution when changing that to use reflection, since it might lead to load target class during aspect
027: * system startup.
028: *
029: * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
030: */
031: public final class Annotations {
032:
033: private final static List EMPTY_LIST = new ArrayList();
034:
035: /**
036: * Return the annotation with a specific name for a specific class.
037: *
038: * @param annotationName the annotation name
039: * @param klass the java.lang.Class object to find the annotation on.
040: * @return the annotation or null
041: */
042: public static Annotation getAnnotation(final String annotationName,
043: final Class klass) {
044: ClassInfo classInfo = AsmClassInfo.getClassInfo(
045: klass.getName(), klass.getClassLoader());
046: return AsmAnnotations.getAnnotation(annotationName, classInfo);
047: }
048:
049: /**
050: * Return the annotation with a specific name for a specific class.
051: *
052: * @param annotation the annotation class
053: * @param klass the java.lang.Class object to find the annotation on.
054: * @return the annotation or null
055: */
056: public static Annotation getAnnotation(final Class annotation,
057: final Class klass) {
058: return getAnnotation(getAnnnotationName(annotation), klass);
059: }
060:
061: /**
062: * Return the annotation with a specific name for a specific method.
063: *
064: * @param annotationName the annotation name
065: * @param method the java.lang.refect.Method object to find the annotation on.
066: * @return the annotation or null
067: */
068: public static Annotation getAnnotation(final String annotationName,
069: final Method method) {
070: ClassLoader loader = method.getDeclaringClass()
071: .getClassLoader();
072: ClassInfo classInfo = AsmClassInfo.getClassInfo(method
073: .getDeclaringClass().getName(), loader);
074: MethodInfo methodInfo = classInfo.getMethod(ReflectHelper
075: .calculateHash(method));
076: return AsmAnnotations.getAnnotation(annotationName, methodInfo);
077: }
078:
079: /**
080: * Return the annotation with a specific name for a specific method.
081: *
082: * @param annotation the annotation class
083: * @param method the java.lang.refect.Method object to find the annotation on.
084: * @return the annotation or null
085: */
086: public static Annotation getAnnotation(final Class annotation,
087: final Method method) {
088: return getAnnotation(getAnnnotationName(annotation), method);
089: }
090:
091: /**
092: * Return the annotation with a specific name for a specific constructor.
093: *
094: * @param annotationName the annotation name
095: * @param constructor the java.lang.refect.Constructor object to find the annotation on.
096: * @return the annotation or null
097: */
098: public static Annotation getAnnotation(final String annotationName,
099: final Constructor constructor) {
100: ClassLoader loader = constructor.getDeclaringClass()
101: .getClassLoader();
102: ClassInfo classInfo = AsmClassInfo.getClassInfo(constructor
103: .getDeclaringClass().getName(), loader);
104: ConstructorInfo constructorInfo = classInfo
105: .getConstructor(ReflectHelper
106: .calculateHash(constructor));
107: return AsmAnnotations.getAnnotation(annotationName,
108: constructorInfo);
109: }
110:
111: /**
112: * Return the annotation with a specific name for a specific constructor.
113: *
114: * @param annotation the annotation class
115: * @param constructor the java.lang.refect.Constructor object to find the annotation on.
116: * @return the annotation or null
117: */
118: public static Annotation getAnnotation(final Class annotation,
119: final Constructor constructor) {
120: return getAnnotation(getAnnnotationName(annotation),
121: constructor);
122: }
123:
124: /**
125: * Return the annotation with a specific name for a specific field.
126: *
127: * @param annotationName the annotation name
128: * @param field the java.lang.reflect.Field object to find the annotation on.
129: * @return the annotation or null
130: */
131: public static Annotation getAnnotation(final String annotationName,
132: final Field field) {
133: ClassLoader loader = field.getDeclaringClass().getClassLoader();
134: ClassInfo classInfo = AsmClassInfo.getClassInfo(field
135: .getDeclaringClass().getName(), loader);
136: FieldInfo fieldInfo = classInfo.getField(ReflectHelper
137: .calculateHash(field));
138: return AsmAnnotations.getAnnotation(annotationName, fieldInfo);
139: }
140:
141: /**
142: * Return the annotation with a specific name for a specific field.
143: *
144: * @param annotation the annotation class
145: * @param field the java.lang.reflect.Field object to find the annotation on.
146: * @return the annotation or null
147: */
148: public static Annotation getAnnotation(final Class annotation,
149: final Field field) {
150: return getAnnotation(getAnnnotationName(annotation), field);
151: }
152:
153: /**
154: * Return a list with the annotations with a specific name for a specific class.
155: *
156: * @param annotationName the annotation name
157: * @param klass the java.lang.Class object to find the annotation on.
158: * @return the annotations in a list (can be empty)
159: */
160: public static List getAnnotations(final String annotationName,
161: final Class klass) {
162: ClassInfo classInfo = AsmClassInfo.getClassInfo(
163: klass.getName(), klass.getClassLoader());
164: return AsmAnnotations.getAnnotations(annotationName, classInfo);
165: }
166:
167: /**
168: * Return a list with the annotations with a specific name for a specific class.
169: *
170: * @param annotation the annotation class
171: * @param klass the java.lang.Class object to find the annotation on.
172: * @return the annotations in a list (can be empty)
173: */
174: public static List getAnnotations(final Class annotation,
175: final Class klass) {
176: return getAnnotations(getAnnnotationName(annotation), klass);
177: }
178:
179: /**
180: * Return a list with the annotations with a specific name for a specific method.
181: *
182: * @param annotationName the annotation name
183: * @param method the java.lang.refect.Method object to find the annotation on.
184: * @return the annotations in a list (can be empty)
185: */
186: public static List getAnnotations(final String annotationName,
187: final Method method) {
188: ClassLoader loader = method.getDeclaringClass()
189: .getClassLoader();
190: ClassInfo classInfo = AsmClassInfo.getClassInfo(method
191: .getDeclaringClass().getName(), loader);
192: MethodInfo methodInfo = classInfo.getMethod(ReflectHelper
193: .calculateHash(method));
194: return AsmAnnotations
195: .getAnnotations(annotationName, methodInfo);
196: }
197:
198: /**
199: * Return a list with the annotations with a specific name for a specific method.
200: *
201: * @param annotation the annotation class
202: * @param method the java.lang.refect.Method object to find the annotation on.
203: * @return the annotations in a list (can be empty)
204: */
205: public static List getAnnotations(final Class annotation,
206: final Method method) {
207: return getAnnotations(getAnnnotationName(annotation), method);
208: }
209:
210: /**
211: * Return a list with the annotations with a specific name for a specific constructor.
212: *
213: * @param annotationName the annotation name
214: * @param constructor the java.lang.refect.Constructor object to find the annotation on.
215: * @return the annotations in a list (can be empty)
216: */
217: public static List getAnnotations(final String annotationName,
218: final Constructor constructor) {
219: ClassLoader loader = constructor.getDeclaringClass()
220: .getClassLoader();
221: ClassInfo classInfo = AsmClassInfo.getClassInfo(constructor
222: .getDeclaringClass().getName(), loader);
223: ConstructorInfo constructorInfo = classInfo
224: .getConstructor(ReflectHelper
225: .calculateHash(constructor));
226: return AsmAnnotations.getAnnotations(annotationName,
227: constructorInfo);
228: }
229:
230: /**
231: * Return a list with the annotations with a specific name for a specific constructor.
232: *
233: * @param annotation the annotation class
234: * @param constructor the java.lang.refect.Constructor object to find the annotation on.
235: * @return the annotations in a list (can be empty)
236: */
237: public static List getAnnotations(final Class annotation,
238: final Constructor constructor) {
239: return getAnnotations(getAnnnotationName(annotation),
240: constructor);
241: }
242:
243: /**
244: * Return a list with the annotations with a specific name for a specific field.
245: *
246: * @param annotationName the annotation name
247: * @param field the java.lang.reflect.Field object to find the annotation on.
248: * @return the annotations in a list (can be empty)
249: */
250: public static List getAnnotations(final String annotationName,
251: final Field field) {
252: ClassLoader loader = field.getDeclaringClass().getClassLoader();
253: ClassInfo classInfo = AsmClassInfo.getClassInfo(field
254: .getDeclaringClass().getName(), loader);
255: FieldInfo fieldInfo = classInfo.getField(ReflectHelper
256: .calculateHash(field));
257: return AsmAnnotations.getAnnotations(annotationName, fieldInfo);
258: }
259:
260: /**
261: * Return a list with the annotations with a specific name for a specific field.
262: *
263: * @param annotation the annotation class
264: * @param field the java.lang.reflect.Field object to find the annotation on.
265: * @return the annotations in a list (can be empty)
266: */
267: public static List getAnnotations(final Class annotation,
268: final Field field) {
269: return getAnnotations(getAnnnotationName(annotation), field);
270: }
271:
272: /**
273: * Return a list with the annotations for a specific class. <p/>Each annotation is wrapped in {@link
274: * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
275: *
276: * @param klass the java.lang.Class object to find the annotation on.
277: * @return a list with the annotations
278: */
279: public static List getAnnotationInfos(final Class klass) {
280: return AsmClassInfo.getClassInfo(klass.getName(),
281: klass.getClassLoader()).getAnnotations();
282: }
283:
284: /**
285: * Return the annotations for a specific method. <p/>Each annotation is wrapped in {@link
286: * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
287: *
288: * @param method the java.lang.refect.Method object to find the annotation on.
289: * @return a list with the annotations
290: */
291: public static List getAnnotationInfos(final Method method) {
292: ClassLoader loader = method.getDeclaringClass()
293: .getClassLoader();
294: ClassInfo classInfo = AsmClassInfo.getClassInfo(method
295: .getDeclaringClass().getName(), loader);
296: // AW methods like aw$initJoinPoints may not be visible
297: MethodInfo methodInfo = classInfo.getMethod(ReflectHelper
298: .calculateHash(method));
299: if (methodInfo != null) {
300: return methodInfo.getAnnotations();
301: } else {
302: return EMPTY_LIST;
303: }
304: }
305:
306: /**
307: * Return the annotations for a specific constructor. <p/>Each annotation is wrapped in {@link
308: * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
309: *
310: * @param constructor the java.lang.reflect.Constructor object to find the annotation on.
311: * @return a list with the annotations
312: */
313: public static List getAnnotationInfos(final Constructor constructor) {
314: ClassLoader loader = constructor.getDeclaringClass()
315: .getClassLoader();
316: ClassInfo classInfo = AsmClassInfo.getClassInfo(constructor
317: .getDeclaringClass().getName(), loader);
318: return classInfo.getConstructor(
319: ReflectHelper.calculateHash(constructor))
320: .getAnnotations();
321: }
322:
323: /**
324: * Return the annotations for a specific field. <p/>Each annotation is wrapped in {@link
325: * org.codehaus.aspectwerkz.annotation.AnnotationInfo}instance.
326: *
327: * @param field the java.lang.reflect.Field object to find the annotation on.
328: * @return a list with the annotations
329: */
330: public static List getAnnotationInfos(final Field field) {
331: ClassLoader loader = field.getDeclaringClass().getClassLoader();
332: ClassInfo classInfo = AsmClassInfo.getClassInfo(field
333: .getDeclaringClass().getName(), loader);
334: // AW fields like aw$instanceLevelAspects may not be visible
335: FieldInfo fieldInfo = classInfo.getField(ReflectHelper
336: .calculateHash(field));
337: if (fieldInfo != null) {
338: return fieldInfo.getAnnotations();
339: } else {
340: return EMPTY_LIST;
341: }
342: }
343:
344: // /**
345: // * Returns the annotation proxy class for a specific annotation loaded in a specific loader.
346: // *
347: // * @param annotationName
348: // * @param loader
349: // * @return
350: // */
351: // public static Class getProxyClass(final String annotationName, final ClassLoader loader) {
352: // Class proxyClass;
353: // AsmClassInfoRepository classInfoRepository = AsmClassInfoRepository.getRepository(loader);
354: // String proxyClassName = (String) classInfoRepository.getAnnotationProperties().get(annotationName);
355: // if (proxyClassName == null) {
356: // return null;
357: // }
358: // if (proxyClassName.equals("")) {
359: // throw new DefinitionException("untyped annotations can not be used with Java5 annotations");
360: // } else {
361: // try {
362: // proxyClass = loader.loadClass(proxyClassName);
363: // } catch (ClassNotFoundException e) {
364: // String message = proxyClassName
365: // +
366: // " could not be found on system classpath or class path provided as argument to the compiler";
367: // throw new DefinitionException(message);
368: // }
369: // }
370: // return proxyClass;
371: // }
372:
373: private static String getAnnnotationName(Class annotation) {
374: return annotation.getName().replace('/', '.');
375: }
376: }
|