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