]> source.dussan.org Git - aspectj.git/blob
1872aed0fa3a658ec6dcd33948aef5411f040dfe
[aspectj.git] /
1 /* *******************************************************************
2  * Copyright (c) 2004 IBM
3  * All rights reserved. 
4  * This program and the accompanying materials are made available 
5  * under the terms of the Eclipse Public License v1.0 
6  * which accompanies this distribution and is available at 
7  * http://www.eclipse.org/legal/epl-v10.html 
8  *  
9  * Contributors: 
10  *     Andy Clement -     initial implementation 
11  * ******************************************************************/
12
13 package org.aspectj.apache.bcel.classfile.tests;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.util.Iterator;
18 import java.util.List;
19
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.AnnotationElementValueGen;
25 import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
26 import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
27 import org.aspectj.apache.bcel.classfile.annotation.ClassElementValueGen;
28 import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
29 import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
30 import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;
31 import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
32 import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValueGen;
33 import org.aspectj.apache.bcel.generic.ClassGen;
34 import org.aspectj.apache.bcel.util.SyntheticRepository;
35
36
37 public class RuntimeVisibleAnnotationAttributeTest extends BcelTestCase {
38         
39
40         protected void setUp() throws Exception {
41                 super.setUp();
42         }
43         
44         public void testSeeAnnotationsAsAttribute() throws ClassNotFoundException {
45                 SyntheticRepository repos = createRepos("testcode.jar");
46                 JavaClass           clazz = repos.loadClass("SimpleAnnotatedClass");
47                 ConstantPool pool = clazz.getConstantPool();
48                 Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz);
49                 assertTrue("Expected a RuntimeVisibleAnnotations attribute but found none",
50                                 rvaAttr.length==1);
51         }
52         
53         public void testAnnotationsAttributeContainsRightData() throws ClassNotFoundException {
54                 SyntheticRepository repos = createRepos("testcode.jar");
55                 JavaClass           clazz = repos.loadClass("SimpleAnnotatedClass");
56                 ConstantPool pool = clazz.getConstantPool();
57                 Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz);
58                 RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) rvaAttr[0];
59                 List anns = rva.getAnnotations();
60                 assertTrue("Should be one annotation but found "+anns.size(),
61                                    anns.size()==1);
62                 AnnotationGen ann = (AnnotationGen) anns.get(0);
63                 assertTrue("Should be called 'SimpleAnnotation' but was called "+ann.getTypeName(),
64                                 ann.getTypeName().equals("SimpleAnnotation"));
65                 List l = ann.getValues();
66                 assertTrue("Should be one value for annotation 'SimpleAnnotation' but found "+l.size(),
67                                 l.size()==1);
68                 ElementNameValuePairGen envp = (ElementNameValuePairGen)l.get(0);
69                 assertTrue("Name of element in SimpleAnnotation should be 'id' but it is "+envp.getNameString(),
70                                 envp.getNameString().equals("id"));
71                 SimpleElementValueGen evalue = (SimpleElementValueGen)envp.getValue();
72                 assertTrue("'id' should be of type int, but it is "+evalue.getElementValueType(),evalue.getElementValueType()==SimpleElementValueGen.PRIMITIVE_INT);
73                 assertTrue("'id' should have value 4 but it is "+evalue.getValueInt(),
74                                 evalue.getValueInt()==4);
75         }
76         
77         public void testAccessingAnnotationsOnClazz() throws ClassNotFoundException {
78                 SyntheticRepository repos = createRepos("testcode.jar");
79                 JavaClass           clazz = repos.loadClass("SimpleAnnotatedClass");
80                 ConstantPool pool = clazz.getConstantPool();
81                 AnnotationGen[] anns = clazz.getAnnotations();
82                 assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length,
83                                 anns.length==1);
84         }
85         
86         public void testReadingWritingAnnotations() throws ClassNotFoundException, IOException {
87                 SyntheticRepository repos = createRepos("testcode.jar");
88                 JavaClass           clazz = repos.loadClass("SimpleAnnotatedClass");
89                 ConstantPool pool = clazz.getConstantPool();
90                 AnnotationGen[] anns = clazz.getAnnotations();
91                 assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length,
92                                 anns.length==1);
93                 
94                 //       Write it out
95                 File tfile = createTestdataFile("SimpleAnnotatedClass.class");
96                 clazz.dump(tfile);
97         
98                 SyntheticRepository repos2 = createRepos(".");
99                 JavaClass           clazz2 = repos.loadClass("SimpleAnnotatedClass");
100                 ConstantPool pool2 = clazz2.getConstantPool();
101                 AnnotationGen[] anns2 = clazz2.getAnnotations();
102                 assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns2.length,
103                                 anns2.length==1);
104                 
105                 assertTrue(tfile.delete());
106         }
107         
108         
109         
110         ////
111         // Test for annotations containing string elements
112         
113         public void testAnnotationStringElement() throws ClassNotFoundException {
114                 SyntheticRepository repos = createRepos("testcode.jar");
115                 JavaClass           clazz = repos.loadClass("AnnotatedClass");
116                 verifyAnnotationStringElement(clazz);
117         }
118         
119
120         public void testAnnotationStringElementReadWrite() throws ClassNotFoundException, IOException {
121                 SyntheticRepository repos = createRepos("testcode.jar");
122                 JavaClass           clazz = repos.loadClass("AnnotatedClass");
123                 verifyAnnotationStringElement(clazz);
124                 
125                 //       Write it out
126                 File tfile = createTestdataFile("AnnotatedClass.class");
127                 clazz.dump(tfile);
128                 
129                 SyntheticRepository repos2 = createRepos(".");
130                 JavaClass           clazz2 = repos2.loadClass("AnnotatedClass");
131                 verifyAnnotationStringElement(clazz2);  
132
133                 assertTrue(tfile.delete());
134         }
135
136         private void verifyAnnotationStringElement(JavaClass clazz) {
137                 AnnotationGen[] anns = clazz.getAnnotations();
138                 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
139                 AnnotationGen ann = anns[0];
140                 assertTrue("should be called 'AnnotationStringElement' but was called "+ann.getTypeName(),
141                                 ann.getTypeName().equals("AnnotationStringElement"));
142                 List l = ann.getValues();
143                 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
144                 ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
145                 assertTrue("Name of element should be 'stringval' but was "+nvp.getNameString(),
146                                 nvp.getNameString().equals("stringval"));
147                 SimpleElementValueGen ev = (SimpleElementValueGen)nvp.getValue();
148                 assertTrue("String value should be 'hello' but was '"+ev.getValueString()+"'",
149                                 ev.getValueString().equals("hello"));
150         }
151         
152         ////
153         // Test for complex annotation that includes all primitives
154         
155         public void testComplexAnnotation() throws ClassNotFoundException {
156                 SyntheticRepository repos = createRepos("testcode.jar");
157                 JavaClass           clazz = repos.loadClass("ComplexAnnotatedClass");
158                 verifyComplexAnnotation(clazz);
159         }
160         
161
162         public void testComplexAnnotationsReadWrite() throws ClassNotFoundException, IOException {
163                 SyntheticRepository repos = createRepos("testcode.jar");
164                 JavaClass           clazz = repos.loadClass("ComplexAnnotatedClass");
165                 verifyComplexAnnotation(clazz);
166
167                 //       Write it out
168                 File tfile = createTestdataFile("ComplexAnnotatedClass.class");
169                 clazz.dump(tfile);
170                 
171                 SyntheticRepository repos2 = createRepos(".");
172                 JavaClass           clazz2 = repos.loadClass("ComplexAnnotatedClass");
173                 verifyComplexAnnotation(clazz2);
174                 
175                 assertTrue(tfile.delete());
176                 
177         }
178         
179         private void verifyComplexAnnotation(JavaClass clazz) {
180                 AnnotationGen[] anns = clazz.getAnnotations();
181                 assertTrue("Should be one annotation but found "+anns.length,anns.length==1);
182                 AnnotationGen ann = anns[0];
183                 assertTrue("Should be called 'ComplexAnnotation' but was called "+ann.getTypeName(),
184                                 ann.getTypeName().equals("ComplexAnnotation"));
185                 List l = ann.getValues();
186                 assertTrue("Should be eight values for annotation 'ComplexAnnotation' but found "+l.size(),
187                                 l.size()==8);
188                 List names = Utility.getListOfAnnotationNames(ann);
189                 assertTrue("Cant find expected element ",names.contains("ival"));
190                 assertTrue("Cant find expected element ",names.contains("dval"));
191                 assertTrue("Cant find expected element ",names.contains("zval"));
192                 assertTrue("Cant find expected element ",names.contains("fval"));
193                 assertTrue("Cant find expected element ",names.contains("jval"));
194                 assertTrue("Cant find expected element ",names.contains("sval"));
195                 assertTrue("Cant find expected element ",names.contains("bval"));
196                 assertTrue("Cant find expected element ",names.contains("cval"));
197                 
198                 checkValue(ann,"ival","4");
199                 checkValue(ann,"jval","56");
200                 checkValue(ann,"fval","3.0");
201                 checkValue(ann,"dval","33.4");
202                 checkValue(ann,"sval","99");
203                 checkValue(ann,"bval","2");
204                 checkValue(ann,"cval",new Character('5').toString());
205                 checkValue(ann,"zval","false");
206                 
207         }
208
209         private void checkValue(AnnotationGen a,String name,String tostring) {
210                 for (Iterator i = a.getValues().iterator(); i.hasNext();) {
211                         ElementNameValuePairGen element = (ElementNameValuePairGen) i.next();
212                         if (element.getNameString().equals(name)) {
213                                 if (!element.getValue().stringifyValue().equals(tostring)) {
214                                         fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue());
215                                 }
216                                 return;
217                         }
218                 }
219                 fail("Didnt find named element "+name);
220         }
221
222         ////
223         // Test an annotation containing a 'Class' element
224         
225         public void testAnnotationClassElement() throws ClassNotFoundException {
226                 SyntheticRepository repos = createRepos("testcode.jar");
227                 JavaClass           clazz = repos.loadClass("AnnotatedWithClassClass");
228                 verifyClassAnnotation(clazz);
229         }
230         
231         public void testAnnotationClassElementCopying() throws ClassNotFoundException {
232                 SyntheticRepository repos = createRepos("testcode.jar");
233                 JavaClass           clazz = repos.loadClass("AnnotatedWithClassClass");
234                 AnnotationGen[] anns = clazz.getAnnotations();
235                 ClassGen cg = new ClassGen(clazz);
236                 // Checks we can copy class values in an annotation
237                 new AnnotationGen(anns[0],cg.getConstantPool(),true);
238                 new AnnotationGen(anns[0],cg.getConstantPool(),false);
239         }
240         
241         public void testAnnotationClassElementReadWrite() throws ClassNotFoundException,IOException {
242                 SyntheticRepository repos = createRepos("testcode.jar");
243                 JavaClass           clazz = repos.loadClass("AnnotatedWithClassClass");
244                 verifyClassAnnotation(clazz);
245
246                 //       Write it out
247                 File tfile = createTestdataFile("AnnotatedWithClassClass.class");
248                 clazz.dump(tfile);
249                 
250                 SyntheticRepository repos2 = createRepos(".");
251                 JavaClass           clazz2 = repos2.loadClass("AnnotatedWithClassClass");
252                 verifyClassAnnotation(clazz2);
253                 
254                 assertTrue(wipe("AnnotatedWithClassClass.class"));
255         }
256         
257         private void verifyClassAnnotation(JavaClass clazz) {
258                 AnnotationGen[] anns = clazz.getAnnotations();
259                 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
260                 AnnotationGen ann = anns[0];
261                 assertTrue("should be called 'AnnotationClassElement' but was called "+ann.getTypeName(),
262                                 ann.getTypeName().equals("AnnotationClassElement"));
263                 List l = ann.getValues();
264                 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
265                 ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
266                 assertTrue("Name of element should be 'clz' but was "+nvp.getNameString(),
267                                 nvp.getNameString().equals("clz"));
268                 ClassElementValueGen ev = (ClassElementValueGen)nvp.getValue();
269                 assertTrue("String value should be 'Ljava/lang/Integer;' but was '"+ev.getClassString()+"'",
270                                 ev.getClassString().equals("Ljava/lang/Integer;"));
271                 
272         }
273         
274         ////
275         // Test an annotation containing an enum element
276         
277         public void testAnnotationEnumElement() throws ClassNotFoundException {
278                 SyntheticRepository repos = createRepos("testcode.jar");
279                 JavaClass           clazz = repos.loadClass("AnnotatedWithEnumClass");
280                 verifyAnnotationEnumElement(clazz);
281         }
282                 
283         public void testAnnotationEnumElementReadWrite() throws ClassNotFoundException, IOException {
284                 SyntheticRepository repos = createRepos("testcode.jar");
285                 JavaClass           clazz = repos.loadClass("AnnotatedWithEnumClass");
286                 verifyAnnotationEnumElement(clazz);
287
288                 //       Write it out
289                 File tfile = createTestdataFile("AnnotatedWithEnumClass.class");
290                 clazz.dump(tfile);
291                 
292                 SyntheticRepository repos2 = createRepos(".");
293                 JavaClass           clazz2 = repos2.loadClass("AnnotatedWithEnumClass");
294                 verifyAnnotationEnumElement(clazz2);
295                 
296                 assertTrue(tfile.delete());
297         }
298         
299         public void verifyAnnotationEnumElement(JavaClass clazz) {
300                 AnnotationGen[] anns = clazz.getAnnotations();
301                 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
302                 AnnotationGen ann = anns[0];
303                 assertTrue("should be called 'AnnotationEnumElement' but was called "+ann.getTypeName(),
304                                 ann.getTypeName().equals("AnnotationEnumElement"));
305                 List l = ann.getValues();
306                 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
307                 ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
308                 assertTrue("Name of element should be 'enumval' but was "+nvp.getNameString(),
309                                 nvp.getNameString().equals("enumval"));
310                 ElementValueGen ev = nvp.getValue();
311                 assertTrue("Should be of type EnumElementValue but is "+ev,ev instanceof EnumElementValueGen);
312                 EnumElementValueGen eev = (EnumElementValueGen)ev;
313                 assertTrue("Should be an enum type value but is "+eev.getElementValueType(),eev.getElementValueType()==SimpleElementValueGen.ENUM_CONSTANT);
314                 assertTrue("Enum type for annotation should be 'SimpleEnum' but is "+Utility.signatureToString(eev.getEnumTypeString()),Utility.signatureToString(eev.getEnumTypeString()).equals("SimpleEnum"));
315                 assertTrue("String value should be 'Red' but was '"+eev.getEnumValueString()+"'",
316                                 eev.getEnumValueString().equals("Red"));
317         }
318         
319         ////
320         // Test an annotation with an array element
321         
322         public void testAnnotationArraysOfAnnotations() throws ClassNotFoundException {
323                 SyntheticRepository repos = createRepos("testcode.jar");
324                 JavaClass           clazz = repos.loadClass("AnnotatedWithCombinedAnnotation");
325                 AnnotationGen[] anns = clazz.getAnnotations();
326                 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
327                 checkCombinedAnnotation(anns[0]);
328         }
329         
330         public void testAnnotationArraysOfAnnotationsReadWrite() throws ClassNotFoundException, IOException {
331                 SyntheticRepository repos = createRepos("testcode.jar");
332                 JavaClass           clazz = repos.loadClass("AnnotatedWithCombinedAnnotation");
333                 AnnotationGen[] anns = clazz.getAnnotations();
334                 assertTrue("should be one annotation but found "+anns.length,anns.length==1);
335                 checkCombinedAnnotation(anns[0]);
336                 
337                 //       Write it out
338                 File tfile = createTestdataFile("AnnotatedWithCombinedAnnotation.class");
339                 clazz.dump(tfile);
340                 
341                 SyntheticRepository repos2 = createRepos(".");
342                 JavaClass           clazz2 = repos2.loadClass("AnnotatedWithCombinedAnnotation");
343                 AnnotationGen[] anns2 = clazz2.getAnnotations();
344                 assertTrue("should be one annotation but found "+anns2.length,anns2.length==1);
345                 checkCombinedAnnotation(anns2[0]);
346
347                 assertTrue(tfile.delete());
348         }
349         
350         
351         private void checkCombinedAnnotation(AnnotationGen ann) {
352                 assertTrue("should be called 'CombinedAnnotation' but was called "+ann.getTypeName(),
353                                 ann.getTypeName().equals("CombinedAnnotation"));
354                 List l = ann.getValues();
355                 assertTrue("Should be one value but there were "+l.size(),l.size()==1);
356                 ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
357                 assertTrue("Name of element should be 'value' but was "+nvp.getNameString(),
358                                 nvp.getNameString().equals("value"));
359                 ElementValueGen ev = nvp.getValue();
360                 assertTrue("Should be of type ArrayElementValue but is "+ev,ev instanceof ArrayElementValueGen);
361                 ArrayElementValueGen aev = (ArrayElementValueGen)ev;
362                 
363                 assertTrue("Array element value should be of size 1 but is "+aev.getElementValuesArraySize(),
364                                 aev.getElementValuesArraySize()==1);
365                 ElementValueGen[] evs = aev.getElementValuesArray();
366                 assertTrue("Entry in the array should be AnnotationElementValue but is "+evs[0],
367                                 evs[0] instanceof AnnotationElementValueGen);
368                 AnnotationElementValueGen inner_ev = (AnnotationElementValueGen)evs[0];
369                 AnnotationGen a = inner_ev.getAnnotation();
370                 assertTrue("Should be SimpleAnnotation but is "+a.getTypeName(),a.getTypeName().equals("SimpleAnnotation"));
371                 List envps = a.getValues();
372                 assertTrue("Should be one name value pair but found "+envps.size(),envps.size()==1);
373                 ElementNameValuePairGen envp = (ElementNameValuePairGen) envps.get(0);
374                 assertTrue("Name should be 'id' but it is "+envp.getNameString(),envp.getNameString().equals("id"));
375                 assertTrue("Value of 'id' should be 4 but it is "+envp.getValue().stringifyValue(),
376                                 envp.getValue().stringifyValue().equals("4"));
377         }
378         
379
380         protected void tearDown() throws Exception {
381                 super.tearDown();
382         }
383         
384 }