1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package tests.api.java.lang.reflect;
19
20import java.lang.annotation.Annotation;
21import java.lang.annotation.ElementType;
22import java.lang.annotation.Inherited;
23import java.lang.annotation.Retention;
24import java.lang.annotation.RetentionPolicy;
25import java.lang.annotation.Target;
26import java.lang.reflect.AccessibleObject;
27import java.lang.reflect.Modifier;
28import java.util.HashSet;
29import java.util.Set;
30
31public class AccessibleObjectTest extends junit.framework.TestCase {
32
33    public class TestClass {
34        public Object aField;
35
36        @InheritedRuntime
37        public void annotatedMethod(){}
38    }
39
40    public class SubTestClass extends TestClass{
41        @AnnotationRuntime0
42        @AnnotationRuntime1
43        @AnnotationClass0
44        @AnnotationSource0
45        public void annotatedMethod(){}
46    }
47
48
49    @Retention(RetentionPolicy.RUNTIME)
50    @Target( {ElementType.METHOD})
51    static @interface AnnotationRuntime0 {
52    }
53
54    @Retention(RetentionPolicy.RUNTIME)
55    @Target( { ElementType.METHOD})
56    static @interface AnnotationRuntime1 {
57    }
58
59    @Retention(RetentionPolicy.CLASS)
60    @Target( { ElementType.METHOD})
61    static @interface AnnotationClass0 {
62    }
63
64    @Retention(RetentionPolicy.SOURCE)
65    @Target( {ElementType.METHOD})
66    static @interface AnnotationSource0 {
67    }
68
69    @Inherited
70    @Retention(RetentionPolicy.RUNTIME)
71    @Target( {ElementType.METHOD})
72    static @interface InheritedRuntime {
73    }
74
75    //used for constructor test
76    private static class MyAccessibleObject extends AccessibleObject{
77        public MyAccessibleObject() {
78            super();
79        }
80    }
81
82    /**
83     * java.lang.reflect.AccessibleObject#AccessibleObject()
84     */
85    public void test_Constructor() {
86        assertNotNull(new MyAccessibleObject());
87    }
88
89    /**
90     * java.lang.reflect.AccessibleObject#isAccessible()
91     */
92    public void test_isAccessible() {
93        // Test for method boolean
94        // java.lang.reflect.AccessibleObject.isAccessible()
95        try {
96            AccessibleObject ao = TestClass.class.getField("aField");
97            ao.setAccessible(true);
98            assertTrue("Returned false to isAccessible", ao.isAccessible());
99            ao.setAccessible(false);
100            assertTrue("Returned true to isAccessible", !ao.isAccessible());
101        } catch (Exception e) {
102            fail("Exception during test : " + e.getMessage());
103        }
104    }
105
106    /**
107     * java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[],
108     *        boolean)
109     */
110    public void test_setAccessible$Ljava_lang_reflect_AccessibleObjectZ() {
111        try {
112            AccessibleObject ao = TestClass.class.getField("aField");
113            AccessibleObject[] aoa = new AccessibleObject[] { ao };
114            AccessibleObject.setAccessible(aoa, true);
115            assertTrue("Returned false to isAccessible", ao.isAccessible());
116            AccessibleObject.setAccessible(aoa, false);
117            assertTrue("Returned true to isAccessible", !ao.isAccessible());
118        } catch (Exception e) {
119            fail("Exception during test : " + e.getMessage());
120        }
121    }
122
123    /**
124     * java.lang.reflect.AccessibleObject#setAccessible(boolean)
125     */
126    public void test_setAccessible() throws Exception {
127        AccessibleObject ao = TestClass.class.getField("aField");
128        ao.setAccessible(true);
129        assertTrue("Returned false to isAccessible", ao.isAccessible());
130        ao.setAccessible(false);
131        assertFalse("Returned true to isAccessible", ao.isAccessible());
132    }
133
134    public void test_getAnnotation() throws Exception{
135        AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
136        //test error case
137        boolean npeThrown = false;
138        try {
139          ao.getAnnotation(null);
140          fail("NPE expected");
141        } catch (NullPointerException e) {
142            npeThrown = true;
143        }
144        assertTrue("NPE expected", npeThrown);
145
146        //test inherited on method has no effect
147        InheritedRuntime ir = ao.getAnnotation(InheritedRuntime.class);
148        assertNull("Inherited Annotations should have no effect", ir);
149
150        //test ordinary runtime annotation
151        AnnotationRuntime0 rt0 = ao.getAnnotation(AnnotationRuntime0.class);
152        assertNotNull("AnnotationRuntime0 instance expected", rt0);
153    }
154
155     public void test_getAnnotations() throws Exception {
156        AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
157        Annotation[] annotations = ao.getAnnotations();
158        assertEquals(2, annotations.length);
159
160        Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
161        ignoreOrder.add(annotations[0].annotationType());
162        ignoreOrder.add(annotations[1].annotationType());
163
164        assertTrue("Missing @AnnotationRuntime0",
165                ignoreOrder.contains(AnnotationRuntime0.class));
166        assertTrue("Missing @AnnotationRuntime1",
167                ignoreOrder.contains(AnnotationRuntime1.class));
168    }
169
170     public void test_getDeclaredAnnotations() throws Exception {
171        AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
172        Annotation[] annotations = ao.getDeclaredAnnotations();
173        assertEquals(2, annotations.length);
174
175        Set<Class<?>> ignoreOrder = new HashSet<Class<?>>();
176        ignoreOrder.add(annotations[0].annotationType());
177        ignoreOrder.add(annotations[1].annotationType());
178
179        assertTrue("Missing @AnnotationRuntime0",
180                ignoreOrder.contains(AnnotationRuntime0.class));
181        assertTrue("Missing @AnnotationRuntime1",
182                ignoreOrder.contains(AnnotationRuntime1.class));
183    }
184
185    public void test_isAnnotationPresent() throws Exception {
186        AccessibleObject ao = SubTestClass.class.getMethod("annotatedMethod");
187        assertTrue("Missing @AnnotationRuntime0",
188                ao.isAnnotationPresent(AnnotationRuntime0.class));
189        assertFalse("AnnotationSource0 should not be visible at runtime",
190                ao.isAnnotationPresent(AnnotationSource0.class));
191        boolean npeThrown = false;
192        try {
193          ao.isAnnotationPresent(null);
194          fail("NPE expected");
195        } catch (NullPointerException e) {
196            npeThrown = true;
197        }
198        assertTrue("NPE expected", npeThrown);
199    }
200
201
202    /**
203     * Sets up the fixture, for example, open a network connection. This method
204     * is called before a test is executed.
205     */
206    protected void setUp() {
207    }
208
209    /**
210     * Tears down the fixture, for example, close a network connection. This
211     * method is called after a test is executed.
212     */
213    protected void tearDown() {
214    }
215}
216