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 /** 36 * For annotation type tokens including, null, DirectlyPresent.class, 37 * IndirectlyPresent.class, etc. the behavior of 38 * AnnotedElementDelegate.foo(arg) is compared for equality to 39 * baseAnnotatedElement.foo(arg) on various kinds of annotated 40 * elements. 41 */ 42 public class TestAnnotatedElementDefaults { 43 public static void main(String... args) throws SecurityException { 44 int failures = 0; 45 46 for (AnnotatedElement annotElement : elementsToTest()) { 47 System.out.println(annotElement); 48 AnnotatedElementDelegate delegate = new AnnotatedElementDelegate(annotElement); 49 failures += testNullHandling(delegate); 50 for (Class<? extends Annotation> annotType : annotationsToTest()) { 51 failures += AnnotatedElementDelegate.testDelegate(delegate, annotType); 52 } 53 } 54 55 if (failures > 0) { 56 System.err.printf("%d failures%n", failures); 57 throw new RuntimeException(); 58 } 59 } 60 61 private static List<AnnotatedElement> elementsToTest() { 62 List<AnnotatedElement> annotatedElements = new ArrayList<>(); 63 annotatedElements.add(TestClass1Super.class); 64 annotatedElements.add(TestClass1.class); 65 for (Method method : TestClass1.class.getDeclaredMethods()) { 66 annotatedElements.add(method); 67 } 68 return annotatedElements; 69 } 70 71 private static List<Class<? extends Annotation>> annotationsToTest() { 72 List<Class<? extends Annotation>> annotations = new ArrayList<>(); 73 annotations.add(Missing.class); 74 75 annotations.add(MissingRepeatable.class); 76 77 annotations.add(DirectlyPresent.class); 78 79 annotations.add(IndirectlyPresent.class); 80 annotations.add(IndirectlyPresentContainer.class); 81 82 annotations.add(DirectlyAndIndirectlyPresent.class); 83 annotations.add(DirectlyAndIndirectlyPresentContainer.class); 84 85 annotations.add(AssociatedDirectOnSuperClass.class); 86 annotations.add(AssociatedDirectOnSuperClassContainer.class); 87 88 annotations.add(AssociatedDirectOnSuperClassIndirectOnSubclass.class); 89 annotations.add(AssociatedDirectOnSuperClassIndirectOnSubclassContainer.class); 90 91 annotations.add(AssociatedIndirectOnSuperClassDirectOnSubclass.class); 92 annotations.add(AssociatedIndirectOnSuperClassDirectOnSubclassContainer.class); 93 return annotations; 94 } 95 96 private static int testNullHandling(AnnotatedElementDelegate delegate) { 97 int failures = 0; 98 try { 99 Object result = delegate.getDeclaredAnnotationsByType(null); 100 failures++; 101 } catch (NullPointerException npe) { 102 ; // Expected 103 } 104 105 try { 106 Object result = delegate.getAnnotationsByType(null); 107 failures++; 108 } catch (NullPointerException npe) { 109 ; // Expected 110 } 111 112 try { 113 Object result = delegate.getDeclaredAnnotation(null); 114 failures++; 115 } catch (NullPointerException npe) { 116 ; // Expected 117 } 118 119 return failures; 120 } 121 122 } 123 124 // ----------------------------------------------------- 125 126 @AssociatedDirectOnSuperClass(123) 127 @AssociatedIndirectOnSuperClass(234) @AssociatedIndirectOnSuperClass(345) 128 @AssociatedDirectOnSuperClassIndirectOnSubclass(987) 129 @AssociatedIndirectOnSuperClassDirectOnSubclass(1111) @AssociatedIndirectOnSuperClassDirectOnSubclass(2222) 130 class TestClass1Super {} 131 132 @DirectlyPresent(1) 133 @IndirectlyPresent(10) @IndirectlyPresent(11) 134 @AssociatedDirectOnSuperClassIndirectOnSubclass(876) @AssociatedDirectOnSuperClassIndirectOnSubclass(765) 135 @AssociatedIndirectOnSuperClassDirectOnSubclass(3333) 136 class TestClass1 extends TestClass1Super { 137 138 @DirectlyPresent(2) 139 @IndirectlyPresentContainer({@IndirectlyPresent(12)}) 140 @DirectlyAndIndirectlyPresentContainer({@DirectlyAndIndirectlyPresent(84), @DirectlyAndIndirectlyPresent(96)}) 141 public void foo() {return ;} 142 143 @IndirectlyPresentContainer({}) 144 @DirectlyAndIndirectlyPresentContainer({@DirectlyAndIndirectlyPresent(11), @DirectlyAndIndirectlyPresent(22)}) 145 @DirectlyAndIndirectlyPresent(33) 146 public void bar() {return ;} 147 } 148 149 // ----------------------------------------------------- 150 151 @Retention(RetentionPolicy.RUNTIME) 152 @interface Missing { 153 int value(); 154 } 155 156 // ----------------------------------------------------- 157 158 @Retention(RetentionPolicy.RUNTIME) 159 @Repeatable(MissingRepeatableContainer.class) 160 @interface MissingRepeatable { 161 int value(); 162 } 163 164 @Retention(RetentionPolicy.RUNTIME) 165 @interface MissingRepeatableContainer { 166 MissingRepeatable[] value(); 167 } 168 169 // ----------------------------------------------------- 170 171 @Retention(RetentionPolicy.RUNTIME) 172 @interface DirectlyPresent { 173 int value(); 174 } 175 176 // ----------------------------------------------------- 177 178 @Retention(RetentionPolicy.RUNTIME) 179 @Repeatable(IndirectlyPresentContainer.class) 180 @interface IndirectlyPresent { 181 int value(); 182 } 183 184 @Retention(RetentionPolicy.RUNTIME) 185 @interface IndirectlyPresentContainer { 186 IndirectlyPresent[] value(); 187 } 188 189 // ----------------------------------------------------- 190 191 @Retention(RetentionPolicy.RUNTIME) 192 @Repeatable(DirectlyAndIndirectlyPresentContainer.class) 193 @interface DirectlyAndIndirectlyPresent { 194 int value(); 195 196 } 197 198 @Retention(RetentionPolicy.RUNTIME) 199 @interface DirectlyAndIndirectlyPresentContainer { 200 DirectlyAndIndirectlyPresent[] value(); 201 } 202 203 // ----------------------------------------------------- 204 205 @Retention(RetentionPolicy.RUNTIME) 206 @Repeatable(AssociatedDirectOnSuperClassContainer.class) 207 @interface AssociatedDirectOnSuperClass { 208 int value(); 209 } 210 211 @Retention(RetentionPolicy.RUNTIME) 212 @interface AssociatedDirectOnSuperClassContainer { 213 AssociatedDirectOnSuperClass[] value(); 214 } 215 216 // ----------------------------------------------------- 217 218 @Retention(RetentionPolicy.RUNTIME) 219 @Repeatable(AssociatedIndirectOnSuperClassContainer.class) 220 @interface AssociatedIndirectOnSuperClass { 221 int value(); 222 } 223 224 @Retention(RetentionPolicy.RUNTIME) 225 @interface AssociatedIndirectOnSuperClassContainer { 226 AssociatedIndirectOnSuperClass[] value(); 227 } 228 229 // ----------------------------------------------------- 230 231 @Retention(RetentionPolicy.RUNTIME) 232 @Repeatable(AssociatedDirectOnSuperClassIndirectOnSubclassContainer.class) 233 @interface AssociatedDirectOnSuperClassIndirectOnSubclass { 234 int value(); 235 } 236 237 @Retention(RetentionPolicy.RUNTIME) 238 @interface AssociatedDirectOnSuperClassIndirectOnSubclassContainer { 239 AssociatedDirectOnSuperClassIndirectOnSubclass[] value(); 240 } 241 242 // ----------------------------------------------------- 243 244 @Retention(RetentionPolicy.RUNTIME) 245 @Repeatable(AssociatedIndirectOnSuperClassDirectOnSubclassContainer.class) 246 @interface AssociatedIndirectOnSuperClassDirectOnSubclass { 247 int value(); 248 } 249 250 @Retention(RetentionPolicy.RUNTIME) 251 @interface AssociatedIndirectOnSuperClassDirectOnSubclassContainer { 252 AssociatedIndirectOnSuperClassDirectOnSubclass[] value(); 253 } 254 255 // ----------------------------------------------------- 256 257 /** 258 * Helper class to ease calling the default methods of {@code 259 * AnnotatedElement} and comparing the results to other 260 * implementation. 261 */ 262 class AnnotatedElementDelegate implements AnnotatedElement { 263 private AnnotatedElement base; 264 265 public AnnotatedElementDelegate(AnnotatedElement base) { 266 Objects.requireNonNull(base); 267 this.base = base; 268 } 269 270 // Delegate to base implemenetation of AnnotatedElement methods 271 // without defaults. 272 @Override 273 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 274 return base.getAnnotation(annotationClass); 275 } 276 277 @Override 278 public Annotation[] getAnnotations() { 279 return base.getAnnotations(); 280 } 281 282 @Override 283 public Annotation[] getDeclaredAnnotations() { 284 return base.getDeclaredAnnotations(); 285 } 286 287 public AnnotatedElement getBase() { 288 return base; 289 } 290 291 static int testDelegate(AnnotatedElementDelegate delegate, 292 Class<? extends Annotation> annotationClass) { 293 int failures = 0; 294 AnnotatedElement base = delegate.getBase(); 295 296 // System.out.println("\tTesting " + delegate + "\ton\t" + annotationClass); 297 298 // <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) 299 failures += annotationArrayCheck(delegate.getDeclaredAnnotationsByType(annotationClass), 300 base.getDeclaredAnnotationsByType(annotationClass), 301 annotationClass, 302 "Equality failure on getDeclaredAnnotationsByType(%s) on %s)%n"); 303 304 // <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) 305 failures += annotationArrayCheck(delegate.getAnnotationsByType(annotationClass), 306 base.getAnnotationsByType(annotationClass), 307 annotationClass, 308 "Equality failure on getAnnotationsByType(%s) on %s)%n"); 309 310 // <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) 311 if (!Objects.equals(delegate.getDeclaredAnnotation(annotationClass), 312 base.getDeclaredAnnotation(annotationClass))) { 313 failures++; 314 System.err.printf("Equality failure on getDeclaredAnnotation(%s) on %s)%n", 315 annotationClass, delegate); 316 } 317 return failures; 318 } 319 private static <T extends Annotation> int annotationArrayCheck(T[] delegate, 320 T[] base, 321 Class<? extends Annotation> annotationClass, 322 String message) { 323 int failures = 0; 324 325 if (!Objects.deepEquals(delegate,base)) { 326 failures = 1; 327 328 System.err.printf(message, 329 annotationClass, 330 delegate); 331 332 System.err.println("Base result:\t" + Arrays.toString(base)); 333 System.err.println("Delegate result:\t " + Arrays.toString(delegate)); 334 System.err.println(); 335 } 336 337 return failures; 338 } 339 }