1 /* 2 * Copyright (c) 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 8005294 27 * @summary Check behavior of default methods of AnnotatedElement 28 * @author Joseph D. Darcy 29 */ 30 31 import java.lang.annotation.*; 32 import java.lang.reflect.*; 33 import java.util.*; 34 35 public class TestAnnotatedElementDefaults { 36 public static void main(String... args) throws SecurityException { 37 int failures = 0; 38 39 List<AnnotatedElement> annotatedElements = new ArrayList<>(); 40 annotatedElements.add(TestClass1Super.class); 41 annotatedElements.add(TestClass1.class); 42 for (Method method : TestClass1.class.getDeclaredMethods()) { 43 annotatedElements.add(method); 44 } 45 46 List<Class<? extends Annotation>> annotations = new ArrayList<>(); 47 annotations.add(Missing.class); 48 annotations.add(MissingRepeatable.class); 49 annotations.add(DirectlyPresent.class); 50 annotations.add(IndirectlyPresent.class); 51 annotations.add(IndirectlyPresentContainer.class); 52 annotations.add(DirectlyAndIndirectlyPresent.class); 53 annotations.add(DirectlyAndIndirectlyPresentContainer.class); 54 55 for (AnnotatedElement annotElement : annotatedElements) { 56 System.out.println(annotElement); 57 AnnotatedElementDelegate delegate = new AnnotatedElementDelegate(annotElement); 58 failures += testNullHandling(delegate); 59 for (Class<? extends Annotation> annotType : annotations) { 60 failures += AnnotatedElementDelegate.testDelegate(delegate, annotType); 61 } 62 } 63 64 if (failures > 0) 65 throw new RuntimeException(); 66 } 67 68 private static int testNullHandling(AnnotatedElementDelegate delegate) { 69 int failures = 0; 70 try { 71 Object result = delegate.getDeclaredAnnotationsByType(null); 72 failures++; 73 } catch (NullPointerException npe) { 74 ; // Expected 75 } 76 77 try { 78 Object result = delegate.getAnnotationsByType(null); 79 failures++; 80 } catch (NullPointerException npe) { 81 ; // Expected 82 } 83 84 try { 85 Object result = delegate.getDeclaredAnnotation(null); 86 failures++; 87 } catch (NullPointerException npe) { 88 ; // Expected 89 } 90 91 return failures; 92 } 93 94 } 95 96 // ----------------------------------------------------- 97 98 /* 99 * For annotation types including {null, PresentAnnotation, 100 * MissingAnnotation, RepeatableAnnotation, ...} the behavior of 101 * AnnotedElementDelegate.foo(arg) is compared for equality to 102 * baseAnnotatedElement.foo(arg). 103 104 * Consider annotation types 105 106 * @NonRepeatable 107 * @NonRepeatableInheritable 108 109 * Base annotated elements will include a Class object (where 110 * annotation inheritance can some input play) and a non-Class object. 111 112 */ 113 114 @AssociatedDirectOnSuperClass(123) 115 @AssociatedIndirectOnSuperClass(234) @AssociatedIndirectOnSuperClass(345) 116 class TestClass1Super {} 117 118 @DirectlyPresent(1) 119 @IndirectlyPresent(10) @IndirectlyPresent(11) 120 class TestClass1 extends TestClass1Super { 121 122 @DirectlyPresent(2) 123 @IndirectlyPresentContainer({@IndirectlyPresent(12)}) 124 @DirectlyAndIndirectlyPresentContainer({@DirectlyAndIndirectlyPresent(84), @DirectlyAndIndirectlyPresent(96)}) 125 public void foo() {return ;} 126 127 @IndirectlyPresentContainer({}) 128 @DirectlyAndIndirectlyPresentContainer({@DirectlyAndIndirectlyPresent(11), @DirectlyAndIndirectlyPresent(22)}) 129 @DirectlyAndIndirectlyPresent(33) 130 public void bar() {return ;} 131 } 132 133 // ----------------------------------------------------- 134 135 @Retention(RetentionPolicy.RUNTIME) 136 @interface DirectlyPresent { 137 int value(); 138 } 139 140 // ----------------------------------------------------- 141 142 @Retention(RetentionPolicy.RUNTIME) 143 @Repeatable(IndirectlyPresentContainer.class) 144 @interface IndirectlyPresent { 145 int value(); 146 } 147 148 @Retention(RetentionPolicy.RUNTIME) 149 @interface IndirectlyPresentContainer { 150 IndirectlyPresent[] value(); 151 } 152 153 // ----------------------------------------------------- 154 155 @Retention(RetentionPolicy.RUNTIME) 156 @Repeatable(DirectlyAndIndirectlyPresentContainer.class) 157 @interface DirectlyAndIndirectlyPresent { 158 int value(); 159 160 } 161 162 @Retention(RetentionPolicy.RUNTIME) 163 @interface DirectlyAndIndirectlyPresentContainer { 164 DirectlyAndIndirectlyPresent[] value(); 165 } 166 167 // ----------------------------------------------------- 168 169 @Retention(RetentionPolicy.RUNTIME) 170 @interface Missing { 171 int value(); 172 } 173 174 // ----------------------------------------------------- 175 176 @Retention(RetentionPolicy.RUNTIME) 177 @Repeatable(MissingRepeatableContainer.class) 178 @interface MissingRepeatable { 179 int value(); 180 } 181 182 @Retention(RetentionPolicy.RUNTIME) 183 @interface MissingRepeatableContainer { 184 MissingRepeatable[] value(); 185 } 186 187 // ----------------------------------------------------- 188 189 @Retention(RetentionPolicy.RUNTIME) 190 @Repeatable(AssociatedDirectOnSuperClassContainer.class) 191 @interface AssociatedDirectOnSuperClass { 192 int value(); 193 } 194 195 @Retention(RetentionPolicy.RUNTIME) 196 @interface AssociatedDirectOnSuperClassContainer { 197 AssociatedDirectOnSuperClass[] value(); 198 } 199 200 // ----------------------------------------------------- 201 202 @Retention(RetentionPolicy.RUNTIME) 203 @Repeatable(AssociatedIndirectOnSuperClassContainer.class) 204 @interface AssociatedIndirectOnSuperClass { 205 int value(); 206 } 207 208 @Retention(RetentionPolicy.RUNTIME) 209 @interface AssociatedIndirectOnSuperClassContainer { 210 AssociatedIndirectOnSuperClass[] value(); 211 } 212 213 // ----------------------------------------------------- 214 215 /** 216 * Helper class to ease calling the default methods of {@code 217 * AnnotatedElement} and comparing the results to other 218 * implementation. 219 */ 220 class AnnotatedElementDelegate implements AnnotatedElement { 221 private AnnotatedElement base; 222 223 public AnnotatedElementDelegate(AnnotatedElement base) { 224 Objects.requireNonNull(base); 225 this.base = base; 226 } 227 228 // // FIXME -- adjust once build / vm problems resolved 229 // @Override 230 // public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) { 231 // return base.getDeclaredAnnotationsByType(annotationClass); 232 // } 233 234 // Delegate to base implemenetation of AnnotatedElement methods 235 // without defaults. 236 @Override 237 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 238 return base.getAnnotation(annotationClass); 239 } 240 241 @Override 242 public Annotation[] getAnnotations() { 243 return base.getAnnotations(); 244 } 245 246 @Override 247 public Annotation[] getDeclaredAnnotations() { 248 return base.getDeclaredAnnotations(); 249 } 250 251 public AnnotatedElement getBase() { 252 return base; 253 } 254 255 static int testDelegate(AnnotatedElementDelegate delegate, 256 Class<? extends Annotation> annotationClass) { 257 int failures = 0; 258 AnnotatedElement base = delegate.getBase(); 259 260 // System.out.println("\tTesting " + delegate + "\ton\t" + annotationClass); 261 262 // <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) 263 if (!Objects.deepEquals(delegate.getDeclaredAnnotationsByType(annotationClass), 264 base.getDeclaredAnnotationsByType(annotationClass))) { 265 failures++; 266 System.err.printf("Equality failure on getDeclaredAnnotationsByType(%s) on %s)%n", 267 annotationClass, delegate); 268 } 269 270 // <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) 271 if (!Objects.deepEquals(delegate.getAnnotationsByType(annotationClass), 272 base.getAnnotationsByType(annotationClass))) { 273 failures++; 274 System.err.printf("Equality failure on getAnnotationsByType(%s) on %s)%n", 275 annotationClass, delegate); 276 } 277 278 // <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) 279 if (!Objects.equals(delegate.getDeclaredAnnotation(annotationClass), 280 base.getDeclaredAnnotation(annotationClass))) { 281 failures++; 282 System.err.printf("Equality failure on getDeclaredAnnotation(%s) on %s)%n", 283 annotationClass, delegate); 284 } 285 return failures; 286 } 287 }