Description

find Annotation

License

Apache License

Declaration

public static <A extends Annotation> A findAnnotation(Class clazz, Class<A> annotationType) 

Method Source Code

//package com.java2s;
/**// w  w w. j a va2  s . co  m
 *
 *     Copyright (C) norad.fr
 *
 *     Licensed under the Apache License, Version 2.0 (the "License");
 *     you may not use this file except in compliance with the License.
 *     You may obtain a copy of the License at
 *
 *             http://www.apache.org/licenses/LICENSE-2.0
 *
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 */

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.WeakHashMap;

public class Main {
    private static final Map<Class<?>, Boolean> annotatedInterfaceCache = new WeakHashMap<Class<?>, Boolean>();

    public static <A extends Annotation> A findAnnotation(Class clazz, Class<A> annotationType) {
        A annotation = getAnnotation(clazz, annotationType);
        Class<?> cl = clazz;
        if (annotation == null) {
            annotation = searchOnInterfaces(clazz, annotationType, cl.getInterfaces());
        }
        while (annotation == null) {
            cl = cl.getSuperclass();
            if (cl == null || cl == Object.class) {
                break;
            }
            annotation = getAnnotation(cl, annotationType);
            if (annotation == null) {
                annotation = searchOnInterfaces(clazz, annotationType, cl.getInterfaces());
            }
        }
        return annotation;
    }

    public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
        A annotation = getAnnotation(method, annotationType);
        Class<?> cl = method.getDeclaringClass();
        if (annotation == null) {
            annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces());
        }
        while (annotation == null) {
            cl = cl.getSuperclass();
            if (cl == null || cl == Object.class) {
                break;
            }
            try {
                Method equivalentMethod = cl.getDeclaredMethod(method.getName(), method.getParameterTypes());
                annotation = getAnnotation(equivalentMethod, annotationType);
                if (annotation == null) {
                    annotation = searchOnInterfaces(method, annotationType, cl.getInterfaces());
                }
            } catch (NoSuchMethodException ex) {
                // We're done...
            }
        }
        return annotation;
    }

    public static <T extends Annotation> T getAnnotation(AnnotatedElement ae, Class<T> annotationType) {
        T ann = ae.getAnnotation(annotationType);
        if (ann == null) {
            for (Annotation metaAnn : ae.getAnnotations()) {
                ann = metaAnn.annotationType().getAnnotation(annotationType);
                if (ann != null) {
                    break;
                }
            }
        }
        return ann;
    }

    private static <A extends Annotation> A searchOnInterfaces(Method method, Class<A> annotationType,
            Class<?>[] ifcs) {
        A annotation = null;
        for (Class<?> iface : ifcs) {
            if (isInterfaceWithAnnotatedMethods(iface)) {
                try {
                    Method equivalentMethod = iface.getMethod(method.getName(), method.getParameterTypes());
                    annotation = getAnnotation(equivalentMethod, annotationType);
                } catch (NoSuchMethodException ex) {
                    // Skip this interface - it doesn't have the method...
                }
                if (annotation != null) {
                    break;
                }
            }
        }
        return annotation;
    }

    private static <A extends Annotation> A searchOnInterfaces(Class clazz, Class<A> annotationType,
            Class<?>[] ifcs) {
        A annotation = null;
        for (Class<?> iface : ifcs) {
            annotation = getAnnotation(iface, annotationType);
            if (annotation != null) {
                break;
            }
        }
        return annotation;
    }

    private static boolean isInterfaceWithAnnotatedMethods(Class<?> iface) {
        synchronized (annotatedInterfaceCache) {
            Boolean flag = annotatedInterfaceCache.get(iface);
            if (flag != null) {
                return flag;
            }
            boolean found = false;
            for (Method ifcMethod : iface.getMethods()) {
                if (ifcMethod.getAnnotations().length > 0) {
                    found = true;
                    break;
                }
            }
            annotatedInterfaceCache.put(iface, found);
            return found;
        }
    }
}

Related

  1. findAnnotation(AnnotatedElement annotatedElement, Class annotationType)
  2. findAnnotation(AnnotatedElement element, Class annotationType)
  3. findAnnotation(Annotation parentAnnotation, Class annotationType)
  4. findAnnotation(Annotation[] parameterAnnotations, Class targetAnnotation)
  5. findAnnotation(Annotation[] searchList, Class annotation)
  6. findAnnotation(Class clazz, Class annotationType)
  7. findAnnotation(Class aClass, Class annotationClass)
  8. findAnnotation(Class classy, Class targetAnnotation)
  9. findAnnotation(Class clazz, Class annotationClass, Set> set)