1 /* 2 * Copyright (c) 2015, 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 8058595 27 * @summary Test that AnnotatedType.getAnnotatedOwnerType() works as expected 28 * 29 * @library /test/lib 30 * @build jdk.test.lib.Asserts 31 * @run main GetAnnotatedOwnerType 32 */ 33 34 import java.lang.annotation.*; 35 import java.lang.reflect.*; 36 37 import jdk.test.lib.Asserts; 38 39 public class GetAnnotatedOwnerType<Dummy> { 40 public @TA("generic") GetAnnotatedOwnerType<String> . @TB("generic") Nested<Integer> genericField; 41 public @TA("raw") GetAnnotatedOwnerType . @TB("raw") Nested rawField; 42 public @TA("non-generic") GetAnnotatedOwnerTypeAuxilliary . @TB("non-generic") Inner nonGeneric; 43 public @TA("non-generic") GetAnnotatedOwnerTypeAuxilliary . @TB("generic") InnerGeneric<String> innerGeneric; 44 public @TA("non-generic") GetAnnotatedOwnerTypeAuxilliary . @TB("raw") InnerGeneric innerRaw; 45 public Object anonymous = new Object() {}; 46 public @TA("array") Dummy[] dummy; 47 public @TA("wildcard") GetAnnotatedOwnerType<?> wildcard; 48 public @TA("typevariable") Dummy tv; 49 public @TA("bad") GetAnnotatedOwnerType<@TA("good") GetAnnotatedOwnerType<String> . @TB("tb") Nested<Integer> > typeArgument; 50 public GetAnnotatedOwnerType< GetAnnotatedOwnerType<String> . 51 B . 52 C<Class<?>, ? extends @TA("complicated") Exception> . 53 D<Number> > [] complicated; 54 55 public static void main(String[] args) throws Exception { 56 testGeneric(); 57 testRaw(); 58 testNonGeneric(); 59 testInnerGeneric(); 60 testInnerRaw(); 61 62 testLocalClass(); 63 testAnonymousClass(); 64 65 testArray(); 66 testWildcard(); 67 testTypeParameter(); 68 69 testTypeArgument(); 70 testComplicated(); 71 } 72 73 public static void testGeneric() throws Exception { 74 Field f = GetAnnotatedOwnerType.class.getField("genericField"); 75 76 // make sure inner is correctly annotated 77 AnnotatedType inner = f.getAnnotatedType(); 78 Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "generic"); 79 Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: " 80 + inner.getAnnotations().length); 81 82 // make sure owner is correctly annotated, on the correct type 83 AnnotatedType outer = inner.getAnnotatedOwnerType(); 84 Asserts.assertEquals(outer.getType(), ((ParameterizedType) f.getGenericType()).getOwnerType()); 85 Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "generic"); 86 Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: " 87 + outer.getAnnotations().length); 88 } 89 90 public static void testRaw() throws Exception { 91 Field f = GetAnnotatedOwnerType.class.getField("rawField"); 92 93 // make sure inner is correctly annotated 94 AnnotatedType inner = f.getAnnotatedType(); 95 Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "raw"); 96 Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: " 97 + inner.getAnnotations().length); 98 99 // make sure owner is correctly annotated, on the correct type 100 AnnotatedType outer = inner.getAnnotatedOwnerType(); 101 Asserts.assertEquals(outer.getType(), ((Class<?>)f.getGenericType()).getEnclosingClass()); 102 Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "raw"); 103 Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: " 104 + outer.getAnnotations().length); 105 } 106 107 public static void testNonGeneric() throws Exception { 108 Field f = GetAnnotatedOwnerType.class.getField("nonGeneric"); 109 110 // make sure inner is correctly annotated 111 AnnotatedType inner = f.getAnnotatedType(); 112 Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "non-generic"); 113 Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: " 114 + inner.getAnnotations().length); 115 116 // make sure owner is correctly annotated, on the correct type 117 AnnotatedType outer = inner.getAnnotatedOwnerType(); 118 Asserts.assertEquals(outer.getType(), ((Class<?>)f.getGenericType()).getEnclosingClass()); 119 Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "non-generic"); 120 Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: " 121 + outer.getAnnotations().length); 122 } 123 124 public static void testInnerGeneric() throws Exception { 125 Field f = GetAnnotatedOwnerType.class.getField("innerGeneric"); 126 127 // make sure inner is correctly annotated 128 AnnotatedType inner = f.getAnnotatedType(); 129 Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "generic"); 130 Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: " 131 + inner.getAnnotations().length); 132 133 // make sure owner is correctly annotated, on the correct type 134 AnnotatedType outer = inner.getAnnotatedOwnerType(); 135 Asserts.assertEquals(outer.getType(), ((ParameterizedType) f.getGenericType()).getOwnerType()); 136 Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "non-generic"); 137 Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: " 138 + outer.getAnnotations().length); 139 } 140 141 public static void testInnerRaw() throws Exception { 142 Field f = GetAnnotatedOwnerType.class.getField("innerRaw"); 143 144 // make sure inner is correctly annotated 145 AnnotatedType inner = f.getAnnotatedType(); 146 Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "raw"); 147 Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: " 148 + inner.getAnnotations().length); 149 150 // make sure owner is correctly annotated, on the correct type 151 AnnotatedType outer = inner.getAnnotatedOwnerType(); 152 Asserts.assertEquals(outer.getType(), ((Class<?>)f.getGenericType()).getEnclosingClass()); 153 Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "non-generic"); 154 Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: " 155 + outer.getAnnotations().length); 156 } 157 158 public static void testLocalClass() throws Exception { 159 class ALocalClass {} 160 class OneMore { 161 public @TA("null") ALocalClass c; 162 } 163 testNegative(OneMore.class.getField("c").getAnnotatedType(), "Local class should return null"); 164 } 165 166 public static void testAnonymousClass() throws Exception { 167 testNegative(GetAnnotatedOwnerType.class.getField("anonymous").getAnnotatedType(), 168 "Anonymous class should return null"); 169 } 170 171 public static void testArray() throws Exception { 172 AnnotatedType t = GetAnnotatedOwnerType.class.getField("dummy").getAnnotatedType(); 173 Asserts.assertTrue((t instanceof AnnotatedArrayType), 174 "Was expecting an AnnotatedArrayType " + t); 175 testNegative(t, "" + t + " should not have an annotated owner type"); 176 } 177 178 public static void testWildcard() throws Exception { 179 AnnotatedType tt = GetAnnotatedOwnerType.class.getField("wildcard").getAnnotatedType(); 180 AnnotatedType t = ((AnnotatedParameterizedType)tt).getAnnotatedActualTypeArguments()[0]; 181 Asserts.assertTrue((t instanceof AnnotatedWildcardType), 182 "Was expecting an AnnotatedWildcardType " + t); 183 testNegative(t, "" + t + " should not have an annotated owner type"); 184 } 185 186 public static void testTypeParameter() throws Exception { 187 AnnotatedType t = GetAnnotatedOwnerType.class.getField("tv").getAnnotatedType(); 188 Asserts.assertTrue((t instanceof AnnotatedTypeVariable), 189 "Was expecting an AnnotatedTypeVariable " + t); 190 testNegative(t, "" + t + " should not have an annotated owner type"); 191 } 192 193 public static void testTypeArgument() throws Exception { 194 AnnotatedType tt = GetAnnotatedOwnerType.class.getField("typeArgument").getAnnotatedType(); 195 Asserts.assertEquals(tt.getAnnotation(TA.class).value(), "bad"); 196 Asserts.assertTrue(tt.getAnnotations().length == 1, "expecting one (1) annotation, got: " 197 + tt.getAnnotations().length); 198 199 // make sure inner is correctly annotated 200 AnnotatedType inner = ((AnnotatedParameterizedType)tt).getAnnotatedActualTypeArguments()[0]; 201 Asserts.assertEquals(inner.getAnnotation(TB.class).value(), "tb"); 202 Asserts.assertTrue(inner.getAnnotations().length == 1, "expecting one (1) annotation, got: " 203 + inner.getAnnotations().length); 204 205 // make sure owner is correctly annotated 206 AnnotatedType outer = inner.getAnnotatedOwnerType(); 207 Asserts.assertEquals(outer.getAnnotation(TA.class).value(), "good"); 208 Asserts.assertTrue(outer.getAnnotations().length == 1, "expecting one (1) annotation, got: " 209 + outer.getAnnotations().length); 210 } 211 212 public static void testComplicated() throws Exception { 213 Field f = GetAnnotatedOwnerType.class.getField("complicated"); 214 215 // Outermost level 216 AnnotatedType t = f.getAnnotatedType(); 217 Asserts.assertTrue((t instanceof AnnotatedArrayType), 218 "Was expecting an AnnotatedArrayType " + t); 219 testNegative(t, "" + t + " should not have an annotated owner type"); 220 Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: " 221 + t.getAnnotations().length); 222 223 // Component type 224 t = ((AnnotatedArrayType)t).getAnnotatedGenericComponentType(); 225 testNegative(t, "" + t + " should not have an annotated owner type"); 226 Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: " 227 + t.getAnnotations().length); 228 229 // Type arg GetAnnotatedOwnerType<String>...D<Number> 230 t = ((AnnotatedParameterizedType)t).getAnnotatedActualTypeArguments()[0]; 231 Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: " 232 + t.getAnnotations().length); 233 234 // C<Class<?>, ? extends ...> 235 t = t.getAnnotatedOwnerType(); 236 Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: " 237 + t.getAnnotations().length); 238 239 // ? extends 240 t = ((AnnotatedParameterizedType)t).getAnnotatedActualTypeArguments()[1]; 241 testNegative(t, "" + t + " should not have an annotated owner type"); 242 Asserts.assertTrue(t.getAnnotations().length == 0, "expecting zero annotation, got: " 243 + t.getAnnotations().length); 244 245 // @TA("complicated") Exception 246 t = ((AnnotatedWildcardType)t).getAnnotatedUpperBounds()[0]; 247 testNegative(t, "" + t + " should not have an annotated owner type"); 248 Asserts.assertEquals(t.getAnnotation(TA.class).value(), "complicated"); 249 Asserts.assertTrue(t.getAnnotations().length == 1, "expecting one (1) annotation, got: " 250 + t.getAnnotations().length); 251 } 252 253 private static void testNegative(AnnotatedType t, String msg) { 254 Asserts.assertNull(t.getAnnotatedOwnerType(), msg); 255 } 256 257 public class Nested<AlsoDummy> {} 258 public class B { 259 public class C<R, S> { 260 public class D<T> { 261 } 262 } 263 } 264 265 @Target(ElementType.TYPE_USE) 266 @Retention(RetentionPolicy.RUNTIME) 267 public @interface TA { 268 String value(); 269 } 270 271 @Target(ElementType.TYPE_USE) 272 @Retention(RetentionPolicy.RUNTIME) 273 public @interface TB { 274 String value(); 275 } 276 } 277 278 class GetAnnotatedOwnerTypeAuxilliary { 279 class Inner {} 280 281 class InnerGeneric<Dummy> {} 282 }