19599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin/*
29599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * Copyright (C) 2016 The Android Open Source Project
39599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin *
49599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
59599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * you may not use this file except in compliance with the License.
69599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * You may obtain a copy of the License at
79599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin *
89599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
99599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin *
109599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * Unless required by applicable law or agreed to in writing, software
119599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
129599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * See the License for the specific language governing permissions and
149599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * limitations under the License.
159599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin */
169599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
179599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkinpackage libcore.reflect;
189599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
199599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkinimport java.lang.annotation.Annotation;
209599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkinimport java.lang.annotation.IncompleteAnnotationException;
219599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkinimport java.lang.annotation.Repeatable;
229599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkinimport java.lang.reflect.*;
239599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkinimport java.util.ArrayList;
249599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
259599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin/**
269599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * Implementation of {@link AnnotatedElement}'s 1.8 methods.
279599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin *
289599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * <p>This implementation is shared between all the classes implementing {@link AnnotatedElement},
299599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * avoiding code duplication.</p>
309599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin *
319599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin * @hide
329599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin */
339599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkinpublic final class AnnotatedElements {
349599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  /**
3520938c5ed2bc8f5de8047a47caddb146f730868fNeil Fuller   * Default implementation of {@link AnnotatedElement#getDeclaredAnnotationsByType}, and
3620938c5ed2bc8f5de8047a47caddb146f730868fNeil Fuller   * {@link AnnotatedElement#getAnnotationsByType} for elements that do not support annotation
3720938c5ed2bc8f5de8047a47caddb146f730868fNeil Fuller   * inheritance.
389599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *
399599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * @return Directly/indirectly present list of annotations of type {@code annotationClass} for
409599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *         {@code element}, or an empty array if none were found.
419599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   */
4220938c5ed2bc8f5de8047a47caddb146f730868fNeil Fuller  public static <T extends Annotation> T[] getDirectOrIndirectAnnotationsByType(
4320938c5ed2bc8f5de8047a47caddb146f730868fNeil Fuller        AnnotatedElement element, Class<T> annotationClass) {
449599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    if (annotationClass == null) {
459599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      throw new NullPointerException("annotationClass");
469599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    }
479599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
489599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    Annotation[] annotations = element.getDeclaredAnnotations();
499599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
509599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // Store a list of repeatable annotations that have been extracted from their container.
519599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    ArrayList<T> unfoldedAnnotations = new ArrayList<T>();
529599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
539599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    Class<? extends Annotation> repeatableAnnotationClass =
549599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin        getRepeatableAnnotationContainerClassFor(annotationClass);
559599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
569599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    for (int i = 0; i < annotations.length; ++i) {
579599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      if (annotationClass.isInstance(annotations[i])) {
589599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin        // Is it directly present?
599599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin        unfoldedAnnotations.add((T)annotations[i]);  // Safe, guarded by above check.
609599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      } else if (repeatableAnnotationClass != null &&
619599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin          repeatableAnnotationClass.isInstance(annotations[i])) {
629599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin        // Is it repeatably (indirectly) present?
639599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin        insertAnnotationValues(annotations[i], annotationClass, unfoldedAnnotations);
649599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      }
659599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    }
669599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
679599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    return unfoldedAnnotations.toArray((T[])Array.newInstance(annotationClass, 0));
689599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  }
699599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
709599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  /**
719599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * Extracts annotations from a container annotation and inserts them into a list.
729599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *
739599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * <p>
749599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * Given a complex annotation "annotation", it should have a "T[] value()" method on it.
759599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * Call that method and add all of the nested annotations into unfoldedAnnotations list.
769599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * </p>
779599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   */
789599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  private static <T extends Annotation> void insertAnnotationValues(Annotation annotation,
799599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      Class<T> annotationClass, ArrayList<T> unfoldedAnnotations) {
809599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // annotation is a complex annotation which has elements of instance annotationClass
819599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // (whose static type is T).
829599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    //
839599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // @interface SomeName {  <--- = annotation.getClass()
849599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    //   ...
859599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    //   T[] value();        <--- T.class == annotationClass
869599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // }
879599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    //
889599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // Use reflection to access these values.
899599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    Class<T[]> annotationArrayClass =
909599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin        (Class<T[]>)((T[])Array.newInstance(annotationClass, 0)).getClass();
919599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
929599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    Method valuesMethod;
939599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    try {
949599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      valuesMethod = annotation.getClass().getDeclaredMethod("value");
959599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      // This will always succeed unless the annotation and its repeatable annotation class were
969599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      // recompiled separately, then this is a binary incompatibility error.
979599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    } catch (NoSuchMethodException e) {
989599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      throw new AssertionError("annotation container = " + annotation +
999599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin          "annotation element class = " + annotationClass + "; missing value() method");
1009599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    } catch (SecurityException e) {
1019599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      throw new IncompleteAnnotationException(annotation.getClass(), "value");
1029599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    }
1039599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
1049599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // Ensure that value() returns a T[]
1059599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    if (!valuesMethod.getReturnType().isArray()) {
1069599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      throw new AssertionError("annotation container = " + annotation +
1079599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin          "annotation element class = " + annotationClass + "; value() doesn't return array");
1089599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    }
1099599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
1109599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // Ensure that the T[] value() is actually the correct type (T==annotationClass).
1119599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    if (!annotationClass.equals(valuesMethod.getReturnType().getComponentType())) {
1129599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      throw new AssertionError("annotation container = " + annotation +
1139599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin          "annotation element class = " + annotationClass + "; value() returns incorrect type");
1149599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    }
1159599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
1169599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    // Append those values into the existing list.
1179599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    T[] nestedAnnotations;
1189599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    try {
1199599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      nestedAnnotations = (T[])valuesMethod.invoke(annotation);  // Safe because of #getMethod.
1209599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    } catch (IllegalAccessException|InvocationTargetException e) {
1219599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      throw new AssertionError(e);
1229599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    }
1239599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
1249599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    for (int i = 0; i < nestedAnnotations.length; ++i) {
1259599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      unfoldedAnnotations.add(nestedAnnotations[i]);
1269599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    }
1279599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  }
1289599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
1299599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  /**
1309599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * Find the {@code \@Repeatable} container annotation class for an annotation class, or
1319599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * {@code null}.
1329599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *
1339599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * <p>
1349599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * Given:
1359599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *
1369599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * <code>
1379599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *  @Repeatable(X.class)
1389599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *  @interface SomeName {     <--- = annotationClass
1399599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *  }...
1409599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * </code>
1419599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *
1429599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * <p>
1439599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * Returns {@code X.class}
1449599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   *
1459599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * Otherwise if there was no {@code \@Repeatable} annotation, return {@code null}.
1469599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   * </p>
1479599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin   */
1489599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  private static <T extends Annotation> Class<? extends Annotation>
1499599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin      getRepeatableAnnotationContainerClassFor(Class<T> annotationClass) {
1509599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
1519599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    Repeatable repeatableAnnotation = annotationClass.getDeclaredAnnotation(Repeatable.class);
1529599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin    return (repeatableAnnotation == null) ? null : repeatableAnnotation.value();
1539599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  }
1549599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
1559599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  private AnnotatedElements() {
1569599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin  }
1579599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin}
1589599ec54b164da29db4e3386a9839aca73caf8eeIgor Murashkin
159