1 /* 2 * Copyright (c) 2016, 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 8162817 8168921 27 * @summary Test of toString on normal annotations 28 */ 29 30 import java.lang.annotation.*; 31 import java.lang.reflect.*; 32 import java.util.*; 33 34 /** 35 * The expected string values are stored in @ExpectedString 36 * annotations. The essence of the test is comparing the toString() 37 * result of annotations to the corresponding ExpectedString.value(). 38 */ 39 40 public class AnnotationToStringTest { 41 public static void main(String... args) throws Exception { 42 int failures = 0; 43 44 failures += check(PrimHost.class.getAnnotation(ExpectedString.class).value(), 45 PrimHost.class.getAnnotation(MostlyPrimitive.class).toString()); 46 failures += classyTest(); 47 failures += arrayAnnotationTest(); 48 49 if (failures > 0) 50 throw new RuntimeException(failures + " failures"); 51 } 52 53 private static int check(String expected, String actual) { 54 if (!expected.equals(actual)) { 55 System.err.printf("ERROR: Expected ''%s'';%ngot ''%s''.\n", 56 expected, actual); 57 return 1; 58 } else 59 return 0; 60 } 61 62 @ExpectedString( 63 "@MostlyPrimitive(c0='a', "+ 64 "c1='\\'', " + 65 "i0=1, " + 66 "i1=2, " + 67 "f0=1.0f, " + 68 "f1=0.0f/0.0f, " + 69 "d0=0.0, " + 70 "d1=1.0/0.0, " + 71 "l0=5, " + 72 "l1=9223372036854775807L, " + 73 "l2=-9223372036854775808L, " + 74 "l3=-2147483648, " + 75 "s0=\"Hello world.\", " + 76 "s1=\"a\\\"b\", " + 77 "class0=Obj[].class)") 78 @MostlyPrimitive( 79 c0='a', 80 c1='\'', 81 i0=1, 82 i1=2, 83 f0=1.0f, 84 f1=Float.NaN, 85 d0=0.0, 86 d1=2.0/0.0, 87 l0=5, 88 l1=Long.MAX_VALUE, 89 l2=Long.MIN_VALUE, 90 l3=Integer.MIN_VALUE, 91 s0="Hello world.", 92 s1="a\"b", 93 class0=Obj[].class 94 ) 95 static class PrimHost{} 96 97 private static int classyTest() { 98 int failures = 0; 99 for (Field f : AnnotationHost.class.getFields()) { 100 Annotation a = f.getAnnotation(Classy.class); 101 System.out.println(a); 102 failures += check(f.getAnnotation(ExpectedString.class).value(), 103 a.toString()); 104 } 105 return failures; 106 } 107 108 static class AnnotationHost { 109 @ExpectedString( 110 "@Classy(value=Obj.class)") 111 @Classy(value=Obj.class) 112 public int f0; 113 114 @ExpectedString( 115 "@Classy(value=Obj[].class)") 116 @Classy(value=Obj[].class) 117 public int f1; 118 119 @ExpectedString( 120 "@Classy(value=Obj[][].class)") 121 @Classy(value=Obj[][].class) 122 public int f2; 123 124 @ExpectedString( 125 "@Classy(value=Obj[][][].class)") 126 @Classy(value=Obj[][][].class) 127 public int f3; 128 129 @ExpectedString( 130 "@Classy(value=int.class)") 131 @Classy(value=int.class) 132 public int f4; 133 134 @ExpectedString( 135 "@Classy(value=int[][][].class)") 136 @Classy(value=int[][][].class) 137 public int f5; 138 } 139 140 /** 141 * Each field should have two annotations, the first being 142 * @ExpectedString and the second the annotation under test. 143 */ 144 private static int arrayAnnotationTest() { 145 int failures = 0; 146 for (Field f : ArrayAnnotationHost.class.getFields()) { 147 Annotation[] annotations = f.getAnnotations(); 148 System.out.println(annotations[1]); 149 failures += check(((ExpectedString)annotations[0]).value(), 150 annotations[1].toString()); 151 } 152 return failures; 153 } 154 155 static class ArrayAnnotationHost { 156 @ExpectedString( 157 "@BooleanArray(value={true, false, true})") 158 @BooleanArray(value={true, false, true}) 159 public boolean[] f0; 160 161 @ExpectedString( 162 "@FloatArray(value={3.0f, 4.0f, 0.0f/0.0f, -1.0f/0.0f, 1.0f/0.0f})") 163 @FloatArray(value={3.0f, 4.0f, Float.NaN, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY}) 164 public float[] f1; 165 166 @ExpectedString( 167 "@DoubleArray(value={1.0, 2.0, 0.0/0.0, 1.0/0.0, -1.0/0.0})") 168 @DoubleArray(value={1.0, 2.0, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,}) 169 public double[] f2; 170 171 @ExpectedString( 172 "@ByteArray(value={10, 11, 12})") 173 @ByteArray(value={10, 11, 12}) 174 public byte[] f3; 175 176 @ExpectedString( 177 "@ShortArray(value={0, 4, 5})") 178 @ShortArray(value={0, 4, 5}) 179 public short[] f4; 180 181 @ExpectedString( 182 "@CharArray(value={'a', 'b', 'c', '\\''})") 183 @CharArray(value={'a', 'b', 'c', '\''}) 184 public char[] f5; 185 186 @ExpectedString( 187 "@IntArray(value={1})") 188 @IntArray(value={1}) 189 public int[] f6; 190 191 @ExpectedString( 192 "@LongArray(value={-9223372036854775808L, -2147483649L, -2147483648," + 193 " -2147483647, 2147483648L, 9223372036854775807L})") 194 @LongArray(value={Long.MIN_VALUE, Integer.MIN_VALUE-1L, Integer.MIN_VALUE, 195 -Integer.MAX_VALUE, Integer.MAX_VALUE+1L, Long.MAX_VALUE}) 196 public long[] f7; 197 198 @ExpectedString( 199 "@StringArray(value={\"A\", \"B\", \"C\", \"\\\"Quote\\\"\"})") 200 @StringArray(value={"A", "B", "C", "\"Quote\""}) 201 public String[] f8; 202 203 @ExpectedString( 204 "@ClassArray(value={int.class, Obj[].class})") 205 @ClassArray(value={int.class, Obj[].class}) 206 public Class<?>[] f9; 207 208 @ExpectedString( 209 "@EnumArray(value={SOURCE})") 210 @EnumArray(value={RetentionPolicy.SOURCE}) 211 public RetentionPolicy[] f10; 212 } 213 } 214 215 // ------------ Supporting types ------------ 216 217 class Obj {} 218 219 @Retention(RetentionPolicy.RUNTIME) 220 @interface ExpectedString { 221 String value(); 222 } 223 224 @Retention(RetentionPolicy.RUNTIME) 225 @interface Classy { 226 Class<?> value(); 227 } 228 229 @Retention(RetentionPolicy.RUNTIME) 230 @interface BooleanArray { 231 boolean[] value(); 232 } 233 234 @Retention(RetentionPolicy.RUNTIME) 235 @interface FloatArray { 236 float[] value(); 237 } 238 239 @Retention(RetentionPolicy.RUNTIME) 240 @interface DoubleArray { 241 double[] value(); 242 } 243 244 @Retention(RetentionPolicy.RUNTIME) 245 @interface ByteArray { 246 byte[] value(); 247 } 248 249 @Retention(RetentionPolicy.RUNTIME) 250 @interface ShortArray { 251 short[] value(); 252 } 253 254 @Retention(RetentionPolicy.RUNTIME) 255 @interface CharArray { 256 char[] value(); 257 } 258 259 @Retention(RetentionPolicy.RUNTIME) 260 @interface IntArray { 261 int[] value(); 262 } 263 264 @Retention(RetentionPolicy.RUNTIME) 265 @interface LongArray { 266 long[] value(); 267 } 268 269 @Retention(RetentionPolicy.RUNTIME) 270 @interface ClassArray { 271 Class<?>[] value() default {int.class, Obj[].class}; 272 } 273 274 @Retention(RetentionPolicy.RUNTIME) 275 @interface StringArray { 276 String[] value(); 277 } 278 279 @Retention(RetentionPolicy.RUNTIME) 280 @interface EnumArray { 281 RetentionPolicy[] value(); 282 } 283 284 @Retention(RetentionPolicy.RUNTIME) 285 @interface MostlyPrimitive { 286 char c0(); 287 char c1(); 288 int i0(); 289 int i1(); 290 float f0(); 291 float f1(); 292 double d0(); 293 double d1(); 294 long l0(); 295 long l1(); 296 long l2(); 297 long l3(); 298 String s0(); 299 String s1(); 300 Class<?> class0(); 301 }