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 comparting the toString()
  37  * result of annotations to ExpectedString.value().
  38  */
  39 public class AnnotationToStringTest {
  40     public static void main(String... args) throws Exception {
  41         int failures = 0;
  42 
  43         failures += classyTest();
  44         failures += arrayAnnotationTest();
  45 
  46         if (failures > 0)
  47             throw new RuntimeException(failures + " failures");
  48     }
  49 
  50     private static int check(String expected, String actual) {
  51         if (!expected.equals(actual)) {
  52             System.err.printf("ERROR: Expected ''%s'';%ngot             ''%s''.\n",
  53                               expected, actual);
  54             return 1;
  55         } else
  56             return 0;
  57     }
  58 
  59     private static int classyTest() {
  60         int failures = 0;
  61         for (Field f : AnnotationHost.class.getFields()) {
  62             Annotation a = f.getAnnotation(Classy.class);
  63             System.out.println(a);
  64             failures += check(f.getAnnotation(ExpectedString.class).value(),
  65                               a.toString());
  66         }
  67         return failures;
  68     }
  69 
  70     static class AnnotationHost {
  71         @ExpectedString(
  72        "@Classy(value=Obj.class)")
  73         @Classy(value=Obj.class)
  74         public int f0;
  75 
  76         @ExpectedString(
  77        "@Classy(value=Obj[].class)")
  78         @Classy(value=Obj[].class)
  79         public int f1;
  80 
  81         @ExpectedString(
  82        "@Classy(value=Obj[][].class)")
  83         @Classy(value=Obj[][].class)
  84         public int f2;
  85 
  86         @ExpectedString(
  87        "@Classy(value=Obj[][][].class)")
  88         @Classy(value=Obj[][][].class)
  89         public int f3;
  90 
  91         @ExpectedString(
  92        "@Classy(value=int.class)")
  93         @Classy(value=int.class)
  94         public int f4;
  95 
  96         @ExpectedString(
  97        "@Classy(value=int[][][].class)")
  98         @Classy(value=int[][][].class)
  99         public int f5;
 100     }
 101 
 102     /**
 103      * Each field should have two annotations, the first being
 104      * @ExpectedString and the second the annotation under test.
 105      */
 106     private static int arrayAnnotationTest() {
 107         int failures = 0;
 108         for (Field f : ArrayAnnotationHost.class.getFields()) {
 109             Annotation[] annotations = f.getAnnotations();
 110             System.out.println(annotations[1]);
 111             failures += check(((ExpectedString)annotations[0]).value(),
 112                               annotations[1].toString());
 113         }
 114         return failures;
 115     }
 116 
 117     static class ArrayAnnotationHost {
 118         @ExpectedString(
 119        "@BooleanArray(value={true, false, true})")
 120         @BooleanArray(value={true, false, true})
 121         public boolean[]   f0;
 122 
 123         @ExpectedString(
 124        "@FloatArray(value={3.0f, 4.0f, 0.0f/0.0f, -1.0f/0.0f, 1.0f/0.0f})")
 125         @FloatArray(value={3.0f, 4.0f, Float.NaN, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY})
 126         public float[]     f1;
 127 
 128         @ExpectedString(
 129        "@DoubleArray(value={1.0, 2.0, 0.0/0.0, 1.0/0.0, -1.0/0.0})")
 130         @DoubleArray(value={1.0, 2.0, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY,})
 131         public double[]    f2;
 132 
 133         @ExpectedString(
 134        "@ByteArray(value={10, 11, 12})")
 135         @ByteArray(value={10, 11, 12})
 136         public byte[]      f3;
 137 
 138         @ExpectedString(
 139        "@ShortArray(value={0, 4, 5})")
 140         @ShortArray(value={0, 4, 5})
 141         public short[]     f4;
 142 
 143         @ExpectedString(
 144        "@CharArray(value={'a', 'b', 'c', '\\''})")
 145         @CharArray(value={'a', 'b', 'c', '\''})
 146         public char[]      f5;
 147 
 148         @ExpectedString(
 149        "@IntArray(value={1})")
 150         @IntArray(value={1})
 151         public int[]       f6;
 152 
 153         @ExpectedString(
 154        "@LongArray(value={-2147483647, 2147483648L, 9223372036854775807L})")
 155         @LongArray(value={-Integer.MAX_VALUE, Integer.MAX_VALUE+1L, Long.MAX_VALUE})
 156         public long[]      f7;
 157 
 158         @ExpectedString(
 159        "@StringArray(value={\"A\", \"B\", \"C\", \"\\\"Quote\\\"\"})")
 160         @StringArray(value={"A", "B", "C", "\"Quote\""})
 161         public String[]    f8;
 162 
 163         @ExpectedString(
 164        "@ClassArray(value={int.class, Obj[].class})")
 165         @ClassArray(value={int.class, Obj[].class})
 166         public Class<?>[]  f9;
 167 
 168         @ExpectedString(
 169        "@EnumArray(value={SOURCE})")
 170         @EnumArray(value={RetentionPolicy.SOURCE})
 171         public RetentionPolicy[]  f10;
 172     }
 173 }
 174 
 175 // ------------ Supporting types ------------
 176 
 177 class Obj {}
 178 
 179 @Retention(RetentionPolicy.RUNTIME)
 180 @interface ExpectedString {
 181     String value();
 182 }
 183 
 184 @Retention(RetentionPolicy.RUNTIME)
 185 @interface Classy {
 186     Class<?> value();
 187 }
 188 
 189 @Retention(RetentionPolicy.RUNTIME)
 190 @interface BooleanArray {
 191     boolean[] value();
 192 }
 193 
 194 @Retention(RetentionPolicy.RUNTIME)
 195 @interface FloatArray {
 196     float[] value();
 197 }
 198 
 199 @Retention(RetentionPolicy.RUNTIME)
 200 @interface DoubleArray {
 201     double[] value();
 202 }
 203 
 204 @Retention(RetentionPolicy.RUNTIME)
 205 @interface ByteArray {
 206     byte[] value();
 207 }
 208 
 209 @Retention(RetentionPolicy.RUNTIME)
 210 @interface ShortArray {
 211     short[] value();
 212 }
 213 
 214 @Retention(RetentionPolicy.RUNTIME)
 215 @interface CharArray {
 216     char[] value();
 217 }
 218 
 219 @Retention(RetentionPolicy.RUNTIME)
 220 @interface IntArray {
 221     int[] value();
 222 }
 223 
 224 @Retention(RetentionPolicy.RUNTIME)
 225 @interface LongArray {
 226     long[] value();
 227 }
 228 
 229 @Retention(RetentionPolicy.RUNTIME)
 230 @interface ClassArray {
 231     Class<?>[] value() default {int.class, Obj[].class};
 232 }
 233 
 234 @Retention(RetentionPolicy.RUNTIME)
 235 @interface StringArray {
 236     String[] value();
 237 }
 238 
 239 @Retention(RetentionPolicy.RUNTIME)
 240 @interface EnumArray {
 241     RetentionPolicy[] value();
 242 }