src/share/classes/sun/reflect/annotation/AnnotationSupport.java

Print this page




 158             Class<?> decl,
 159             Class<A> annoClass) {
 160         Objects.requireNonNull(decl);
 161 
 162         // Search declared
 163         A[] result = getDirectlyAndIndirectlyPresent(declaredAnnotations, annoClass);
 164 
 165         // Search inherited
 166         if(AnnotationType.getInstance(annoClass).isInherited()) {
 167             Class<?> superDecl = decl.getSuperclass();
 168             while (result.length == 0 && superDecl != null) {
 169                 result = getDirectlyAndIndirectlyPresent(LANG_ACCESS.getDeclaredAnnotationMap(superDecl), annoClass);
 170                 superDecl = superDecl.getSuperclass();
 171             }
 172         }
 173 
 174         return result;
 175     }
 176 
 177 
 178     /* Reflectively invoke the values-method of the given annotation
 179      * (container), cast it to an array of annotations and return the result.


 180      */
 181     private static <A extends Annotation> A[] getValueArray(Annotation container) {
 182         try {
 183             // According to JLS the container must have an array-valued value
 184             // method. Get the AnnotationType, get the "value" method and invoke
 185             // it to get the content.
 186 
 187             Class<? extends Annotation> containerClass = container.annotationType();
 188             AnnotationType annoType = AnnotationType.getInstance(containerClass);
 189             if (annoType == null)
 190                 throw invalidContainerException(container, null);
 191 
 192             Method m = annoType.members().get("value");
 193             if (m == null)
 194                 throw invalidContainerException(container, null);
 195 
 196             m.setAccessible(true);
 197 
 198             // This will erase to (Annotation[]) but we do a runtime cast on the
 199             // return-value in the method that call this method.
 200             @SuppressWarnings("unchecked")
 201             A[] values = (A[]) m.invoke(container);
 202 
 203             return values;
 204 
 205         } catch (IllegalAccessException    | // couldn't loosen security
 206                  IllegalArgumentException  | // parameters doesn't match
 207                  InvocationTargetException | // the value method threw an exception
 208                  ClassCastException e) {
 209 
 210             throw invalidContainerException(container, e);
 211 
 212         }
 213     }
 214 
 215 
 216     private static AnnotationFormatError invalidContainerException(Annotation anno,
 217                                                                    Throwable cause) {
 218         return new AnnotationFormatError(
 219                 anno + " is an invalid container for repeating annotations",
 220                 cause);
 221     }
 222 
 223 
 224     /* Sanity check type of all the annotation instances of type {@code annoClass}
 225      * from {@code container}.
 226      */
 227     private static <A extends Annotation> void checkTypes(A[] annotations,
 228                                                           Annotation container,
 229                                                           Class<A> annoClass) {
 230         for (A a : annotations) {
 231             if (!annoClass.isInstance(a)) {


 158             Class<?> decl,
 159             Class<A> annoClass) {
 160         Objects.requireNonNull(decl);
 161 
 162         // Search declared
 163         A[] result = getDirectlyAndIndirectlyPresent(declaredAnnotations, annoClass);
 164 
 165         // Search inherited
 166         if(AnnotationType.getInstance(annoClass).isInherited()) {
 167             Class<?> superDecl = decl.getSuperclass();
 168             while (result.length == 0 && superDecl != null) {
 169                 result = getDirectlyAndIndirectlyPresent(LANG_ACCESS.getDeclaredAnnotationMap(superDecl), annoClass);
 170                 superDecl = superDecl.getSuperclass();
 171             }
 172         }
 173 
 174         return result;
 175     }
 176 
 177 
 178     /*
 179      * Reflectively invoke the values-method of the given annotation
 180      * (container), cast it to an array of annotations and return the
 181      * result.
 182      */
 183     public static <A extends Annotation> A[] getValueArray(Annotation container) {
 184         try {
 185             // According to JLS the container must have an array-valued value
 186             // method. Get the AnnotationType, get the "value" method and invoke
 187             // it to get the content.
 188 
 189             Class<? extends Annotation> containerClass = container.annotationType();
 190             AnnotationType annoType = AnnotationType.getInstance(containerClass);
 191             if (annoType == null)
 192                 throw invalidContainerException(container, null);
 193 
 194             Method m = annoType.members().get("value");
 195             if (m == null)
 196                 throw invalidContainerException(container, null);
 197 
 198             m.setAccessible(true);
 199 
 200             // This will erase to (Annotation[]) but we do a runtime cast on the
 201             // return-value in the method that call this method.
 202             @SuppressWarnings("unchecked")
 203             A[] values = (A[]) m.invoke(container);

 204             return values;

 205         } catch (IllegalAccessException    | // couldn't loosen security
 206                  IllegalArgumentException  | // parameters doesn't match
 207                  InvocationTargetException | // the value method threw an exception
 208                  ClassCastException e) {

 209             throw invalidContainerException(container, e);

 210         }
 211     }
 212 
 213 
 214     private static AnnotationFormatError invalidContainerException(Annotation anno,
 215                                                                    Throwable cause) {
 216         return new AnnotationFormatError(
 217                 anno + " is an invalid container for repeating annotations",
 218                 cause);
 219     }
 220 
 221 
 222     /* Sanity check type of all the annotation instances of type {@code annoClass}
 223      * from {@code container}.
 224      */
 225     private static <A extends Annotation> void checkTypes(A[] annotations,
 226                                                           Annotation container,
 227                                                           Class<A> annoClass) {
 228         for (A a : annotations) {
 229             if (!annoClass.isInstance(a)) {