AnnotationDefaultTest.java revision 3294:9adfb22ff08f
1/* 2 * Copyright (c) 2014, 2015, 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 8042947 27 * @summary Checking AnnotationDefault attribute. 28 * @library /tools/lib /tools/javac/lib ../lib 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.file 31 * jdk.compiler/com.sun.tools.javac.main 32 * jdk.jdeps/com.sun.tools.classfile 33 * jdk.jdeps/com.sun.tools.javap 34 * @build AnnotationDefaultTest TestBase TestResult InMemoryFileManager ToolBox AnnotationDefaultVerifier 35 * @run main AnnotationDefaultTest 36 */ 37 38import com.sun.tools.classfile.*; 39 40import java.io.File; 41import java.io.IOException; 42import java.lang.annotation.RetentionPolicy; 43import java.nio.file.Files; 44import java.util.HashMap; 45import java.util.Map; 46import java.util.Objects; 47import java.util.function.Function; 48import java.util.stream.Collectors; 49import java.util.stream.Stream; 50 51public class AnnotationDefaultTest extends TestResult { 52 53 private final static String templateFileName = "AnnotationDefault.java.template"; 54 55 private final AnnotationDefaultVerifier verifier; 56 57 public AnnotationDefaultTest() { 58 verifier = new AnnotationDefaultVerifier(); 59 } 60 61 private void test(String template, Map<String, String> replacements, boolean hasDefault) { 62 String source = replace(template, replacements); 63 addTestCase(source); 64 try { 65 printf("Testing source:\n%s\n", source); 66 String className = "AnnotationDefault"; 67 InMemoryFileManager fileManager = compile(source); 68 69 // Map <method-name, expected-annotation-default-values> 70 Map<String, ExpectedValues> expectedValues = 71 getExpectedValues(forName(className, fileManager)); 72 ClassFile classFile = readClassFile(fileManager.getClasses().get(className)); 73 74 for (Method method : classFile.methods) { 75 String methodName = method.getName(classFile.constant_pool); 76 printf("Testing method : %s\n", methodName); 77 AnnotationDefault_attribute attr = 78 (AnnotationDefault_attribute) method.attributes 79 .get(Attribute.AnnotationDefault); 80 81 if (hasDefault && !checkNotNull(attr, "Attribute is not null") 82 || !hasDefault && checkNull(attr, "Attribute is null")) { 83 // stop checking, attr is null 84 continue; 85 } 86 87 checkEquals(countNumberOfAttributes(method.attributes.attrs), 88 1l, 89 "Number of AnnotationDefault attribute"); 90 checkEquals(classFile.constant_pool 91 .getUTF8Value(attr.attribute_name_index), 92 "AnnotationDefault", "attribute_name_index"); 93 94 ExpectedValues expectedValue = expectedValues.get(methodName); 95 checkEquals((char) attr.default_value.tag, expectedValue.tag(), 96 String.format("check tag : %c %s", expectedValue.tag(), expectedValue.name())); 97 verifier.testElementValue(attr.default_value.tag, 98 this, classFile, attr.default_value, 99 expectedValue.values()); 100 verifier.testLength(attr.default_value.tag, this, attr); 101 } 102 } catch (Exception e) { 103 addFailure(e); 104 } 105 } 106 107 private Class<?> forName(String className, InMemoryFileManager fileManager) throws ClassNotFoundException { 108 return fileManager.getClassLoader(null).loadClass(className); 109 } 110 111 private Map<String, ExpectedValues> getExpectedValues(Class<?> clazz) { 112 return Stream.of(clazz.getMethods()) 113 .map(method -> method.getAnnotation(ExpectedValues.class)) 114 .filter(Objects::nonNull) 115 .collect(Collectors.toMap( 116 ExpectedValues::name, 117 Function.identity())); 118 } 119 120 private String replace(String template, Map<String, String> replacements) { 121 String ans = template; 122 for (Map.Entry<String, String> replace : replacements.entrySet()) { 123 ans = ans.replaceAll(replace.getKey(), replace.getValue()); 124 } 125 return ans; 126 } 127 128 private long countNumberOfAttributes(Attribute[] attrs) { 129 return Stream.of(attrs) 130 .filter(x -> x instanceof AnnotationDefault_attribute) 131 .count(); 132 } 133 134 public String getSource(File templateFileName) throws IOException { 135 return Files.lines(templateFileName.toPath()) 136 .filter(str -> !str.startsWith("/*") && !str.startsWith(" *")) 137 .collect(Collectors.joining("\n")); 138 } 139 140 public void test() throws TestFailedException { 141 try { 142 String template = getSource(getSourceFile(templateFileName)); 143 for (int i = 0; i < 2; ++i) { 144 for (String repeatable : new String[] {"", "@Repeatable(Container.class)"}) { 145 for (RetentionPolicy policy : RetentionPolicy.values()) { 146 final int finalI = i; 147 Map<String, String> replacements = new HashMap<String, String>(){{ 148 put("%POLICY%", policy.toString()); 149 if (finalI != 0) { 150 put("default.*\n", ";\n"); 151 } 152 put("%REPEATABLE%", repeatable); 153 }}; 154 test(template, replacements, i == 0); 155 } 156 } 157 } 158 } catch (Throwable e) { 159 addFailure(e); 160 } finally { 161 checkStatus(); 162 } 163 } 164 165 public static void main(String[] args) throws TestFailedException { 166 new AnnotationDefaultTest().test(); 167 } 168} 169