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