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  * @test
  25  * @bug 8013497
  26  * @summary test for API: TypeVariable.getAnnotatedBounds()
  27  * @library ../../../../
  28  * @build AnnotationTest TestCaseGenerator DeclarationGenerator Helper
  29  * @author Charlie Wang
  30  * @run main TypeVariableGetAnnotatedBoundsTest
  31  */
  32 import java.lang.reflect.AnnotatedType;
  33 import java.lang.reflect.TypeVariable;
  34 
  35 /*
  36  * Construct the test code in a structure specified in TestCase.
  37  * In each of the following cases, different combinations of annotation 
  38  * specified in AnnotationTest.annotationCombinations are tested. The output
  39  * annotations must be the same as input both in value and order.
  40  * 1. No bounds
  41  * 2. Single bounds
  42  * 3. Multiple bounds
  43  * The program test all the cases in TestCase by looping over each one of it.
  44  * Test cases are constructed with small code snippet from Helper.SrcType
  45  * using changable annotations, type and name. After these values are specified,
  46  * the method GenTestCode() generates corresponding java code, encapsulate them
  47  * with a class. Then this class is compiled by Helper.compileCode() into
  48  * classes which is later loaded into memory by Helper.loadClass().
  49  * The test fails if any of the cases fail.
  50  */
  51 public class TypeVariableGetAnnotatedBoundsTest extends AnnotationTest {
  52 
  53     enum TestCase implements TestCaseGenerator {
  54 
  55         TESTBASECLS() {
  56             /**
  57              * generate test base, which is the class name used to compile the code: 
  58              * import java.io.*; 
  59              * import java.util.*; 
  60              * import java.lang.*; 
  61              * import java.lang.reflect.*;
  62              * import java.lang.annotation.*; 
  63              * class testBaseClsName { }
  64              */
  65             public String genTestCase(String str) {
  66                 if (0 == clsIdx) {
  67                     clsIdx++;
  68                     return AnnotationTest.genBaseClass(testBaseClsName);
  69                 } else {
  70                     return "";
  71                 }
  72             }
  73         },
  74         NOBOUND() {
  75             /**
  76              * generate test class: 
  77              * class TypeAnnoCls<T> { 
  78              *      T method1(){} 
  79              * }
  80              *
  81              * input should be like [anno]
  82              */
  83             public String genTestCase(String str) {
  84                 if (null == str) {
  85                     throw new RuntimeException("bad test base.");
  86                 }
  87                 String testCode = "";
  88                 lhm.clear();
  89                 lhm.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
  90                 lhm.put(Helper.Declaration.GENERICS1, "T");
  91                 lhm.put(Helper.Declaration.CLASS_BODY_START, "");
  92                 lhm.put(Helper.Declaration.CLASS_BODY_END, "");
  93                 testCode += Helper.genDeclaration(lhm);
  94                 testInput.put(typeAnnoClsName + clsIdx, "");
  95                 lhm.clear();
  96                 clsIdx++;
  97                 return testCode;
  98             }
  99         },
 100         SINGLEBOUND() {
 101             /**
 102              * generate test class: 
 103              * class TypeAnnoCls<T extebds @anno Object> {
 104              *      T method1(){} 
 105              * }
 106              *
 107              * input should be like [anno]
 108              */
 109             public String genTestCase(String str) {
 110                 if (null == str) {
 111                     throw new RuntimeException("bad test base.");
 112                 }
 113                 String testCode = "";
 114                 lhm.clear();
 115                 lhm.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
 116                 lhm.put(Helper.Declaration.GENERICS1, 
 117                         "T extends " + str + " Object");
 118                 lhm.put(Helper.Declaration.CLASS_BODY_START, "");
 119                 lhm.put(Helper.Declaration.CLASS_BODY_END, "");
 120                 testCode += Helper.genDeclaration(lhm);
 121                 testInput.put(typeAnnoClsName + clsIdx, str);
 122                 lhm.clear();
 123                 clsIdx++;
 124                 return testCode;
 125             }
 126         },
 127         MULTIPLEBOUNDS() {
 128             /**
 129              * generate test class: 
 130              * class TypeAnnoCls<T extebds @anno Object> {
 131              *      T method1(){} 
 132              * }
 133              *
 134              * input should be like [anno]
 135              */
 136             public String genTestCase(String str) {
 137                 if (null == str) {
 138                     throw new RuntimeException("bad test base.");
 139                 }
 140                 String testCode = "";
 141                 lhm.clear();
 142                 lhm.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
 143                 lhm.put(Helper.Declaration.GENERICS2, 
 144                         "T " + str + " Object " + str + " Serializable");
 145                 lhm.put(Helper.Declaration.CLASS_BODY_START, "");
 146                 lhm.put(Helper.Declaration.CLASS_BODY_END, "");
 147                 testCode += Helper.genDeclaration(lhm);
 148                 testInput.put(typeAnnoClsName + clsIdx, str);
 149                 lhm.clear();
 150                 clsIdx++;
 151                 return testCode;
 152             }
 153         };
 154 
 155         // generate test class of a specific case
 156         public String genTestCase(String str) {
 157             return "";
 158         }
 159     }
 160 
 161     // compare input with result
 162     protected boolean checkResult() throws Exception {
 163         compileCode(TestCase.class);
 164         // Get Class object for the compiled class
 165         for (Object clsName : testInput.keySet()) {
 166             Class cls = Helper.loadClass((String) clsName);
 167             TypeVariable[] typeVars = cls.getTypeParameters();
 168             for (TypeVariable tv : typeVars) {
 169                 AnnotatedType[] abs = ((TypeVariable) tv).getAnnotatedBounds();
 170                 for (AnnotatedType at : abs) {
 171                     if (!Helper.getAT(at).equals(testInput.get(clsName))) {
 172                         Helper.debugPrint(clsName 
 173                                 + " failed with faulty annotations.");
 174                         return false;
 175                     }
 176                 }
 177             }
 178         }
 179         return true;
 180     }
 181 
 182     public static void main(String[] args) throws Exception {
 183         new TypeVariableGetAnnotatedBoundsTest().test();
 184     }
 185 }