changeset 784:61db4d3eb315

add Types.typeAnnotationOf() method (parallel to Element.getAnnotation())
author mali
date Sat, 24 Oct 2009 04:41:24 -0400
parents 66107fd66788
children 1622c479717e
files src/share/classes/com/sun/tools/javac/model/JavacElements.java src/share/classes/com/sun/tools/javac/model/JavacTypes.java src/share/classes/javax/lang/model/util/Types.java
diffstat 3 files changed, 72 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Sat Oct 24 04:05:02 2009 -0400
+++ b/src/share/classes/com/sun/tools/javac/model/JavacElements.java	Sat Oct 24 04:41:24 2009 -0400
@@ -99,20 +99,27 @@
         enter = Enter.instance(context);
     }
 
+    /**
+     * An internal-use utility that creates a reified annotation.
+     */
+    public static <A extends Annotation> A getAnnotation(List<Attribute.Compound> annotations,
+            Class<A> annoType) {
+        if (!annoType.isAnnotation())
+            throw new IllegalArgumentException("Not an annotation type: "
+                                               + annoType);
+        String name = annoType.getName();
+        for (Attribute.Compound anno : annotations)
+            if (name.equals(anno.type.tsym.flatName().toString()))
+                return AnnotationProxyMaker.generateAnnotation(anno, annoType);
+        return null;
+    }
 
     /**
      * An internal-use utility that creates a reified annotation.
      */
     public static <A extends Annotation> A getAnnotation(Symbol annotated,
                                                          Class<A> annoType) {
-        if (!annoType.isAnnotation())
-            throw new IllegalArgumentException("Not an annotation type: "
-                                               + annoType);
-        String name = annoType.getName();
-        for (Attribute.Compound anno : annotated.getAnnotationMirrors())
-            if (name.equals(anno.type.tsym.flatName().toString()))
-                return AnnotationProxyMaker.generateAnnotation(anno, annoType);
-        return null;
+        return getAnnotation(annotated.getAnnotationMirrors(), annoType);
     }
 
     /**
--- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Sat Oct 24 04:05:02 2009 -0400
+++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java	Sat Oct 24 04:41:24 2009 -0400
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.model;
 
+import java.lang.annotation.Annotation;
 import java.util.List;
 import java.util.Set;
 import java.util.EnumSet;
@@ -306,4 +307,9 @@
     public List<? extends AnnotationMirror> typeAnnotationsOf(TypeMirror type) {
         return ((Type)type).typeAnnotations;
     }
+
+    public <A extends Annotation> A typeAnnotationOf(TypeMirror type,
+            Class<A> annotationType) {
+        return JavacElements.getAnnotation(((Type)type).typeAnnotations, annotationType);
+    }
 }
--- a/src/share/classes/javax/lang/model/util/Types.java	Sat Oct 24 04:05:02 2009 -0400
+++ b/src/share/classes/javax/lang/model/util/Types.java	Sat Oct 24 04:41:24 2009 -0400
@@ -25,6 +25,9 @@
 
 package javax.lang.model.util;
 
+import java.lang.annotation.Annotation;
+import java.lang.annotation.AnnotationTypeMismatchException;
+import java.lang.annotation.IncompleteAnnotationException;
 import java.util.List;
 import javax.lang.model.element.*;
 import javax.lang.model.type.*;
@@ -306,4 +309,52 @@
      * @return the type annotations targetting the type
      */
     List<? extends AnnotationMirror> typeAnnotationsOf(TypeMirror type);
+
+    /**
+     * Returns the type's annotation for the specified type if
+     * such an annotation is present, else {@code null}.  The
+     * annotation has to be directly present on this
+     * element.
+     *
+     * <p> The annotation returned by this method could contain an element
+     * whose value is of type {@code Class}.
+     * This value cannot be returned directly:  information necessary to
+     * locate and load a class (such as the class loader to use) is
+     * not available, and the class might not be loadable at all.
+     * Attempting to read a {@code Class} object by invoking the relevant
+     * method on the returned annotation
+     * will result in a {@link MirroredTypeException},
+     * from which the corresponding {@link TypeMirror} may be extracted.
+     * Similarly, attempting to read a {@code Class[]}-valued element
+     * will result in a {@link MirroredTypesException}.
+     *
+     * <blockquote>
+     * <i>Note:</i> This method is unlike others in this and related
+     * interfaces.  It operates on runtime reflective information &mdash;
+     * representations of annotation types currently loaded into the
+     * VM &mdash; rather than on the representations defined by and used
+     * throughout these interfaces.  Consequently, calling methods on
+     * the returned annotation object can throw many of the exceptions
+     * that can be thrown when calling methods on an annotation object
+     * returned by core reflection.  This method is intended for
+     * callers that are written to operate on a known, fixed set of
+     * annotation types.
+     * </blockquote>
+     *
+     * @param <A>  the annotation type
+     * @param type  the targetted type
+     * @param annotationType  the {@code Class} object corresponding to
+     *          the annotation type
+     * @return the type's annotation for the specified annotation
+     *         type if present on the type, else {@code null}
+     *
+     * @see #getAnnotationMirrors()
+     * @see EnumConstantNotPresentException
+     * @see AnnotationTypeMismatchException
+     * @see IncompleteAnnotationException
+     * @see MirroredTypeException
+     * @see MirroredTypesException
+     */
+    <A extends Annotation> A typeAnnotationOf(TypeMirror type, Class<A> annotationType);
+
 }