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 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 "s0=\"Hello world.\", " + 74 "s1=\"a\\\"b\", " + 75 "class0=Obj[].class)") 76 @MostlyPrimitive( 77 c0='a', 78 c1='\'', 79 i0=1, 80 i1=2, 81 f0=1.0f, 82 f1=Float.NaN, 83 d0=0.0, 84 d1=2.0/0.0, 85 l0=5, 86 l1=Long.MAX_VALUE, 87 s0="Hello world.", 88 s1="a\"b", 89 class0=Obj[].class 90 ) 91 static class PrimHost{} 92 93 private static int classyTest() { 94 int failures = 0; 95 for (Field f : AnnotationHost.class.getFields()) { 96 Annotation a = f.getAnnotation(Classy.class); 97 System.out.println(a); 98 failures += check(f.getAnnotation(ExpectedString.class).value(), 99 a.toString()); 100 } 101 return failures; 102 } 103 104 static class AnnotationHost { 105 @ExpectedString( 106 "@Classy(value=Obj.class)") 107 @Classy(value=Obj.class) 108 public int f0; 109 110 @ExpectedString( 111 "@Classy(value=Obj[].class)") 112 @Classy(value=Obj[].class) 113 public int f1; 114 115 @ExpectedString( 116 "@Classy(value=Obj[][].class)") 117 @Classy(value=Obj[][].class) 118 public int f2; 119 120 @ExpectedString( 121 "@Classy(value=Obj[][][].class)") 122 @Classy(value=Obj[][][].class) 123 public int f3; 124 125 @ExpectedString( 126 "@Classy(value=int.class)") 127 @Classy(value=int.class) 128 public int f4; 129 130 @ExpectedString( 131 "@Classy(value=int[][][].class)") 132 @Classy(value=int[][][].class) 133 public int f5; 134 } 135 136 /** 137 * Each field should have two annotations, the first being 138 * @ExpectedString and the second the annotation under test. 139 */ 140 private static int arrayAnnotationTest() { 141 int failures = 0; 142 for (Field f : ArrayAnnotationHost.class.getFields()) { 143 Annotation[] annotations = f.getAnnotations(); 144 System.out.println(annotations[1]); 145 failures += check(((ExpectedString)annotations[0]).value(), 146 annotations[1].toString()); 147 } 148 return failures; 149 } 150 151 static class ArrayAnnotationHost { 152 @ExpectedString( 153 "@BooleanArray(value={true, false, true})") 154 @BooleanArray(value={true, false, true}) 155 public boolean[] f0; 156 157 @ExpectedString( 158 "@FloatArray(value={3.0f, 4.0f, 0.0f/0.0f, -1.0f/0.0f, 1.0f/0.0f})") 159 @FloatArray(value={3.0f, 4.0f, Float.NaN, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY}) 160 public float[] f1; 161 162 @ExpectedString( 163 "@DoubleArray(value={1.0, 2.0, 0.0/0.0, 1.0/0.0, -1.0/0.0})") 164 @DoubleArray(value={1.0, 2.0, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,}) 165 public double[] f2; 166 167 @ExpectedString( 168 "@ByteArray(value={10, 11, 12})") 169 @ByteArray(value={10, 11, 12}) 170 public byte[] f3; 171 172 @ExpectedString( 173 "@ShortArray(value={0, 4, 5})") 174 @ShortArray(value={0, 4, 5}) 175 public short[] f4; 176 177 @ExpectedString( 178 "@CharArray(value={'a', 'b', 'c', '\\''})") 179 @CharArray(value={'a', 'b', 'c', '\''}) 180 public char[] f5; 181 182 @ExpectedString( 183 "@IntArray(value={1})") 184 @IntArray(value={1}) 185 public int[] f6; 186 187 @ExpectedString( 188 "@LongArray(value={-2147483647, 2147483648L, 9223372036854775807L})") 189 @LongArray(value={-Integer.MAX_VALUE, Integer.MAX_VALUE+1L, Long.MAX_VALUE}) 190 public long[] f7; 191 192 @ExpectedString( 193 "@StringArray(value={\"A\", \"B\", \"C\", \"\\\"Quote\\\"\"})") 194 @StringArray(value={"A", "B", "C", "\"Quote\""}) 195 public String[] f8; 196 197 @ExpectedString( 198 "@ClassArray(value={int.class, Obj[].class})") 199 @ClassArray(value={int.class, Obj[].class}) 200 public Class<?>[] f9; 201 202 @ExpectedString( 203 "@EnumArray(value={SOURCE})") 204 @EnumArray(value={RetentionPolicy.SOURCE}) 205 public RetentionPolicy[] f10; 206 } 207 } 208 209 // ------------ Supporting types ------------ 210 211 class Obj {} 212 213 @Retention(RetentionPolicy.RUNTIME) 214 @interface ExpectedString { 215 String value(); 216 } 217 218 @Retention(RetentionPolicy.RUNTIME) 219 @interface Classy { 220 Class<?> value(); 221 } 222 223 @Retention(RetentionPolicy.RUNTIME) 224 @interface BooleanArray { 225 boolean[] value(); 226 } 227 228 @Retention(RetentionPolicy.RUNTIME) 229 @interface FloatArray { 230 float[] value(); 231 } 232 233 @Retention(RetentionPolicy.RUNTIME) 234 @interface DoubleArray { 235 double[] value(); 236 } 237 238 @Retention(RetentionPolicy.RUNTIME) 239 @interface ByteArray { 240 byte[] value(); 241 } 242 243 @Retention(RetentionPolicy.RUNTIME) 244 @interface ShortArray { 245 short[] value(); 246 } 247 248 @Retention(RetentionPolicy.RUNTIME) 249 @interface CharArray { 250 char[] value(); 251 } 252 253 @Retention(RetentionPolicy.RUNTIME) 254 @interface IntArray { 255 int[] value(); 256 } 257 258 @Retention(RetentionPolicy.RUNTIME) 259 @interface LongArray { 260 long[] value(); 261 } 262 263 @Retention(RetentionPolicy.RUNTIME) 264 @interface ClassArray { 265 Class<?>[] value() default {int.class, Obj[].class}; 266 } 267 268 @Retention(RetentionPolicy.RUNTIME) 269 @interface StringArray { 270 String[] value(); 271 } 272 273 @Retention(RetentionPolicy.RUNTIME) 274 @interface EnumArray { 275 RetentionPolicy[] value(); 276 } 277 278 @Retention(RetentionPolicy.RUNTIME) 279 @interface MostlyPrimitive { 280 char c0(); 281 char c1(); 282 int i0(); 283 int i1(); 284 float f0(); 285 float f1(); 286 double d0(); 287 double d1(); 288 long l0(); 289 long l1(); 290 String s0(); 291 String s1(); 292 Class<?> class0(); 293 }