1/*
2 * Copyright (c) 2012, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug     7154390 8005712 8007278 8004912
27 * @summary Unit test for repeated annotation reflection
28 *
29 * @compile RepeatedUnitTest.java subpackage/package-info.java subpackage/Container.java subpackage/Containee.java subpackage/NonRepeated.java subpackage/InheritedContainee.java subpackage/InheritedContainer.java subpackage/InheritedNonRepeated.java
30 * @run main RepeatedUnitTest
31 */
32
33import subpackage.*;
34
35import java.lang.annotation.*;
36import java.lang.reflect.*;
37import java.util.*;
38
39public class RepeatedUnitTest {
40    public static void main(String[] args) throws Exception {
41        // PACKAGE ANNOTATIONS
42        Class c = Class.forName("subpackage.NonRepeated"); // force package "subpackage" load
43        Package p = Package.getPackage("subpackage");
44        packageNonRepeated(p);
45        packageRepeated(p);
46        packageContainer(p);
47
48        // INHERITED/NON-INHERITED ON CLASS
49        inheritedMe1();
50        inheritedMe2();
51        inheritedMe3();
52        inheritedMe4();
53
54        inheritedMe5();    // ContainerOnSuperSingleOnSub
55        inheritedMe6();    // RepeatableOnSuperSingleOnSub
56        inheritedMe7();    // SingleAnnoOnSuperContainerOnSub
57        inheritedMe8();    // SingleOnSuperRepeatableOnSub
58
59
60        // CONSTRUCTOR
61        checkMultiplier(Me1.class.getConstructor(new Class[0]), 10);
62
63        // FIELD
64        checkMultiplier(Me1.class.getField("foo"), 1);
65
66        // METHOD
67        checkMultiplier(Me1.class.getDeclaredMethod("mee", (Class<?>[])null), 100);
68
69        // INNER CLASS
70        checkMultiplier(Me1.MiniMee.class, 1000);
71
72        // ENUM ELEMENT
73        checkMultiplier(Me1.E.class.getField("EE"), 10000);
74
75        // ENUM
76        checkMultiplier(Me1.E.class, 100000);
77    }
78
79    static void packageNonRepeated(AnnotatedElement e) {
80        NonRepeated nr = e.getAnnotation(NonRepeated.class);
81        check(nr.value() == 10);
82
83        check(1 == countAnnotation(e, NonRepeated.class));
84
85        nr = e.getAnnotationsByType(NonRepeated.class)[0];
86        check(nr.value() == 10);
87
88        check(1 == containsAnnotationOfType(e.getAnnotations(), NonRepeated.class));
89    }
90
91    static void packageRepeated(AnnotatedElement e) {
92        Containee c = e.getAnnotation(Containee.class);
93        check(c == null);
94        check(2 == countAnnotation(e, Containee.class));
95
96        c = e.getAnnotationsByType(Containee.class)[0];
97        check(c.value() == 1);
98        c = e.getAnnotationsByType(Containee.class)[1];
99        check(c.value() == 2);
100
101        check(0 == containsAnnotationOfType(e.getAnnotations(), Containee.class));
102    }
103
104    static void packageContainer(AnnotatedElement e) {
105        Container cr = e.getAnnotation(Container.class);
106        check(null != cr);
107        check(1 == containsAnnotationOfType(e.getAnnotationsByType(Container.class), Container.class));
108        check(1 == countAnnotation(e, Container.class));
109    }
110
111    static void inheritedMe1() {
112        AnnotatedElement e = Me1.class;
113        check(null == e.getAnnotation(NonRepeated.class));
114        check(e.getAnnotation(InheritedNonRepeated.class).value() == 20);
115        check(0 == countAnnotation(e, Containee.class));
116        check(4 == countAnnotation(e, InheritedContainee.class));
117        check(0 == countAnnotation(e, Container.class));
118        check(1 == countAnnotation(e, InheritedContainer.class));
119    }
120
121    static void inheritedMe2() {
122        AnnotatedElement e = Me2.class;
123        check(e.getAnnotation(NonRepeated.class).value() == 100);
124        check(e.getAnnotation(InheritedNonRepeated.class).value() == 200);
125        check(4 == countAnnotation(e, Containee.class));
126        check(4 == countAnnotation(e, InheritedContainee.class));
127        check(1 == countAnnotation(e, Container.class));
128        check(1 == countAnnotation(e, InheritedContainer.class));
129        check(1 == countAnnotation(e, NonRepeated.class));
130        check(1 == countAnnotation(e, InheritedNonRepeated.class));
131
132        check(e.getAnnotationsByType(Containee.class)[2].value() == 300);
133        check(e.getAnnotationsByType(InheritedContainee.class)[2].value() == 300);
134        check(e.getAnnotationsByType(InheritedNonRepeated.class)[0].value() == 200);
135        check(e.getAnnotationsByType(NonRepeated.class)[0].value() == 100);
136    }
137
138    static void inheritedMe3() {
139        AnnotatedElement e = Me3.class;
140        check(null == e.getAnnotation(NonRepeated.class));
141
142        check(0 == countAnnotation(e, Containee.class));
143        check(4 == countAnnotation(e, InheritedContainee.class));
144        check(0 == countAnnotation(e, Container.class));
145        check(1 == countAnnotation(e, InheritedContainer.class));
146
147        check(e.getAnnotationsByType(InheritedContainee.class)[2].value() == 350);
148        check(e.getAnnotationsByType(InheritedNonRepeated.class)[0].value() == 15);
149    }
150
151    static void inheritedMe4() {
152        AnnotatedElement e = Me4.class;
153        check(e.getAnnotation(NonRepeated.class).value() == 1000);
154        check(e.getAnnotation(InheritedNonRepeated.class).value() == 2000);
155        check(4 == countAnnotation(e, Containee.class));
156        check(4 == countAnnotation(e, InheritedContainee.class));
157        check(1 == countAnnotation(e, Container.class));
158        check(1 == countAnnotation(e, InheritedContainer.class));
159        check(1 == countAnnotation(e, NonRepeated.class));
160        check(1 == countAnnotation(e, InheritedNonRepeated.class));
161
162        check(e.getAnnotationsByType(Containee.class)[2].value() == 3000);
163        check(e.getAnnotationsByType(InheritedContainee.class)[2].value() == 3000);
164        check(e.getAnnotationsByType(InheritedNonRepeated.class)[0].value() == 2000);
165        check(e.getAnnotationsByType(NonRepeated.class)[0].value() == 1000);
166    }
167
168    static void inheritedMe5() {
169        AnnotatedElement e = Me5.class;
170        check(2 == e.getAnnotations().length);
171        check(1 == countAnnotation(e, InheritedContainee.class));
172    }
173
174    static void inheritedMe6() {
175        AnnotatedElement e = Me6.class;
176        check(2 == e.getAnnotations().length);
177        check(1 == countAnnotation(e, InheritedContainee.class));
178    }
179
180    static void inheritedMe7() {
181        AnnotatedElement e = Me7.class;
182        check(2 == e.getAnnotations().length);
183        check(2 == countAnnotation(e, InheritedContainee.class));
184    }
185
186    static void inheritedMe8() {
187        AnnotatedElement e = Me8.class;
188        check(2 == e.getAnnotations().length);
189        check(2 == countAnnotation(e, InheritedContainee.class));
190    }
191
192    static void checkMultiplier(AnnotatedElement e, int m) {
193        // Basic sanity of non-repeating getAnnotation(Class)
194        check(e.getAnnotation(NonRepeated.class).value() == 5 * m);
195
196        // Check count of annotations returned from getAnnotationsByType(Class)
197        check(4 == countAnnotation(e, Containee.class));
198        check(1 == countAnnotation(e, Container.class));
199        check(1 == countAnnotation(e, NonRepeated.class));
200
201        // Check contents of array returned from getAnnotationsByType(Class)
202        check(e.getAnnotationsByType(Containee.class)[2].value() == 3 * m);
203        check(e.getAnnotationsByType(NonRepeated.class)[0].value() == 5 * m);
204
205        // Check getAnnotation(Class)
206        check(e.getAnnotation(Containee.class) == null);
207        check(e.getAnnotation(Container.class) != null);
208
209        // Check count of annotations returned from getAnnotations()
210        check(0 == containsAnnotationOfType(e.getAnnotations(), Containee.class));
211        check(1 == containsAnnotationOfType(e.getAnnotations(), Container.class));
212        check(1 == containsAnnotationOfType(e.getAnnotations(), NonRepeated.class));
213    }
214
215    static void check(Boolean b) {
216        if (!b) throw new RuntimeException();
217    }
218
219    static int countAnnotation(AnnotatedElement e, Class<? extends Annotation> c) {
220        return containsAnnotationOfType(e.getAnnotationsByType(c), c);
221    }
222
223    static <A extends Annotation> int containsAnnotationOfType(A[] l, Class<? extends Annotation> a) {
224        int count = 0;
225        for (Annotation an : l) {
226            if (an.annotationType().equals(a))
227                count++;
228        }
229        return count;
230    }
231}
232
233@NonRepeated @InheritedNonRepeated
234@InheritedContainee(1) @InheritedContainee(2) @InheritedContainee(3) @InheritedContainee(4)
235@Containee(1) @Containee(2) @Containee(3) @Containee(4)
236class Grandma {}
237
238class Mother extends Grandma {}
239
240@NonRepeated(5) @InheritedNonRepeated(15)
241@InheritedContainee(150) @InheritedContainee(250) @InheritedContainee(350) @InheritedContainee(450)
242@Containee(150) @Containee(250) @Containee(350) @Containee(450)
243class Father extends Grandma {}
244
245class Me1 extends Mother {
246
247    @NonRepeated(5)
248    @Containee(1) @Containee(2) @Containee(3) @Containee(4)
249    public String foo = "";
250
251    @NonRepeated(50)
252    @Containee(10) @Containee(20) @Containee(30) @Containee(40)
253    public Me1() {
254    }
255
256    @NonRepeated(500)
257    @Containee(100) @Containee(200) @Containee(300) @Containee(400)
258    public void mee() {
259    }
260
261    @NonRepeated(5000)
262    @Containee(1000) @Containee(2000) @Containee(3000) @Containee(4000)
263    public class MiniMee {}
264
265    @NonRepeated(500000)
266    @Containee(100000) @Containee(200000) @Containee(300000) @Containee(400000)
267    public enum E {
268        @NonRepeated(50000)
269        @Containee(10000) @Containee(20000) @Containee(30000) @Containee(40000)
270        EE(),
271    }
272}
273
274@NonRepeated(100) @InheritedNonRepeated(200)
275@InheritedContainee(100) @InheritedContainee(200) @InheritedContainee(300) @InheritedContainee(400)
276@Containee(100) @Containee(200) @Containee(300) @Containee(400)
277class Me2 extends Mother {}
278
279class Me3 extends Father {}
280
281@NonRepeated(1000) @InheritedNonRepeated(2000)
282@InheritedContainee(1000) @InheritedContainee(2000) @InheritedContainee(3000) @InheritedContainee(4000)
283@Containee(1000) @Containee(2000) @Containee(3000) @Containee(4000)
284class Me4 extends Father {}
285
286
287@InheritedContainer({@InheritedContainee(1), @InheritedContainee(2)})
288class SuperOf5 {}
289
290@InheritedContainee(3)
291class Me5 extends SuperOf5{}
292
293
294@InheritedContainee(1) @InheritedContainee(2)
295class SuperOf6 {}
296
297@InheritedContainee(3)
298class Me6 extends SuperOf6 {}
299
300
301@InheritedContainee(1)
302class SuperOf7 {}
303
304@InheritedContainer({@InheritedContainee(2), @InheritedContainee(3)})
305class Me7 extends SuperOf7 {}
306
307
308@InheritedContainee(1)
309class SuperOf8 {}
310
311@InheritedContainee(2) @InheritedContainee(3)
312class Me8 extends SuperOf8 {}
313