1 /*
2 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
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
128 // of the corresponding annotation types breaks infinite recursion.
129 if (annotationClass != Retention.class &&
130 annotationClass != Inherited.class) {
131 Retention ret = annotationClass.getAnnotation(Retention.class);
132 retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
133 inherited = annotationClass.isAnnotationPresent(Inherited.class);
134 }
135 }
136
137 /**
138 * Returns the type that must be returned by the invocation handler
139 * of a dynamic proxy in order to have the dynamic proxy return
140 * the specified type (which is assumed to be a legal member type
141 * for an annotation).
|
1 /*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
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
124 sun.misc.SharedSecrets.getJavaLangAccess().
125 setAnnotationType(annotationClass, this);
126
127 // Initialize retention, & inherited fields. Special treatment
128 // of the corresponding annotation types breaks infinite recursion.
129 if (annotationClass != Retention.class &&
130 annotationClass != Inherited.class) {
131 Retention ret = annotationClass.getAnnotation(Retention.class);
132 retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
133 inherited = annotationClass.isAnnotationPresent(Inherited.class);
134 }
135 }
136
137 /**
138 * Returns the type that must be returned by the invocation handler
139 * of a dynamic proxy in order to have the dynamic proxy return
140 * the specified type (which is assumed to be a legal member type
141 * for an annotation).
|