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: Executable.getAnnotatedExceptionTypes()
  27  * @library ../../../../
  28  * @build AnnotationTest TestCaseGenerator DeclarationGenerator Helper
  29  * @author Charlie Wang
  30  * @run main ExecutableGetAnnotatedExceptionTypesTest
  31  */
  32 import java.lang.reflect.AnnotatedType;
  33 import java.lang.reflect.Method;
  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 exception
  41  * 2. Single exception
  42  * 3. Multiple exceptions
  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 ExecutableGetAnnotatedExceptionTypesTest 
  52     extends AnnotationTest {
  53 
  54     enum TestCase implements TestCaseGenerator {
  55 
  56         TESTBASECLS() {
  57             /**
  58              * generate test base, which is the class name used to compile the code: 
  59              * import java.io.*; 
  60              * import java.util.*; 
  61              * import java.lang.*; 
  62              * import java.lang.reflect.*;
  63              * import java.lang.annotation.*; 
  64              * class testBaseClsName { }
  65              */
  66             public String genTestCase(String str) {
  67                 if (0 == clsIdx) {
  68                     clsIdx++;
  69                     return AnnotationTest.genBaseClass(testBaseClsName);
  70                 } else {
  71                     return "";
  72                 }
  73             }
  74         },
  75         NOEXCEPTION() {
  76             /**
  77              * generate test method: 
  78              * class TypeAnnoCls {
  79              * String m() {
  80              *     return null;} 
  81              * }
  82              *
  83              * input should be like [anno]
  84              */
  85             public String genTestCase(String str) {
  86 
  87                 if (null == str) {
  88                     throw new RuntimeException("bad test base.");
  89                 }
  90 
  91                 String testCode = "";
  92                 lhm.clear();
  93                 lhm.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
  94                 lhm.put(Helper.Declaration.CLASS_BODY_START, "");
  95                 lhm.put(Helper.Declaration.METHOD_HEADER, "String m");
  96                 lhm.put(Helper.Declaration.METHOD_PARAMETER, "");
  97                 lhm.put(Helper.Declaration.METHOD_BODY, "");
  98                 lhm.put(Helper.Declaration.CLASS_BODY_END, "");
  99                 testCode += Helper.genDeclaration(lhm);
 100                 testInput.put(typeAnnoClsName + clsIdx, "");
 101                 lhm.clear();
 102                 clsIdx++;
 103                 return testCode;
 104             }
 105         },
 106         SINGLEEXCEPTION() {
 107             /**
 108              * generate test method: 
 109              * class TypeAnnoCls {
 110              *     String m() throws @anno Exception {
 111              *          return null;
 112              *      } 
 113              * }
 114              *
 115              * input should be like [anno]
 116              */
 117             public String genTestCase(String str) {
 118                 if (null == str) {
 119                     throw new RuntimeException("bad test base.");
 120                 }
 121                 String testCode = "";
 122                 lhm.clear();
 123                 lhm.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
 124                 lhm.put(Helper.Declaration.CLASS_BODY_START, "");
 125                 lhm.put(Helper.Declaration.METHOD_HEADER, "String m");
 126                 lhm.put(Helper.Declaration.METHOD_PARAMETER, "");
 127                 lhm.put(Helper.Declaration.METHOD_EXCEPTION, 
 128                         str + " RuntimeException");
 129                 lhm.put(Helper.Declaration.METHOD_BODY, "");
 130                 lhm.put(Helper.Declaration.CLASS_BODY_END, "");
 131                 testCode += Helper.genDeclaration(lhm);
 132                 testInput.put(typeAnnoClsName + clsIdx, str);
 133                 lhm.clear();
 134                 clsIdx++;
 135                 return testCode;
 136             }
 137         },
 138         MULTIPLEEXCEPTION() {
 139             /**
 140              * generate test method: 
 141              * class TypeAnnoCls {
 142              *      String m() {
 143              *          return null;
 144              *      } 
 145              * }
 146              *
 147              * input should be like [anno]
 148              */
 149             public String genTestCase(String str) {
 150                 if (null == str) {
 151                     throw new RuntimeException("bad test base.");
 152                 }
 153                 String testCode = "";
 154                 lhm.clear();
 155                 lhm.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
 156                 lhm.put(Helper.Declaration.CLASS_BODY_START, "");
 157                 lhm.put(Helper.Declaration.METHOD_HEADER, "String m");
 158                 lhm.put(Helper.Declaration.METHOD_PARAMETER, "");
 159                 lhm.put(Helper.Declaration.METHOD_EXCEPTION, 
 160                         new String[]{str + " RuntimeException", 
 161                             str + " ArrayIndexOutOfBoundsException"});
 162                 lhm.put(Helper.Declaration.METHOD_BODY, "");
 163                 lhm.put(Helper.Declaration.CLASS_BODY_END, "");
 164                 testCode += Helper.genDeclaration(lhm);
 165                 testInput.put(typeAnnoClsName + clsIdx, str);
 166                 lhm.clear();
 167                 clsIdx++;
 168                 return testCode;
 169             }
 170         };
 171 
 172         // generate test class of a specific case
 173         public String genTestCase(String str) {
 174             return "";
 175         }
 176     }
 177 
 178     // compare input with result
 179     protected boolean checkResult() throws Exception {
 180         compileCode(TestCase.class);
 181         // Get Class object for the compiled class
 182         for (Object clsName : testInput.keySet()) {
 183             Class cls = Helper.loadClass((String) clsName);
 184             Method m = cls.getDeclaredMethod(
 185                     TestCaseGenerator.testBaseMethodName, (Class<?>[]) null);
 186             AnnotatedType[] aet = m.getAnnotatedExceptionTypes();
 187 
 188             for (AnnotatedType at : aet) {
 189                 if (!Helper.getAT(at).equals(testInput.get(clsName))) {
 190                     Helper.debugPrint(clsName 
 191                             + " failed with faulty annotations.");
 192                     return false;
 193                 }
 194             }
 195         }
 196         return true;
 197     }
 198 
 199     public static void main(String[] args) throws Exception {
 200         new ExecutableGetAnnotatedExceptionTypesTest().test();
 201     }
 202 }