1 /* *******************************************************************
2 * Copyright (c) 2004 IBM
4 * This program and the accompanying materials are made available
5 * under the terms of the Common Public License v1.0
6 * which accompanies this distribution and is available at
7 * http://www.eclipse.org/legal/cpl-v10.html
10 * Andy Clement - initial implementation
11 * ******************************************************************/
13 package org.aspectj.apache.bcel.classfile.tests;
16 import java.io.IOException;
17 import java.util.Iterator;
18 import java.util.List;
20 import org.aspectj.apache.bcel.classfile.Attribute;
21 import org.aspectj.apache.bcel.classfile.ConstantPool;
22 import org.aspectj.apache.bcel.classfile.JavaClass;
23 import org.aspectj.apache.bcel.classfile.Utility;
24 import org.aspectj.apache.bcel.classfile.annotation.Annotation;
25 import org.aspectj.apache.bcel.classfile.annotation.AnnotationElementValue;
26 import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValue;
27 import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue;
28 import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePair;
29 import org.aspectj.apache.bcel.classfile.annotation.ElementValue;
30 import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue;
31 import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue;
32 import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
33 import org.aspectj.apache.bcel.util.SyntheticRepository;
36 public class RuntimeVisibleAnnotationAttributeTest extends BcelTestCase {
39 protected void setUp() throws Exception {
43 public void testSeeAnnotationsAsAttribute() throws ClassNotFoundException {
44 SyntheticRepository repos = createRepos("testcode.jar");
45 JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
46 ConstantPool pool = clazz.getConstantPool();
47 Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz);
48 assertTrue("Expected a RuntimeVisibleAnnotations attribute but found none",
52 public void testAnnotationsAttributeContainsRightData() throws ClassNotFoundException {
53 SyntheticRepository repos = createRepos("testcode.jar");
54 JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
55 ConstantPool pool = clazz.getConstantPool();
56 Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz);
57 RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) rvaAttr[0];
58 List anns = rva.getAnnotations();
59 assertTrue("Should be one annotation but found "+anns.size(),
61 Annotation ann = (Annotation) anns.get(0);
62 assertTrue("Should be called 'SimpleAnnotation' but was called "+ann.getTypeName(),
63 ann.getTypeName().equals("SimpleAnnotation"));
64 List l = ann.getValues();
65 assertTrue("Should be one value for annotation 'SimpleAnnotation' but found "+l.size(),
67 ElementNameValuePair envp = (ElementNameValuePair)l.get(0);
68 assertTrue("Name of element in SimpleAnnotation should be 'id' but it is "+envp.getNameString(),
69 envp.getNameString().equals("id"));
70 SimpleElementValue evalue = (SimpleElementValue)envp.getValue();
71 assertTrue("'id' should be of type int, but it is "+evalue.getElementValueType(),evalue.getElementValueType()==SimpleElementValue.PRIMITIVE_INT);
72 assertTrue("'id' should have value 4 but it is "+evalue.getValueInt(),
73 evalue.getValueInt()==4);
76 public void testAccessingAnnotationsOnClazz() throws ClassNotFoundException {
77 SyntheticRepository repos = createRepos("testcode.jar");
78 JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
79 ConstantPool pool = clazz.getConstantPool();
80 Annotation[] anns = clazz.getAnnotations();
81 assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length,
85 public void testReadingWritingAnnotations() throws ClassNotFoundException, IOException {
86 SyntheticRepository repos = createRepos("testcode.jar");
87 JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
88 ConstantPool pool = clazz.getConstantPool();
89 Annotation[] anns = clazz.getAnnotations();
90 assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length,
94 File tfile = createTestdataFile("SimpleAnnotatedClass.class");
97 SyntheticRepository repos2 = createRepos(".");
98 JavaClass clazz2 = repos.loadClass("SimpleAnnotatedClass");
99 ConstantPool pool2 = clazz2.getConstantPool();
100 Annotation[] anns2 = clazz2.getAnnotations();
101 assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns2.length,
104 assertTrue(tfile.delete());
110 // Test for annotations containing string elements
112 public void testAnnotationStringElement() throws ClassNotFoundException {
113 SyntheticRepository repos = createRepos("testcode.jar");
114 JavaClass clazz = repos.loadClass("AnnotatedClass");
115 verifyAnnotationStringElement(clazz);
119 public void testAnnotationStringElementReadWrite() throws ClassNotFoundException, IOException {
120 SyntheticRepository repos = createRepos("testcode.jar");
121 JavaClass clazz = repos.loadClass("AnnotatedClass");
122 verifyAnnotationStringElement(clazz);
125 File tfile = createTestdataFile("AnnotatedClass.class");
128 SyntheticRepository repos2 = createRepos(".");
129 JavaClass clazz2 = repos2.loadClass("AnnotatedClass");
130 verifyAnnotationStringElement(clazz2);
132 assertTrue(tfile.delete());
135 private void verifyAnnotationStringElement(JavaClass clazz) {
136 Annotation[] anns = clazz.getAnnotations();
137 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
138 Annotation ann = anns[0];
139 assertTrue("should be called 'AnnotationStringElement' but was called "+ann.getTypeName(),
140 ann.getTypeName().equals("AnnotationStringElement"));
141 List l = ann.getValues();
142 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
143 ElementNameValuePair nvp = (ElementNameValuePair)l.get(0);
144 assertTrue("Name of element should be 'stringval' but was "+nvp.getNameString(),
145 nvp.getNameString().equals("stringval"));
146 SimpleElementValue ev = (SimpleElementValue)nvp.getValue();
147 assertTrue("String value should be 'hello' but was '"+ev.getValueString()+"'",
148 ev.getValueString().equals("hello"));
152 // Test for complex annotation that includes all primitives
154 public void testComplexAnnotation() throws ClassNotFoundException {
155 SyntheticRepository repos = createRepos("testcode.jar");
156 JavaClass clazz = repos.loadClass("ComplexAnnotatedClass");
157 verifyComplexAnnotation(clazz);
161 public void testComplexAnnotationsReadWrite() throws ClassNotFoundException, IOException {
162 SyntheticRepository repos = createRepos("testcode.jar");
163 JavaClass clazz = repos.loadClass("ComplexAnnotatedClass");
164 verifyComplexAnnotation(clazz);
167 File tfile = createTestdataFile("ComplexAnnotatedClass.class");
170 SyntheticRepository repos2 = createRepos(".");
171 JavaClass clazz2 = repos.loadClass("ComplexAnnotatedClass");
172 verifyComplexAnnotation(clazz2);
174 assertTrue(tfile.delete());
178 private void verifyComplexAnnotation(JavaClass clazz) {
179 Annotation[] anns = clazz.getAnnotations();
180 assertTrue("Should be one annotation but found "+anns.length,anns.length==1);
181 Annotation ann = anns[0];
182 assertTrue("Should be called 'ComplexAnnotation' but was called "+ann.getTypeName(),
183 ann.getTypeName().equals("ComplexAnnotation"));
184 List l = ann.getValues();
185 assertTrue("Should be eight values for annotation 'ComplexAnnotation' but found "+l.size(),
187 List names = Utility.getListOfAnnotationNames(ann);
188 assertTrue("Cant find expected element ",names.contains("ival"));
189 assertTrue("Cant find expected element ",names.contains("dval"));
190 assertTrue("Cant find expected element ",names.contains("zval"));
191 assertTrue("Cant find expected element ",names.contains("fval"));
192 assertTrue("Cant find expected element ",names.contains("jval"));
193 assertTrue("Cant find expected element ",names.contains("sval"));
194 assertTrue("Cant find expected element ",names.contains("bval"));
195 assertTrue("Cant find expected element ",names.contains("cval"));
197 checkValue(ann,"ival","4");
198 checkValue(ann,"jval","56");
199 checkValue(ann,"fval","3.0");
200 checkValue(ann,"dval","33.4");
201 checkValue(ann,"sval","99");
202 checkValue(ann,"bval","2");
203 checkValue(ann,"cval","5");
204 checkValue(ann,"zval","false");
208 private void checkValue(Annotation a,String name,String tostring) {
209 for (Iterator i = a.getValues().iterator(); i.hasNext();) {
210 ElementNameValuePair element = (ElementNameValuePair) i.next();
211 if (element.getNameString().equals(name)) {
212 if (!element.getValue().stringifyValue().equals(tostring)) {
213 fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue());
218 fail("Didnt find named element "+name);
222 // Test an annotation containing a 'Class' element
224 public void testAnnotationClassElement() throws ClassNotFoundException {
225 SyntheticRepository repos = createRepos("testcode.jar");
226 JavaClass clazz = repos.loadClass("AnnotatedWithClassClass");
227 verifyClassAnnotation(clazz);
230 public void testAnnotationClassElementReadWrite() throws ClassNotFoundException,IOException {
231 SyntheticRepository repos = createRepos("testcode.jar");
232 JavaClass clazz = repos.loadClass("AnnotatedWithClassClass");
233 verifyClassAnnotation(clazz);
236 File tfile = createTestdataFile("AnnotatedWithClassClass.class");
239 SyntheticRepository repos2 = createRepos(".");
240 JavaClass clazz2 = repos2.loadClass("AnnotatedWithClassClass");
241 verifyClassAnnotation(clazz2);
243 assertTrue(wipe("AnnotatedWithClassClass.class"));
246 private void verifyClassAnnotation(JavaClass clazz) {
247 Annotation[] anns = clazz.getAnnotations();
248 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
249 Annotation ann = anns[0];
250 assertTrue("should be called 'AnnotationClassElement' but was called "+ann.getTypeName(),
251 ann.getTypeName().equals("AnnotationClassElement"));
252 List l = ann.getValues();
253 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
254 ElementNameValuePair nvp = (ElementNameValuePair)l.get(0);
255 assertTrue("Name of element should be 'clz' but was "+nvp.getNameString(),
256 nvp.getNameString().equals("clz"));
257 ClassElementValue ev = (ClassElementValue)nvp.getValue();
258 assertTrue("String value should be 'Ljava/lang/Integer;' but was '"+ev.getClassString()+"'",
259 ev.getClassString().equals("Ljava/lang/Integer;"));
264 // Test an annotation containing an enum element
266 public void testAnnotationEnumElement() throws ClassNotFoundException {
267 SyntheticRepository repos = createRepos("testcode.jar");
268 JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass");
269 verifyAnnotationEnumElement(clazz);
272 public void testAnnotationEnumElementReadWrite() throws ClassNotFoundException, IOException {
273 SyntheticRepository repos = createRepos("testcode.jar");
274 JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass");
275 verifyAnnotationEnumElement(clazz);
278 File tfile = createTestdataFile("AnnotatedWithEnumClass.class");
281 SyntheticRepository repos2 = createRepos(".");
282 JavaClass clazz2 = repos2.loadClass("AnnotatedWithEnumClass");
283 verifyAnnotationEnumElement(clazz2);
285 assertTrue(tfile.delete());
288 public void verifyAnnotationEnumElement(JavaClass clazz) {
289 Annotation[] anns = clazz.getAnnotations();
290 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
291 Annotation ann = anns[0];
292 assertTrue("should be called 'AnnotationEnumElement' but was called "+ann.getTypeName(),
293 ann.getTypeName().equals("AnnotationEnumElement"));
294 List l = ann.getValues();
295 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
296 ElementNameValuePair nvp = (ElementNameValuePair)l.get(0);
297 assertTrue("Name of element should be 'enumval' but was "+nvp.getNameString(),
298 nvp.getNameString().equals("enumval"));
299 ElementValue ev = nvp.getValue();
300 assertTrue("Should be of type EnumElementValue but is "+ev,ev instanceof EnumElementValue);
301 EnumElementValue eev = (EnumElementValue)ev;
302 assertTrue("Should be an enum type value but is "+eev.getElementValueType(),eev.getElementValueType()==SimpleElementValue.ENUM_CONSTANT);
303 assertTrue("Enum type for annotation should be 'SimpleEnum' but is "+eev.getEnumTypeString(),eev.getEnumTypeString().equals("SimpleEnum"));
304 assertTrue("String value should be 'Red' but was '"+eev.getEnumValueString()+"'",
305 eev.getEnumValueString().equals("Red"));
309 // Test an annotation with an array element
311 public void testAnnotationArraysOfAnnotations() throws ClassNotFoundException {
312 SyntheticRepository repos = createRepos("testcode.jar");
313 JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation");
314 Annotation[] anns = clazz.getAnnotations();
315 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
316 checkCombinedAnnotation(anns[0]);
319 public void testAnnotationArraysOfAnnotationsReadWrite() throws ClassNotFoundException, IOException {
320 SyntheticRepository repos = createRepos("testcode.jar");
321 JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation");
322 Annotation[] anns = clazz.getAnnotations();
323 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
324 checkCombinedAnnotation(anns[0]);
327 File tfile = createTestdataFile("AnnotatedWithCombinedAnnotation.class");
330 SyntheticRepository repos2 = createRepos(".");
331 JavaClass clazz2 = repos2.loadClass("AnnotatedWithCombinedAnnotation");
332 Annotation[] anns2 = clazz2.getAnnotations();
333 assertTrue("should be one annotation but found "+anns2.length,anns2.length==1);
334 checkCombinedAnnotation(anns2[0]);
336 assertTrue(tfile.delete());
340 private void checkCombinedAnnotation(Annotation ann) {
341 assertTrue("should be called 'CombinedAnnotation' but was called "+ann.getTypeName(),
342 ann.getTypeName().equals("CombinedAnnotation"));
343 List l = ann.getValues();
344 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
345 ElementNameValuePair nvp = (ElementNameValuePair)l.get(0);
346 assertTrue("Name of element should be 'value' but was "+nvp.getNameString(),
347 nvp.getNameString().equals("value"));
348 ElementValue ev = nvp.getValue();
349 assertTrue("Should be of type ArrayElementValue but is "+ev,ev instanceof ArrayElementValue);
350 ArrayElementValue aev = (ArrayElementValue)ev;
352 assertTrue("Array element value should be of size 1 but is "+aev.getElementValuesArraySize(),
353 aev.getElementValuesArraySize()==1);
354 ElementValue[] evs = aev.getElementValuesArray();
355 assertTrue("Entry in the array should be AnnotationElementValue but is "+evs[0],
356 evs[0] instanceof AnnotationElementValue);
357 AnnotationElementValue inner_ev = (AnnotationElementValue)evs[0];
358 Annotation a = inner_ev.getAnnotation();
359 assertTrue("Should be SimpleAnnotation but is "+a.getTypeName(),a.getTypeName().equals("SimpleAnnotation"));
360 List envps = a.getValues();
361 assertTrue("Should be one name value pair but found "+envps.size(),envps.size()==1);
362 ElementNameValuePair envp = (ElementNameValuePair) envps.get(0);
363 assertTrue("Name should be 'id' but it is "+envp.getNameString(),envp.getNameString().equals("id"));
364 assertTrue("Value of 'id' should be 4 but it is "+envp.getValue().stringifyValue(),
365 envp.getValue().stringifyValue().equals("4"));
369 protected void tearDown() throws Exception {