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