1/* 2 * Copyright (C) 2011 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 17package libcore.java.lang.reflect; 18 19import java.lang.annotation.Annotation; 20import java.lang.annotation.Inherited; 21import java.lang.annotation.Retention; 22import java.lang.annotation.RetentionPolicy; 23import java.lang.reflect.AnnotatedElement; 24import java.lang.reflect.Constructor; 25import java.lang.reflect.Field; 26import java.lang.reflect.Method; 27import java.util.Arrays; 28import java.util.HashSet; 29import java.util.Set; 30import junit.framework.TestCase; 31 32public final class AnnotationsTest extends TestCase { 33 34 public void testClassDirectAnnotations() { 35 assertAnnotatedElement(Type.class, AnnotationA.class, AnnotationB.class); 36 } 37 38 public void testClassInheritedAnnotations() { 39 assertAnnotatedElement(ExtendsType.class, AnnotationB.class); 40 } 41 42 public void testConstructorAnnotations() throws Exception { 43 Constructor<Type> constructor = Type.class.getConstructor(); 44 assertAnnotatedElement(constructor, AnnotationA.class, AnnotationC.class); 45 } 46 47 public void testFieldAnnotations() throws Exception { 48 Field field = Type.class.getField("field"); 49 assertAnnotatedElement(field, AnnotationA.class, AnnotationD.class); 50 } 51 52 public void testMethodAnnotations() throws Exception { 53 Method method = Type.class.getMethod("method", String.class, String.class); 54 assertAnnotatedElement(method, AnnotationB.class, AnnotationC.class); 55 } 56 57 public void testParameterAnnotations() throws Exception { 58 Method method = Type.class.getMethod("method", String.class, String.class); 59 Annotation[][] parameterAnnotations = method.getParameterAnnotations(); 60 assertEquals(2, parameterAnnotations.length); 61 assertEquals(set(AnnotationB.class, AnnotationD.class), 62 annotationsToTypes(parameterAnnotations[0])); 63 assertEquals(set(AnnotationC.class, AnnotationD.class), 64 annotationsToTypes(parameterAnnotations[1])); 65 } 66 67 @Retention(RetentionPolicy.RUNTIME) 68 public @interface AnnotationA {} 69 70 @Inherited 71 @Retention(RetentionPolicy.RUNTIME) 72 public @interface AnnotationB {} 73 74 @Retention(RetentionPolicy.RUNTIME) 75 public @interface AnnotationC {} 76 77 @Retention(RetentionPolicy.RUNTIME) 78 public @interface AnnotationD {} 79 80 @AnnotationA @AnnotationB 81 public static class Type { 82 @AnnotationA @AnnotationC public Type() {} 83 @AnnotationA @AnnotationD public String field; 84 @AnnotationB @AnnotationC public void method(@AnnotationB @AnnotationD String parameter1, 85 @AnnotationC @AnnotationD String parameter2) {} 86 } 87 88 public static class ExtendsType extends Type {} 89 90 91 private void assertAnnotatedElement( 92 AnnotatedElement element, Class<? extends Annotation>... expectedAnnotations) { 93 Set<Class<? extends Annotation>> actualTypes = annotationsToTypes(element.getAnnotations()); 94 Set<Class<? extends Annotation>> expectedTypes = set(expectedAnnotations); 95 assertEquals(expectedTypes, actualTypes); 96 97 // getAnnotations() should be consistent with isAnnotationPresent() and getAnnotation() 98 assertPresent(expectedTypes.contains(AnnotationA.class), element, AnnotationA.class); 99 assertPresent(expectedTypes.contains(AnnotationB.class), element, AnnotationB.class); 100 assertPresent(expectedTypes.contains(AnnotationC.class), element, AnnotationC.class); 101 102 try { 103 element.isAnnotationPresent(null); 104 fail(); 105 } catch (NullPointerException expected) { 106 } 107 108 try { 109 element.getAnnotation(null); 110 fail(); 111 } catch (NullPointerException expected) { 112 } 113 } 114 115 private Set<Class<? extends Annotation>> annotationsToTypes(Annotation[] annotations) { 116 Set<Class<? extends Annotation>> result = new HashSet<Class<? extends Annotation>>(); 117 for (Annotation annotation : annotations) { 118 result.add(annotation.annotationType()); 119 } 120 return result; 121 } 122 123 private void assertPresent(boolean present, AnnotatedElement element, 124 Class<? extends Annotation> annotation) { 125 if (present) { 126 assertNotNull(element.getAnnotation(annotation)); 127 assertTrue(element.isAnnotationPresent(annotation)); 128 } else { 129 assertNull(element.getAnnotation(annotation)); 130 assertFalse(element.isAnnotationPresent(annotation)); 131 } 132 } 133 134 private <T> Set<T> set(T... instances) { 135 return new HashSet<T>(Arrays.asList(instances)); 136 } 137} 138