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.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         // AW methods like aw$initJoinPoints may not be visible
    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         // AW fields like aw$instanceLevelAspects may not be visible
    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 //    public static Class getProxyClass(final String annotationName, final ClassLoader loader) {
    302 //        Class proxyClass;
    303 //        AsmClassInfoRepository classInfoRepository = AsmClassInfoRepository.getRepository(loader);
    304 //        String proxyClassName = (String) classInfoRepository.getAnnotationProperties().get(annotationName);
    305 //        if (proxyClassName == null) {
    306 //            return null;
    307 //        }
    308 //        if (proxyClassName.equals("")) {
    309 //            throw new DefinitionException("untyped annotations can not be used with Java5 annotations");
    310 //        } else {
    311 //            try {
    312 //                proxyClass = loader.loadClass(proxyClassName);
    313 //            } catch (ClassNotFoundException e) {
    314 //                String message = proxyClassName
    315 //                                 +
    316 //                                 " could not be found on system classpath or class path provided as argument to the compiler";
    317 //                throw new DefinitionException(message);
    318 //            }
    319 //        }
    320 //        return proxyClass;
    321 //    }
    322
    323     private static String getAnnnotationName(Class annotation) {
    324         return annotation.getName().replace('/', '.');
    325     }
    326 }