Example usage for java.lang.reflect AnnotatedElement getAnnotationsByType

List of usage examples for java.lang.reflect AnnotatedElement getAnnotationsByType

Introduction

In this page you can find the example usage for java.lang.reflect AnnotatedElement getAnnotationsByType.

Prototype

default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) 

Source Link

Document

Returns annotations that are associated with this element.

Usage

From source file:com.github.helenusdriver.commons.lang3.reflect.ReflectionUtils.java

/**
 * Gets annotations that are associated with the specified element. If there
 * are no annotations associated with the element, the return value is an
 * empty map. The difference between this method and
 * {@link AnnotatedElement#getAnnotationsByType(Class)} is that this method
 * works on annotation classes that are annotated with the {@link Keyable}
 * annotation in order to determine the key of each annotation. For this to
 * work, the annotated class must defined a key element as defined in the
 * {@link Keyable} annotation of the same return type as specified in
 * <code>keyClass</code>. If its argument is a repeatable annotation type
 * (JLS 9.6), this method, attempts to find one or more annotations of that
 * type by "looking through" a container annotation. The caller of this method
 * is free to modify the returned map; it will have no effect on the maps
 * returned to other callers./*from   w w w. ja v  a2  s  .  c  o  m*/
 * <p>
 * This method will look for both the specified annotation and if the
 * annotation is annotated with {@link Repeatable}, it will also look for this
 * containing annotation which must have a <code>value()</code>
 * element with an array type of the specified annotation. The resulting
 * array will always start with the annotation itself if found followed by
 * all of those provided by the containing annotation.
 *
 * @author paouelle
 *
 * @param <K> the type of the keys to find
 * @param <T> the type of the annotation to query for and return if present
 *
 * @param  keyClass the class of the keys to find and return
 * @param  annotationClass the type of annotations to retrieve
 * @param  annotatedElement the element from which to retrieve the annotations
 * @return a non-<code>null</code> ordered map of annotations associated with the
 *         given element properly keyed as defined in each annotation (may be
 *         empty if none found)
 * @throws NullPointerException if <code>annotatedElement</code>,
 *         <code>annotationClass</code> or <code>keyClass</code> is
 *         <code>null</code>
 * @throws IllegalArgumentException if <code>annotationClass</code> is not
 *         annotated with {@link Keyable} or if the containing annotation
 *         doesn't define a <code>value()</code> element returning an array
 *         of type <code>annotationClass</code> or if <code>annotationClass</code>
 *         doesn't define an element named as specified in its {@link Keyable}
 *         annotation that returns a value of the same class as <code>keyClass</code>
 *         or again if a duplicated keyed annotation is found
 */
@SuppressWarnings("unchecked")
public static <K, T extends Annotation> Map<K, T> getAnnotationsByType(Class<K> keyClass,
        Class<T> annotationClass, AnnotatedElement annotatedElement) {
    org.apache.commons.lang3.Validate.notNull(annotationClass, "invalid null annotation class");
    org.apache.commons.lang3.Validate.notNull(annotatedElement, "invalid null annotation element");
    org.apache.commons.lang3.Validate.notNull(keyClass, "invalid null key class");
    final Keyable k = annotationClass.getAnnotation(Keyable.class);

    org.apache.commons.lang3.Validate.isTrue(k != null, "annotation @%s not annotated with @Keyable",
            annotationClass.getName());
    final Method km;

    try {
        km = annotationClass.getMethod(k.value());
    } catch (NoSuchMethodException e) {
        throw new IllegalArgumentException(
                "annotation key element @" + annotationClass.getName() + "." + k.value() + "() not found", e);
    }
    org.apache.commons.lang3.Validate.isTrue(keyClass.isAssignableFrom(km.getReturnType()),
            "annotation key element @%s.%s() doesn't return class: %s", annotationClass.getName(), k.value(),
            keyClass.getName());
    final T[] as = annotatedElement.getAnnotationsByType(annotationClass);

    if (as.length == 0) {
        return Collections.emptyMap();
    }
    final Map<K, T> map = new LinkedHashMap<>(as.length);

    for (T a : as) {
        final K ak;

        try {
            ak = (K) km.invoke(a);
        } catch (IllegalAccessException e) { // not expected
            throw new IllegalStateException(e);
        } catch (InvocationTargetException e) {
            final Throwable t = e.getTargetException();

            if (t instanceof Error) {
                throw (Error) t;
            } else if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else { // not expected
                throw new IllegalStateException(e);
            }
        }
        org.apache.commons.lang3.Validate.isTrue(map.put(ak, a) == null,
                "duplicate key '%s' found in annotation @%s", ak, annotationClass.getName());
    }
    return map;
}