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

Print this page




  69 
  70     /** Helper to get the container, or null if none, of an annotation. */
  71     private static <A extends Annotation> Class<? extends Annotation> getContainer(Class<A> annotationClass) {
  72         Repeatable containingAnnotation = annotationClass.getDeclaredAnnotation(Repeatable.class);
  73         return (containingAnnotation == null) ? null : containingAnnotation.value();
  74     }
  75 
  76     /** Reflectively look up and get the returned array from the the
  77      * invocation of the value() element on an instance of an
  78      * Annotation.
  79      */
  80     private static  <A extends Annotation> A[] getValueArray(Annotation containerInstance) {
  81         try {
  82             // the spec tells us the container must have an array-valued
  83             // value element. Get the AnnotationType, get the "value" element
  84             // and invoke it to get the contents.
  85 
  86             Class<? extends Annotation> containerClass = containerInstance.annotationType();
  87             AnnotationType annoType = AnnotationType.getInstance(containerClass);
  88             if (annoType == null)
  89                 throw new InvalidContainerAnnotationError(containerInstance + " is an invalid container for repeating annotations");
  90 
  91             Method m = annoType.members().get("value");
  92             if (m == null)
  93                 throw new InvalidContainerAnnotationError(containerInstance +
  94                                                           " is an invalid container for repeating annotations");
  95             m.setAccessible(true);
  96 
  97             @SuppressWarnings("unchecked") // not provably safe, but we catch the ClassCastException
  98             A[] a = (A[])m.invoke(containerInstance); // this will erase to (Annotation[]) but we
  99                                                       // do a runtime cast on the return-value
 100                                                       // in the methods that call this method
 101             return a;
 102         } catch (IllegalAccessException | // couldnt loosen security
 103                  IllegalArgumentException | // parameters doesn't match
 104                  InvocationTargetException | // the value method threw an exception
 105                  ClassCastException e) { // well, a cast failed ...
 106             throw new InvalidContainerAnnotationError(
 107                     containerInstance + " is an invalid container for repeating annotations",
 108                     e,
 109                     containerInstance,
 110                     null);
 111         }
 112     }
 113 
 114     /* Sanity check type of and return a list of all the annotation
 115      * instances of type {@code annotationClass} from {@code
 116      * containerInstance}.
 117      */
 118     private static <A extends Annotation> List<A> unpackAll(Annotation containerInstance,
 119                                                             Class<A> annotationClass) {
 120         if (containerInstance == null) {
 121             return Collections.emptyList(); // container not present
 122         }
 123 
 124         try {
 125             A[] a = getValueArray(containerInstance);
 126             List<A> l = new ArrayList<>(a.length);
 127             for (int i  = 0; i < a.length; i++)
 128                 l.add(annotationClass.cast(a[i]));
 129             return l;
 130         } catch (ClassCastException |
 131                  NullPointerException e) {
 132             throw new InvalidContainerAnnotationError(
 133                     String.format("%s is an invalid container for repeating annotations of type: %s",
 134                         containerInstance, annotationClass),
 135                     e,
 136                     containerInstance,
 137                     annotationClass);
 138         }
 139     }
 140 }


  69 
  70     /** Helper to get the container, or null if none, of an annotation. */
  71     private static <A extends Annotation> Class<? extends Annotation> getContainer(Class<A> annotationClass) {
  72         Repeatable containingAnnotation = annotationClass.getDeclaredAnnotation(Repeatable.class);
  73         return (containingAnnotation == null) ? null : containingAnnotation.value();
  74     }
  75 
  76     /** Reflectively look up and get the returned array from the the
  77      * invocation of the value() element on an instance of an
  78      * Annotation.
  79      */
  80     private static  <A extends Annotation> A[] getValueArray(Annotation containerInstance) {
  81         try {
  82             // the spec tells us the container must have an array-valued
  83             // value element. Get the AnnotationType, get the "value" element
  84             // and invoke it to get the contents.
  85 
  86             Class<? extends Annotation> containerClass = containerInstance.annotationType();
  87             AnnotationType annoType = AnnotationType.getInstance(containerClass);
  88             if (annoType == null)
  89                 throw new AnnotationFormatError(containerInstance + " is an invalid container for repeating annotations");
  90 
  91             Method m = annoType.members().get("value");
  92             if (m == null)
  93                 throw new AnnotationFormatError(containerInstance +
  94                                                           " is an invalid container for repeating annotations");
  95             m.setAccessible(true);
  96 
  97             @SuppressWarnings("unchecked") // not provably safe, but we catch the ClassCastException
  98             A[] a = (A[])m.invoke(containerInstance); // this will erase to (Annotation[]) but we
  99                                                       // do a runtime cast on the return-value
 100                                                       // in the methods that call this method
 101             return a;
 102         } catch (IllegalAccessException | // couldnt loosen security
 103                  IllegalArgumentException | // parameters doesn't match
 104                  InvocationTargetException | // the value method threw an exception
 105                  ClassCastException e) { // well, a cast failed ...
 106             throw new AnnotationFormatError(
 107                     containerInstance + " is an invalid container for repeating annotations",
 108                     e);


 109         }
 110     }
 111 
 112     /* Sanity check type of and return a list of all the annotation
 113      * instances of type {@code annotationClass} from {@code
 114      * containerInstance}.
 115      */
 116     private static <A extends Annotation> List<A> unpackAll(Annotation containerInstance,
 117                                                             Class<A> annotationClass) {
 118         if (containerInstance == null) {
 119             return Collections.emptyList(); // container not present
 120         }
 121 
 122         try {
 123             A[] a = getValueArray(containerInstance);
 124             List<A> l = new ArrayList<>(a.length);
 125             for (int i  = 0; i < a.length; i++)
 126                 l.add(annotationClass.cast(a[i]));
 127             return l;
 128         } catch (ClassCastException |
 129                  NullPointerException e) {
 130             throw new AnnotationFormatError(
 131                     String.format("%s is an invalid container for repeating annotations of type: %s",
 132                         containerInstance, annotationClass),
 133                     e);


 134         }
 135     }
 136 }