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 8023651 8044629 27 * @summary Test that the receiver annotations and the return annotations of 28 * constructors behave correctly. 29 * @run testng ConstructorReceiverTest 30 */ 31 32 import java.lang.annotation.*; 33 import java.lang.reflect.*; 34 import java.util.Arrays; 35 import org.testng.annotations.DataProvider; 36 import org.testng.annotations.Test; 37 38 import static org.testng.Assert.*; 39 40 public class ConstructorReceiverTest { 41 public static final Integer EMPTY_ANNOTATED_TYPE = Integer.valueOf(-1); 42 43 // Format is { 44 // { Class to get ctor for, 45 // ctor param class, 46 // value of anno of return type, 47 // value of anno for receiver, 48 // or null if there should be no receiver, 49 // or EMPTY_ANNOTATED_TYPE of there should be a receiver but 50 // no annotation 51 // }, 52 // ... 53 // } 54 public static final Object[][] TESTS = { 55 { ConstructorReceiverTest.class, null, Integer.valueOf(5), null }, 56 { ConstructorReceiverTest.Middle.class, ConstructorReceiverTest.class, Integer.valueOf(10), Integer.valueOf(15) }, 57 { ConstructorReceiverTest.Middle.Inner.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(100), Integer.valueOf(150) }, 58 { ConstructorReceiverTest.Middle.Inner.Innermost.class, ConstructorReceiverTest.Middle.Inner.class, Integer.valueOf(1000), Integer.valueOf(1500) }, 59 { ConstructorReceiverTest.Middle.InnerNoReceiver.class, ConstructorReceiverTest.Middle.class, Integer.valueOf(300), EMPTY_ANNOTATED_TYPE }, 60 { ConstructorReceiverTest.Nested.class, null, Integer.valueOf(20), null }, 61 { ConstructorReceiverTest.Nested.NestedMiddle.class, ConstructorReceiverTest.Nested.class, Integer.valueOf(200), Integer.valueOf(250)}, 62 { ConstructorReceiverTest.Nested.NestedMiddle.NestedInner.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(2000), Integer.valueOf(2500)}, 63 { ConstructorReceiverTest.Nested.NestedMiddle.NestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(4000), EMPTY_ANNOTATED_TYPE}, 64 { ConstructorReceiverTest.Nested.NestedMiddle.SecondNestedInnerNoReceiver.class, ConstructorReceiverTest.Nested.NestedMiddle.class, Integer.valueOf(5000), EMPTY_ANNOTATED_TYPE}, 65 }; 66 67 68 @DataProvider 69 public Object[][] data() { return TESTS; } 70 71 @Test(dataProvider = "data") 72 public void testAnnotatedReciver(Class<?> toTest, Class<?> ctorParamType, 73 Integer returnVal, Integer receiverVal) throws NoSuchMethodException { 74 Constructor c; 75 if (ctorParamType == null) 76 c = toTest.getDeclaredConstructor(); 77 else 78 c = toTest.getDeclaredConstructor(ctorParamType); 79 80 AnnotatedType annotatedReceiverType = c.getAnnotatedReceiverType(); 81 82 // Some Constructors doesn't conceptually have a receiver, they should return null 83 if (receiverVal == null) { 84 assertNull(annotatedReceiverType, "getAnnotatedReciverType should return null for Constructor: " + c); 85 return; 86 } 87 88 // check that getType() matches the receiver 89 assertEquals(annotatedReceiverType.getType(), 90 ctorParamType, 91 "getType() doesn't match receiver type: " + ctorParamType); 92 93 Annotation[] receiverAnnotations = annotatedReceiverType.getAnnotations(); 94 95 // Some Constructors have no annotations on but in theory can have a receiver 96 if (receiverVal.equals(EMPTY_ANNOTATED_TYPE)) { 97 assertEquals(receiverAnnotations.length, 0, "expecting an empty annotated type for: " + c); 98 return; 99 } 100 101 // The rest should have annotations 102 assertEquals(receiverAnnotations.length, 1, "expecting a 1 element array. Looking at 'length': "); 103 assertEquals(((Annot)receiverAnnotations[0]).value(), receiverVal.intValue(), " wrong annotation found. Found " + 104 receiverAnnotations[0] + 105 " should find @Annot with value=" + 106 receiverVal); 107 } 108 109 @Test(dataProvider = "data") 110 public void testAnnotatedReturn(Class<?> toTest, Class<?> ctorParamType, 111 Integer returnVal, Integer receiverVal) throws NoSuchMethodException { 112 Constructor c; 113 if (ctorParamType == null) 114 c = toTest.getDeclaredConstructor(); 115 else 116 c = toTest.getDeclaredConstructor(ctorParamType); 117 118 AnnotatedType annotatedReturnType = c.getAnnotatedReturnType(); 119 Annotation[] returnAnnotations = annotatedReturnType.getAnnotations(); 120 121 assertEquals(returnAnnotations.length, 1, "expecting a 1 element array. Looking at 'length': "); 122 assertEquals(((Annot)returnAnnotations[0]).value(), returnVal.intValue(), " wrong annotation found. Found " + 123 returnAnnotations[0] + 124 " should find @Annot with value=" + 125 returnVal); 126 } 127 128 @Annot(5) ConstructorReceiverTest() {} 129 130 private class Middle { 131 @Annot(10) public Middle(@Annot(15) ConstructorReceiverTest ConstructorReceiverTest.this) {} 132 133 public class Inner { 134 @Annot(100) Inner(@Annot(150) Middle Middle.this) {} 135 136 class Innermost { 137 @Annot(1000) private Innermost(@Annot(1500) Inner Inner.this) {} 138 } 139 } 140 141 class InnerNoReceiver { 142 @Annot(300) InnerNoReceiver(Middle Middle.this) {} 143 } 144 } 145 146 public static class Nested { 147 @Annot(20) public Nested() {} 148 149 class NestedMiddle { 150 @Annot(200) public NestedMiddle(@Annot(250) Nested Nested.this) {} 151 152 class NestedInner { 153 @Annot(2000) public NestedInner(@Annot(2500) NestedMiddle NestedMiddle.this) {} 154 } 155 156 class NestedInnerNoReceiver { 157 @Annot(4000) public NestedInnerNoReceiver() {} 158 } 159 160 class SecondNestedInnerNoReceiver { 161 @Annot(5000) public SecondNestedInnerNoReceiver(NestedMiddle NestedMiddle.this) {} 162 } 163 } 164 } 165 166 @Retention(RetentionPolicy.RUNTIME) 167 @Target(ElementType.TYPE_USE) 168 public static @interface Annot { 169 int value(); 170 } 171 }