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 /**
  25  * @test 
  26  * @bug 8013497
  27  * @summary test for API: Class.getAnnotatedInterfaces()
  28  * @author Charlie Wang
  29  * @library ../../../
  30  * @build AnnotationTest TestCaseGenerator DeclarationGenerator Helper
  31  * @run main ClassGetAnnotatedInterfacesTest
  32  */
  33 import java.lang.reflect.AnnotatedType;
  34 import java.util.LinkedHashMap;
  35 import java.util.List;
  36 import java.util.Map;
  37 
  38 /*
  39  * This file is intended to test API: Class.getAnnotatedInterfaces(). 
  40  * It can be run directly by java command or by jtreg.
  41  * By setting Helper.DEBUG = true/false, one can display/hide the test code
  42  * on the command line output, which is constructed for the annotation test.
  43  * Here's more details about test code generation:
  44  * Construct the test code in a structure specified in TestCase.
  45  * In each of the following cases, different combinations of annotation 
  46  * specified in AnnotationTest.annotationCombinations are tested. The output
  47  * annotations must be the same as input both in value and order.
  48  * 1. Single interface
  49  * 2. Interface extends interface
  50  * 3. Single class
  51  * 4. Class extends class implements interface
  52  * The program test all the cases in TestCase by looping over each one of it.
  53  * Test cases are constructed with small code snippet from Helper.SrcType
  54  * using changable annotations, type and name. After these values are specified,
  55  * the method GenTestCode() generates corresponding java code, encapsulate them
  56  * with a class. Then this class is compiled by Helper.compileCode() into
  57  * classes which is later loaded into memory by Helper.loadClass().
  58  * The test fails if any of the cases fail.
  59  */
  60 public class ClassGetAnnotatedInterfacesTest extends AnnotationTest{
  61 
  62     enum TestCase implements TestCaseGenerator{
  63 
  64         TESTBASECLS() {
  65             /**
  66              * generate test base, which is the class name used to compile the
  67              * code: 
  68              * import java.io.*; 
  69              * import java.util.*; 
  70              * import java.lang.*;
  71              * import java.lang.reflect.*; 
  72              * import java.lang.annotation.*; 
  73              * class testBaseClsName { }
  74              */
  75             public String genTestCase(String str) {
  76                 if (0 == testInput.size()) {
  77                     testInput.put(null, null);
  78                     return AnnotationTest.genBaseClass(testBaseClsName);
  79                 } else {
  80                     return "";
  81                 }
  82             }
  83         },
  84         SINGLEINT() {
  85             /**
  86              * generate single interface: 
  87              * [#ANNO] interface TypeAnnoInt1 { }
  88              * then append annotations on [#ANNO]
  89              *
  90              * input should be like [@anno]
  91              */
  92             public String genTestCase(String str) {
  93                 if (null == str) {
  94                     throw new RuntimeException("bad test case.");
  95                 }
  96                 String testCode = "";
  97                 int clsIdx = testInput.size();
  98                 TestCodeGenerator tcg = new TestCodeGenerator();
  99                 tcg.put(Helper.Declaration.INTERFACE, typeAnnoIntName + clsIdx);
 100                 tcg.put(Helper.Declaration.CLASS_BODY_START, "");
 101                 tcg.put(Helper.Declaration.CLASS_BODY_END, "");
 102                 testCode += tcg.genTestCode();
 103                 testInput.put(typeAnnoIntName + clsIdx, "");
 104                 return testCode;
 105             }
 106         },
 107         INTEXTINT() {
 108             /**
 109              * generate interface extends interface: 
 110              * [#ANNO] interface TypeAnnoInt extends 
 111              * [#ANNO] Serializable {} 
 112              * then append annotations on [#ANNO]
 113              *
 114              * input should be like [@anno]
 115              */
 116             public String genTestCase(String str) {
 117                 if (null == str) {
 118                     throw new RuntimeException("bad test case.");
 119                 }
 120                 String testCode = "";
 121                 int clsIdx = testInput.size();
 122                 TestCodeGenerator tcg = new TestCodeGenerator();
 123                 tcg.put(Helper.Declaration.INTERFACE, typeAnnoIntName + clsIdx);
 124                 tcg.put(Helper.Declaration.EXTENDS, str + " Serializable");
 125                 tcg.put(Helper.Declaration.CLASS_BODY_START, "");
 126                 tcg.put(Helper.Declaration.CLASS_BODY_END, "");
 127                 testCode += tcg.genTestCode();
 128                 testInput.put(typeAnnoIntName + clsIdx, str);
 129                 return testCode;
 130             }
 131         },
 132         SINGLECLS() {
 133             /**
 134              * generate single class: 
 135              * [#ANNO] class TypeAnnoCls3 { } 
 136              * then append annotations on [#ANNO]
 137              *
 138              * input should be like [@anno]
 139              */
 140             public String genTestCase(String str) {
 141                 if (null == str) {
 142                     throw new RuntimeException("bad test case.");
 143                 }
 144                 String testCode = "";
 145                 int clsIdx = testInput.size();
 146                 TestCodeGenerator tcg = new TestCodeGenerator();
 147                 tcg.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
 148                 tcg.put(Helper.Declaration.CLASS_BODY_START, "");
 149                 tcg.put(Helper.Declaration.CLASS_BODY_END, "");
 150                 testCode += tcg.genTestCode();
 151                 testInput.put(typeAnnoClsName + clsIdx, "");
 152                 return testCode;
 153             }
 154         },
 155         CLSIMPINTS() {
 156             /**
 157              * generate cls implements interface: 
 158              * [#ANNO] class TypeAnnoCls4 implements 
 159              * [#ANNO] Serializable, [#ANNO] Cloneable {} 
 160              * then append annotations on [#ANNO]
 161              *
 162              * input should be like [@anno]
 163              */
 164             public String genTestCase(String str) {
 165                 if (null == str) {
 166                     throw new RuntimeException("bad test case.");
 167                 }
 168                 String testCode = "";
 169                 int clsIdx = testInput.size();
 170                 TestCodeGenerator tcg = new TestCodeGenerator();
 171                 tcg.put(Helper.Declaration.CLASS, typeAnnoClsName + clsIdx);
 172                 tcg.put(Helper.Declaration.IMPLEMENTS, new String[]{
 173                     str + " Serializable", str + " Cloneable"});
 174                 tcg.put(Helper.Declaration.CLASS_BODY_START, "");
 175                 tcg.put(Helper.Declaration.CLASS_BODY_END, "");
 176                 testCode += tcg.genTestCode();
 177                 testInput.put(typeAnnoClsName + clsIdx, str);
 178                 return testCode;
 179             }
 180         };
 181         
 182         // a place to hold class name -- annotation correspondence
 183         public static Map<String, String> testInput = new LinkedHashMap<>();
 184 
 185         // generate test class of a specific case
 186         public String genTestCase(String str) {
 187             return "";
 188         }
 189     }
 190 
 191     // generate source code for test according to TestCase
 192     protected String genTestCode(Class<? extends TestCaseGenerator> tcg) {
 193         String testCode = "";
 194         testCode += super.genTestCode(tcg);
 195         
 196         // special cases
 197         TestCase.testInput.put("Object.class", "");
 198         TestCase.testInput.put("int.class", "");
 199         TestCase.testInput.put("void.class", "");
 200         return testCode;
 201     }
 202 
 203     // compare input with result
 204     protected boolean checkResult() throws Exception {
 205         boolean ret = true;
 206         compileCode(TestCase.class);
 207         for (String clsName : TestCase.testInput.keySet()) {
 208             if (null == clsName) {
 209                 continue;
 210             }
 211             Class cls = loadClass(clsName);
 212             AnnotatedType[] as = cls.getAnnotatedInterfaces();
 213             List<String> result = Helper.getMultipleAT(as);
 214             if (0 == result.size()) {
 215                 if (!"".equals(TestCase.testInput.get(clsName))) {
 216                     // should be empty output
 217                     ret = false;
 218                     Helper.debugPrint(clsName.toString()
 219                             + " failed without empty output.");
 220                 }
 221             } else {
 222                 for (int i = 0; i < result.size(); i++) {
 223                     if (!result.get(i).equals(TestCase.testInput.get(clsName))) {
 224                         // annotations not match
 225                         ret = false;
 226                         Helper.debugPrint(clsName.toString()
 227                                 + " failed with faulty annotations.");
 228                     }
 229                 }
 230             }
 231         }
 232         return ret;
 233     }
 234 
 235     public static void main(String[] args) throws Exception {
 236         new ClassGetAnnotatedInterfacesTest().test();
 237     }
 238 }