You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

RuntimeVisibleAnnotationAttributeTest.java 16KB

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