blob: 75e684557cf9987cd3e0c7250cc9c4fcb25ef4ba [file] [log] [blame]
Igor Murashkindf187e42016-02-01 11:43:26 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.lang.annotation.Annotation;
18import java.lang.reflect.Method;
19
20public class AnnotationTest extends AnnotationTestHelpers {
21 public static void testAnnotationsByType() {
22 System.out.println("==============================");
23 System.out.println("Class annotations by type:");
24 System.out.println("==============================");
25
26 // Print associated annotations:
27 // * A is directly present or repeatably present on an element E;
28 // * No annotation of A is directly/repeatably present on an element
29 // AND E is a class AND A's type is inheritable, AND A is associated with its superclass.
30 // (Looks through subtypes recursively only if there's 0 result at each level,
31 // and the annotation is @Inheritable).
32 printAnnotationsByType(Calendar.class, SingleUser.class);
33 printAnnotationsByType(Calendars.class, SingleUser.class);
34
35 printAnnotationsByType(Calendar.class, User.class);
36 printAnnotationsByType(Calendars.class, User.class);
37
38 printAnnotationsByType(Calendar.class, User2.class); // Enforce ordering 'z,x,y'
39 printAnnotationsByType(Calendars.class, User2.class);
40
41 // NOTE:
42 // Order of outer-most annotations Calendars[C,C],S vs C,Calendars[C,C] is unspecified.
43 // In particular it's the order of #getDeclaredAnnotations which is completely unmentioned.
44 // The only requirement for #getAnnotationsByType is to have same ordering as
45 // #getDeclaredAnnotations.
46 // (Calendars[] itself has to maintain value() order).
47 printAnnotationsByType(Calendar.class, UserComplex.class); // Cs(C,C),C collapses into C,C,C.
48 printAnnotationsByType(Calendars.class, UserComplex.class);
49
50 printAnnotationsByType(Calendar.class, UserSub.class);
51 printAnnotationsByType(Calendars.class, UserSub.class);
52
53 printAnnotationsByType(Calendar.class, UserSub2.class);
54 // The directly present "Calendar" annotation masks all the repeatably present
55 // "Calendar" annotations coming from User.
56 printAnnotationsByType(Calendars.class, UserSub2.class);
57 // Edge case: UserSub2 doesn't directly have a Calendars annotation,
58 // so it doesn't mask the "User" Calendars annotation.
59
60 System.out.println("-----------------------------");
61 System.out.println("-----------------------------");
62
63 }
64
65 public static void testDeclaredAnnotation() {
66 System.out.println("==============================");
67 System.out.println("Class declared annotation:");
68 System.out.println("==============================");
69
70 // Print directly present annotations:
71 //
72 // The element E has an annotation_item for it (accessible through an
73 // annotations_directory_item) corresponding to an annotation A,
74 // and A's type_idx must match that on the encoded_annotation (from the annotation_item).
75 // (Does not look through the subtypes recursively)
76 printDeclaredAnnotation(SingleUser.class, Calendar.class);
77 printDeclaredAnnotation(SingleUser.class, Calendars.class);
78
79 printDeclaredAnnotation(User.class, Calendar.class);
80 printDeclaredAnnotation(User.class, Calendars.class);
81
82 printDeclaredAnnotation(UserComplex.class, Calendar.class);
83 printDeclaredAnnotation(UserComplex.class, Calendars.class);
84
85 printDeclaredAnnotation(UserSub.class, Calendar.class);
86 printDeclaredAnnotation(UserSub.class, Calendars.class);
87
88 printDeclaredAnnotation(UserSub2.class, Calendar.class);
89 printDeclaredAnnotation(UserSub2.class, Calendars.class);
90
91 System.out.println("-----------------------------");
92 System.out.println("-----------------------------");
93 }
94
95 public static void testDeclaredAnnotationsByType() {
96 System.out.println("==============================");
97 System.out.println("Declared class annotations by type:");
98 System.out.println("==============================");
99
100 // A is directly present or repeatably present on an element E;
101 // -- (does not do any recursion for classes regardless of @Inherited)
102 printDeclaredAnnotationsByType(Calendar.class, SingleUser.class);
103 printDeclaredAnnotationsByType(Calendars.class, SingleUser.class);
104
105 printDeclaredAnnotationsByType(Calendar.class, User.class);
106 printDeclaredAnnotationsByType(Calendars.class, User.class);
107
108 printDeclaredAnnotationsByType(Calendar.class, User2.class); // Enforce ordering 'z,x,y'
109 printDeclaredAnnotationsByType(Calendars.class, User2.class);
110
111 printDeclaredAnnotationsByType(Calendar.class, UserComplex.class);
112 printDeclaredAnnotationsByType(Calendars.class, UserComplex.class);
113
114 printDeclaredAnnotationsByType(Calendar.class, UserSub.class);
115 printDeclaredAnnotationsByType(Calendars.class, UserSub.class);
116
117 printDeclaredAnnotationsByType(Calendar.class, UserSub2.class);
118 // The directly present "Calendar" annotation masks all the repeatably present "Calendar"
119 // annotations coming from User.
120 printDeclaredAnnotationsByType(Calendars.class, UserSub2.class);
121 // Edge case: UserSub2 doesn't directly have a Calendars annotation,
122 // so it doesn't mask the "User" Calendars annotation.
123
124 System.out.println("-----------------------------");
125 System.out.println("-----------------------------");
126 }
127
128 // Print the annotation "annotationClass" that is associated with an element denoted by
129 // "annotationUseClass."
130 private static <A extends Annotation> void printAnnotationsByType(Class<A> annotationClass,
131 Class<?> annotationUseClass) {
132 A[] annotationsByType = annotationUseClass.getAnnotationsByType(annotationClass);
133
134 String msg = "Annotations by type, defined by class "
135 + annotationUseClass.getName() + " with annotation " + annotationClass.getName() + ": "
136 + asString(annotationsByType);
137
138
139 System.out.println(msg);
140 }
141
142 private static <A extends Annotation> void printDeclaredAnnotation(Class<?> annotationUseClass,
143 Class<A> annotationDefClass) {
144 A anno = annotationUseClass.getDeclaredAnnotation(annotationDefClass);
145
146 String msg = asString(anno);
147
148 System.out.println("Declared annotations by class " + annotationUseClass
149 + ", annotation " + annotationDefClass + ": " + msg);
150 }
151
152 // Print the annotation "annotationClass" that is directly/indirectly present with an element
153 // denoted by "annotationUseClass."
154 private static <A extends Annotation> void printDeclaredAnnotationsByType(
155 Class<A> annotationClass, Class<?> annotationUseClass) {
156 A[] annotationsByType = annotationUseClass.getDeclaredAnnotationsByType(annotationClass);
157
158 String msg = "Declared annnotations by type, defined by class " + annotationUseClass.getName()
159 + " with annotation " + annotationClass.getName() + ": "
160 + asString(annotationsByType);
161
162 System.out.println(msg);
163 }
164
165 public static void testMethodAnnotationsByType() {
166 System.out.println("==============================");
167 System.out.println("Method annotations by type:");
168 System.out.println("==============================");
169
170 // Print associated annotations:
171 // * A is directly present or repeatably present on an element E;
172 // * No annotation of A is directly/repeatably present on an element AND E is a class
173 // AND A's type is inheritable, AND A is associated with its superclass.
174 // (Looks through subtypes recursively only if there's 0 result at each level,
175 // and the annotation is @Inheritable).
176 printMethodAnnotationsByType(Calendar.class, "singleUser", AnnotationTestFixture.class);
177 printMethodAnnotationsByType(Calendars.class, "singleUser", AnnotationTestFixture.class);
178
179 printMethodAnnotationsByType(Calendar.class, "user", AnnotationTestFixture.class);
180 printMethodAnnotationsByType(Calendars.class, "user", AnnotationTestFixture.class);
181
182 printMethodAnnotationsByType(Calendar.class, "user2", AnnotationTestFixture.class);
183 printMethodAnnotationsByType(Calendars.class, "user2", AnnotationTestFixture.class);
184
185 printMethodAnnotationsByType(Calendar.class, "userComplex", AnnotationTestFixture.class);
186 printMethodAnnotationsByType(Calendars.class, "userComplex", AnnotationTestFixture.class);
187
188 System.out.println("-----------------------------");
189 System.out.println("-----------------------------");
190 }
191
192 // Print the annotation "annotationClass" that is associated with an element denoted by
193 // "annotationUseClass" method methodName.
194 private static <A extends Annotation> void printMethodAnnotationsByType(Class<A> annotationClass,
195 String methodName, Class<?> annotationUseClass) {
196 Method m = null;
197 try {
198 m = annotationUseClass.getDeclaredMethod(methodName);
199 } catch (Throwable t) {
200 throw new AssertionError(t);
201 }
202 A[] annotationsByType = m.getAnnotationsByType(annotationClass);
203
204 String msg = "Annotations by type, defined by method " + m.getName() + " with annotation " +
205 annotationClass.getName() + ": " +
206 asString(annotationsByType);
207
208 System.out.println(msg);
209 }
210
211 public static void testMethodDeclaredAnnotations() {
212 System.out.println("==============================");
213 System.out.println("Declared method annotations:");
214 System.out.println("==============================");
215
216 printMethodDeclaredAnnotation(Calendar.class, "singleUser", AnnotationTestFixture.class);
217 printMethodDeclaredAnnotation(Calendars.class, "singleUser", AnnotationTestFixture.class);
218
219 printMethodDeclaredAnnotation(Calendar.class, "user", AnnotationTestFixture.class);
220 printMethodDeclaredAnnotation(Calendars.class, "user", AnnotationTestFixture.class);
221
222 printMethodDeclaredAnnotation(Calendar.class, "user2", AnnotationTestFixture.class);
223 printMethodDeclaredAnnotation(Calendars.class, "user2", AnnotationTestFixture.class);
224
225 printMethodDeclaredAnnotation(Calendar.class, "userComplex", AnnotationTestFixture.class);
226 printMethodDeclaredAnnotation(Calendars.class, "userComplex", AnnotationTestFixture.class);
227
228 System.out.println("-----------------------------");
229 System.out.println("-----------------------------");
230 }
231
232 // Print the annotation "annotationClass" that is associated with an element denoted by
233 // methodName in annotationUseClass.
234 private static <A extends Annotation> void printMethodDeclaredAnnotation(Class<A> annotationClass,
235 String methodName, Class<?> annotationUseClass) {
236 Method m = null;
237 try {
238 m = annotationUseClass.getDeclaredMethod(methodName);
239 } catch (Throwable t) {
240 throw new AssertionError(t);
241 }
242 Annotation annotationsByType = m.getDeclaredAnnotation(annotationClass);
243
244 String msg = "Annotations declared by method " + m.getName() + " with annotation "
245 + annotationClass.getName() + ": "
246 + asString(annotationsByType);
247
248 System.out.println(msg);
249 }
250
251 public static void testMethodDeclaredAnnotationsByType() {
252 System.out.println("==============================");
253 System.out.println("Declared method annotations by type:");
254 System.out.println("==============================");
255
256 printMethodDeclaredAnnotationByType(Calendar.class, "singleUser", AnnotationTestFixture.class);
257 printMethodDeclaredAnnotationByType(Calendars.class, "singleUser", AnnotationTestFixture.class);
258
259 printMethodDeclaredAnnotationByType(Calendar.class, "user", AnnotationTestFixture.class);
260 printMethodDeclaredAnnotationByType(Calendars.class, "user", AnnotationTestFixture.class);
261
262 printMethodDeclaredAnnotationByType(Calendar.class, "user2", AnnotationTestFixture.class);
263 printMethodDeclaredAnnotationByType(Calendars.class, "user2", AnnotationTestFixture.class);
264
265 printMethodDeclaredAnnotationByType(Calendar.class, "userComplex", AnnotationTestFixture.class);
266 printMethodDeclaredAnnotationByType(Calendars.class, "userComplex",
267 AnnotationTestFixture.class);
268
269 System.out.println("-----------------------------");
270 System.out.println("-----------------------------");
271 }
272
273 // Print the annotation "annotationClass" that is associated with an element denoted by
274 // methodName in annotationUseClass.
275 private static <A extends Annotation> void printMethodDeclaredAnnotationByType(
276 Class<A> annotationClass, String methodName, Class<?> annotationUseClass) {
277 Method m = null;
278 try {
279 m = annotationUseClass.getDeclaredMethod(methodName);
280 } catch (Throwable t) {
281 throw new AssertionError(t);
282 }
283 A[] annotationsByType = m.getDeclaredAnnotationsByType(annotationClass);
284
285 String msg = "Annotations by type, defined by method " + m.getName() + " with annotation "
286 + annotationClass.getName() + ": "
287 + asString(annotationsByType);
288
289 System.out.println(msg);
290 }
291}