28 import java.lang.annotation.*; 29 import java.lang.reflect.*; 30 import java.util.*; 31 import java.security.AccessController; 32 import java.security.PrivilegedAction; 33 34 /** 35 * Represents an annotation type at run time. Used to type-check annotations 36 * and apply member defaults. 37 * 38 * @author Josh Bloch 39 * @since 1.5 40 */ 41 public class AnnotationType { 42 /** 43 * Member name -> type mapping. Note that primitive types 44 * are represented by the class objects for the corresponding wrapper 45 * types. This matches the return value that must be used for a 46 * dynamic proxy, allowing for a simple isInstance test. 47 */ 48 private final Map<String, Class<?>> memberTypes = new HashMap<String,Class<?>>(); 49 50 /** 51 * Member name -> default value mapping. 52 */ 53 private final Map<String, Object> memberDefaults = 54 new HashMap<String, Object>(); 55 56 /** 57 * Member name -> Method object mapping. This (and its assoicated 58 * accessor) are used only to generate AnnotationTypeMismatchExceptions. 59 */ 60 private final Map<String, Method> members = new HashMap<String, Method>(); 61 62 /** 63 * The retention policy for this annotation type. 64 */ 65 private RetentionPolicy retention = RetentionPolicy.RUNTIME;; 66 67 /** 68 * Whether this annotation type is inherited. 69 */ 70 private boolean inherited = false; 71 72 /** 73 * Returns an AnnotationType instance for the specified annotation type. 74 * 75 * @throw IllegalArgumentException if the specified class object for 76 * does not represent a valid annotation type 77 */ 78 public static synchronized AnnotationType getInstance( 79 Class<? extends Annotation> annotationClass) 80 { 88 89 /** 90 * Sole constructor. 91 * 92 * @param annotationClass the class object for the annotation type 93 * @throw IllegalArgumentException if the specified class object for 94 * does not represent a valid annotation type 95 */ 96 private AnnotationType(final Class<? extends Annotation> annotationClass) { 97 if (!annotationClass.isAnnotation()) 98 throw new IllegalArgumentException("Not an annotation type"); 99 100 Method[] methods = 101 AccessController.doPrivileged(new PrivilegedAction<Method[]>() { 102 public Method[] run() { 103 // Initialize memberTypes and defaultValues 104 return annotationClass.getDeclaredMethods(); 105 } 106 }); 107 108 109 for (Method method : methods) { 110 if (method.getParameterTypes().length != 0) 111 throw new IllegalArgumentException(method + " has params"); 112 String name = method.getName(); 113 Class<?> type = method.getReturnType(); 114 memberTypes.put(name, invocationHandlerReturnType(type)); 115 members.put(name, method); 116 117 Object defaultValue = method.getDefaultValue(); 118 if (defaultValue != null) 119 memberDefaults.put(name, defaultValue); 120 121 members.put(name, method); 122 } 123 124 sun.misc.SharedSecrets.getJavaLangAccess(). 125 setAnnotationType(annotationClass, this); 126 127 // Initialize retention, & inherited fields. Special treatment | 28 import java.lang.annotation.*; 29 import java.lang.reflect.*; 30 import java.util.*; 31 import java.security.AccessController; 32 import java.security.PrivilegedAction; 33 34 /** 35 * Represents an annotation type at run time. Used to type-check annotations 36 * and apply member defaults. 37 * 38 * @author Josh Bloch 39 * @since 1.5 40 */ 41 public class AnnotationType { 42 /** 43 * Member name -> type mapping. Note that primitive types 44 * are represented by the class objects for the corresponding wrapper 45 * types. This matches the return value that must be used for a 46 * dynamic proxy, allowing for a simple isInstance test. 47 */ 48 private final Map<String, Class<?>> memberTypes; 49 50 /** 51 * Member name -> default value mapping. 52 */ 53 private final Map<String, Object> memberDefaults; 54 55 /** 56 * Member name -> Method object mapping. This (and its assoicated 57 * accessor) are used only to generate AnnotationTypeMismatchExceptions. 58 */ 59 private final Map<String, Method> members; 60 61 /** 62 * The retention policy for this annotation type. 63 */ 64 private RetentionPolicy retention = RetentionPolicy.RUNTIME;; 65 66 /** 67 * Whether this annotation type is inherited. 68 */ 69 private boolean inherited = false; 70 71 /** 72 * Returns an AnnotationType instance for the specified annotation type. 73 * 74 * @throw IllegalArgumentException if the specified class object for 75 * does not represent a valid annotation type 76 */ 77 public static synchronized AnnotationType getInstance( 78 Class<? extends Annotation> annotationClass) 79 { 87 88 /** 89 * Sole constructor. 90 * 91 * @param annotationClass the class object for the annotation type 92 * @throw IllegalArgumentException if the specified class object for 93 * does not represent a valid annotation type 94 */ 95 private AnnotationType(final Class<? extends Annotation> annotationClass) { 96 if (!annotationClass.isAnnotation()) 97 throw new IllegalArgumentException("Not an annotation type"); 98 99 Method[] methods = 100 AccessController.doPrivileged(new PrivilegedAction<Method[]>() { 101 public Method[] run() { 102 // Initialize memberTypes and defaultValues 103 return annotationClass.getDeclaredMethods(); 104 } 105 }); 106 107 memberTypes = new HashMap<String,Class<?>>(methods.length+1, 1.0f); 108 memberDefaults = new HashMap<String, Object>(0); 109 members = new HashMap<String, Method>(methods.length+1, 1.0f); 110 111 for (Method method : methods) { 112 if (method.getParameterTypes().length != 0) 113 throw new IllegalArgumentException(method + " has params"); 114 String name = method.getName(); 115 Class<?> type = method.getReturnType(); 116 memberTypes.put(name, invocationHandlerReturnType(type)); 117 members.put(name, method); 118 119 Object defaultValue = method.getDefaultValue(); 120 if (defaultValue != null) 121 memberDefaults.put(name, defaultValue); 122 123 members.put(name, method); 124 } 125 126 sun.misc.SharedSecrets.getJavaLangAccess(). 127 setAnnotationType(annotationClass, this); 128 129 // Initialize retention, & inherited fields. Special treatment |