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