1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.bcel.generic;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
23 import static org.junit.jupiter.api.Assertions.assertNotNull;
24 import static org.junit.jupiter.api.Assertions.assertNull;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26 import static org.junit.jupiter.api.Assertions.fail;
27
28 import java.io.File;
29 import java.util.ArrayList;
30 import java.util.List;
31
32 import org.apache.bcel.AbstractTest;
33 import org.apache.bcel.Const;
34 import org.apache.bcel.classfile.AnnotationEntry;
35 import org.apache.bcel.classfile.ArrayElementValue;
36 import org.apache.bcel.classfile.ElementValue;
37 import org.apache.bcel.classfile.ElementValuePair;
38 import org.apache.bcel.classfile.JavaClass;
39 import org.apache.bcel.classfile.Method;
40 import org.apache.bcel.classfile.ParameterAnnotationEntry;
41 import org.apache.bcel.classfile.SimpleElementValue;
42 import org.apache.bcel.util.SyntheticRepository;
43 import org.junit.jupiter.api.Test;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 class GeneratingAnnotatedClassesTest extends AbstractTest {
65 private void assertArrayElementValue(final int nExpectedArrayValues, final AnnotationEntry anno) {
66 final ElementValuePair elementValuePair = anno.getElementValuePairs()[0];
67 assertEquals("value", elementValuePair.getNameString());
68 final ArrayElementValue ev = (ArrayElementValue) elementValuePair.getValue();
69 final ElementValue[] eva = ev.getElementValuesArray();
70 assertEquals(nExpectedArrayValues, eva.length);
71 }
72
73 private void assertMethodAnnotations(final Method method, final int expectedNumberAnnotations, final int nExpectedArrayValues) {
74 final String methodName = method.getName();
75 final AnnotationEntry[] annos = method.getAnnotationEntries();
76 assertEquals(expectedNumberAnnotations, annos.length, () -> "For " + methodName);
77 if (expectedNumberAnnotations != 0) {
78 assertArrayElementValue(nExpectedArrayValues, annos[0]);
79 }
80 }
81
82 private void assertParameterAnnotations(final Method method, final int... expectedNumberOfParmeterAnnotations) {
83 final String methodName = "For " + method.getName();
84 final ParameterAnnotationEntry[] parameterAnnotations = method.getParameterAnnotationEntries();
85 assertEquals(expectedNumberOfParmeterAnnotations.length, parameterAnnotations.length, methodName);
86
87 int i = 0;
88 for (final ParameterAnnotationEntry parameterAnnotation : parameterAnnotations) {
89 final AnnotationEntry[] annos = parameterAnnotation.getAnnotationEntries();
90 final int expectedLength = expectedNumberOfParmeterAnnotations[i++];
91 final int j = i;
92 assertEquals(expectedLength, annos.length, () -> methodName + " parameter " + j);
93 if (expectedLength != 0) {
94 assertSimpleElementValue(annos[0]);
95 }
96 }
97 assertNotNull(method.getAttribute(Const.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS));
98 assertNull(method.getAttribute(Const.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS));
99 }
100
101 private void assertSimpleElementValue(final AnnotationEntry anno) {
102 final ElementValuePair elementValuePair = anno.getElementValuePairs()[0];
103 assertEquals("id", elementValuePair.getNameString());
104 final SimpleElementValue ev = (SimpleElementValue) elementValuePair.getValue();
105 assertEquals(42, ev.getValueInt());
106 }
107
108 private void buildClassContents(final ClassGen cg, final ConstantPoolGen cp, final InstructionList il) {
109
110 final MethodGen mg = createMethodGen("main", il, cp);
111 final InstructionFactory factory = new InstructionFactory(cg);
112
113 final ObjectType inStream = new ObjectType("java.io.InputStream");
114 final ObjectType printStream = new ObjectType("java.io.PrintStream");
115
116
117
118
119 il.append(factory.createNew("java.io.BufferedReader"));
120 il.append(InstructionConst.DUP);
121 il.append(factory.createNew("java.io.InputStreamReader"));
122 il.append(InstructionConst.DUP);
123 il.append(factory.createFieldAccess("java.lang.System", "in", inStream, Const.GETSTATIC));
124 il.append(factory.createInvoke("java.io.InputStreamReader", "<init>", Type.VOID, new Type[] {inStream}, Const.INVOKESPECIAL));
125 il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID, new Type[] {new ObjectType("java.io.Reader")}, Const.INVOKESPECIAL));
126 LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null);
127 final int in = lg.getIndex();
128 lg.setStart(il.append(new ASTORE(in)));
129
130 lg = mg.addLocalVariable("name", Type.STRING, null, null);
131 final int name = lg.getIndex();
132 il.append(InstructionConst.ACONST_NULL);
133 lg.setStart(il.append(new ASTORE(name)));
134
135
136
137
138
139
140
141
142
143
144
145 final InstructionHandle tryStart = il.append(new PUSH(cp, "Andy"));
146 il.append(new ASTORE(name));
147
148
149 final GOTO g = new GOTO(null);
150 final InstructionHandle tryEnd = il.append(g);
151
152 final LocalVariableGen varEx = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null);
153 final int varExSlot = varEx.getIndex();
154 final InstructionHandle handler = il.append(new ASTORE(varExSlot));
155 varEx.setStart(handler);
156 varEx.setEnd(il.append(InstructionConst.RETURN));
157 mg.addExceptionHandler(tryStart, tryEnd, handler, new ObjectType("java.io.IOException"));
158
159
160 final InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", printStream, Const.GETSTATIC));
161 g.setTarget(ih);
162
163
164 il.append(factory.createNew(Type.STRINGBUFFER));
165 il.append(InstructionConst.DUP);
166 il.append(new PUSH(cp, "Hello, "));
167 il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, new Type[] {Type.STRING}, Const.INVOKESPECIAL));
168 il.append(new ALOAD(name));
169 il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
170 il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Const.INVOKEVIRTUAL));
171 il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
172 il.append(InstructionConst.RETURN);
173
174
175
176 mg.setMaxStack();
177 mg.setMaxLocals();
178 cg.addMethod(mg.getMethod());
179 il.dispose();
180 cg.addEmptyConstructor(Const.ACC_PUBLIC);
181 }
182
183 private void buildClassContentsWithAnnotatedMethods(final ClassGen cg, final ConstantPoolGen cp, final InstructionList il) {
184
185 final MethodGen mg = createMethodGen("main", il, cp);
186 final InstructionFactory factory = new InstructionFactory(cg);
187 mg.addAnnotationEntry(createSimpleVisibleAnnotation(mg.getConstantPool()));
188
189 final ObjectType inStream = new ObjectType("java.io.InputStream");
190 final ObjectType printStream = new ObjectType("java.io.PrintStream");
191
192
193
194
195 il.append(factory.createNew("java.io.BufferedReader"));
196 il.append(InstructionConst.DUP);
197 il.append(factory.createNew("java.io.InputStreamReader"));
198 il.append(InstructionConst.DUP);
199 il.append(factory.createFieldAccess("java.lang.System", "in", inStream, Const.GETSTATIC));
200 il.append(factory.createInvoke("java.io.InputStreamReader", "<init>", Type.VOID, new Type[] {inStream}, Const.INVOKESPECIAL));
201 il.append(factory.createInvoke("java.io.BufferedReader", "<init>", Type.VOID, new Type[] {new ObjectType("java.io.Reader")}, Const.INVOKESPECIAL));
202 LocalVariableGen lg = mg.addLocalVariable("in", new ObjectType("java.io.BufferedReader"), null, null);
203 final int in = lg.getIndex();
204 lg.setStart(il.append(new ASTORE(in)));
205
206 lg = mg.addLocalVariable("name", Type.STRING, null, null);
207 final int name = lg.getIndex();
208 il.append(InstructionConst.ACONST_NULL);
209 lg.setStart(il.append(new ASTORE(name)));
210
211
212
213
214
215
216
217
218
219
220
221 final InstructionHandle tryStart = il.append(new PUSH(cp, "Andy"));
222 il.append(new ASTORE(name));
223
224
225 final GOTO g = new GOTO(null);
226 final InstructionHandle tryEnd = il.append(g);
227
228 final LocalVariableGen varEx = mg.addLocalVariable("ex", Type.getType("Ljava.io.IOException;"), null, null);
229 final int varExSlot = varEx.getIndex();
230 final InstructionHandle handler = il.append(new ASTORE(varExSlot));
231 varEx.setStart(handler);
232 varEx.setEnd(il.append(InstructionConst.RETURN));
233 mg.addExceptionHandler(tryStart, tryEnd, handler, new ObjectType("java.io.IOException"));
234
235
236 final InstructionHandle ih = il.append(factory.createFieldAccess("java.lang.System", "out", printStream, Const.GETSTATIC));
237 g.setTarget(ih);
238
239
240 il.append(factory.createNew(Type.STRINGBUFFER));
241 il.append(InstructionConst.DUP);
242 il.append(new PUSH(cp, "Hello, "));
243 il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, new Type[] {Type.STRING}, Const.INVOKESPECIAL));
244 il.append(new ALOAD(name));
245 il.append(factory.createInvoke("java.lang.StringBuffer", "append", Type.STRINGBUFFER, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
246 il.append(factory.createInvoke("java.lang.StringBuffer", "toString", Type.STRING, Type.NO_ARGS, Const.INVOKEVIRTUAL));
247 il.append(factory.createInvoke("java.io.PrintStream", "println", Type.VOID, new Type[] {Type.STRING}, Const.INVOKEVIRTUAL));
248 il.append(InstructionConst.RETURN);
249
250
251
252 mg.setMaxStack();
253 mg.setMaxLocals();
254 cg.addMethod(mg.getMethod());
255 il.dispose();
256 cg.addEmptyConstructor(Const.ACC_PUBLIC);
257 }
258
259
260 private ClassGen createClassGen(final String className) {
261 return new ClassGen(className, "java.lang.Object", "<generated>", Const.ACC_PUBLIC | Const.ACC_SUPER, null);
262 }
263
264 public AnnotationEntryGen createCombinedAnnotation(final ConstantPoolGen cp) {
265
266 final AnnotationEntryGen a = createSimpleVisibleAnnotation(cp);
267 final ArrayElementValueGen array = new ArrayElementValueGen(cp);
268 array.addElement(new AnnotationElementValueGen(a, cp));
269 final ElementValuePairGen nvp = new ElementValuePairGen("value", array, cp);
270 final List<ElementValuePairGen> elements = new ArrayList<>();
271 elements.add(nvp);
272 return new AnnotationEntryGen(new ObjectType("CombinedAnnotation"), elements, true, cp);
273 }
274
275 public AnnotationEntryGen createFruitAnnotation(final ConstantPoolGen cp, final String aFruit) {
276 final SimpleElementValueGen evg = new SimpleElementValueGen(ElementValueGen.STRING, cp, aFruit);
277 final ElementValuePairGen nvGen = new ElementValuePairGen("fruit", evg, cp);
278 final ObjectType t = new ObjectType("SimpleStringAnnotation");
279 final List<ElementValuePairGen> elements = new ArrayList<>();
280 elements.add(nvGen);
281 return new AnnotationEntryGen(t, elements, true, cp);
282 }
283
284 private MethodGen createMethodGen(final String methodname, final InstructionList il, final ConstantPoolGen cp) {
285 return new MethodGen(Const.ACC_STATIC | Const.ACC_PUBLIC,
286
287 Type.VOID,
288 new Type[] {new ArrayType(Type.STRING, 1)},
289
290 new String[] {"argv"},
291 methodname, "HelloWorld",
292 il, cp);
293 }
294
295 public AnnotationEntryGen createSimpleInvisibleAnnotation(final ConstantPoolGen cp) {
296 final SimpleElementValueGen evg = new SimpleElementValueGen(ElementValueGen.PRIMITIVE_INT, cp, 4);
297 final ElementValuePairGen nvGen = new ElementValuePairGen("id", evg, cp);
298 final ObjectType t = new ObjectType("SimpleAnnotation");
299 final List<ElementValuePairGen> elements = new ArrayList<>();
300 elements.add(nvGen);
301 return new AnnotationEntryGen(t, elements, false, cp);
302 }
303
304 public AnnotationEntryGen createSimpleVisibleAnnotation(final ConstantPoolGen cp) {
305 final SimpleElementValueGen evg = new SimpleElementValueGen(ElementValueGen.PRIMITIVE_INT, cp, 4);
306 final ElementValuePairGen nvGen = new ElementValuePairGen("id", evg, cp);
307 final ObjectType t = new ObjectType("SimpleAnnotation");
308 final List<ElementValuePairGen> elements = new ArrayList<>();
309 elements.add(nvGen);
310 return new AnnotationEntryGen(t, elements, true, cp);
311 }
312
313 private void dumpClass(final ClassGen cg, final String fname) {
314 try {
315 final File f = createTestdataFile(fname);
316 cg.getJavaClass().dump(f);
317 } catch (final java.io.IOException e) {
318 System.err.println(e);
319 }
320 }
321
322 private void dumpClass(final ClassGen cg, final String dir, final String fname) {
323 dumpClass(cg, dir + File.separator + fname);
324 }
325
326 private JavaClass getClassFrom(final String where, final String clazzname) throws ClassNotFoundException {
327
328 final SyntheticRepository repos = createRepos(where);
329 return repos.loadClass(clazzname);
330 }
331
332
333
334
335
336
337
338
339
340
341
342 @Test
343 void testGenerateClassLevelAnnotations() throws ClassNotFoundException {
344
345 final ClassGen cg = createClassGen("HelloWorld");
346 cg.setMajor(49);
347 cg.setMinor(0);
348 final ConstantPoolGen cp = cg.getConstantPool();
349 final InstructionList il = new InstructionList();
350 cg.addAnnotationEntry(createSimpleVisibleAnnotation(cp));
351 cg.addAnnotationEntry(createSimpleInvisibleAnnotation(cp));
352 buildClassContents(cg, cp, il);
353
354 dumpClass(cg, "HelloWorld.class");
355 final JavaClass jc = getClassFrom(".", "HelloWorld");
356 final AnnotationEntry[] as = jc.getAnnotationEntries();
357 assertEquals(2, as.length, "Wrong number of AnnotationEntries");
358
359 assertEquals("LSimpleAnnotation;", as[0].getAnnotationType(), "Wrong name of annotation 1");
360 assertEquals("LSimpleAnnotation;", as[1].getAnnotationType(), "Wrong name of annotation 2");
361 final ElementValuePair[] vals = as[0].getElementValuePairs();
362 final ElementValuePair nvp = vals[0];
363 assertEquals("id", nvp.getNameString(), "Wrong name of element in SimpleAnnotation");
364 final ElementValue ev = nvp.getValue();
365 assertEquals(ElementValue.PRIMITIVE_INT, ev.getElementValueType(), "Wrong type of element value");
366 assertEquals("4", ev.stringifyValue(), "Wrong value of element");
367 assertTrue(createTestdataFile("HelloWorld.class").delete());
368 }
369
370
371
372
373 @Test
374 void testGenerateMethodLevelAnnotations1() throws ClassNotFoundException {
375
376 final ClassGen cg = createClassGen("HelloWorld");
377 final ConstantPoolGen cp = cg.getConstantPool();
378 final InstructionList il = new InstructionList();
379 buildClassContentsWithAnnotatedMethods(cg, cp, il);
380
381 int i = cg.getMethods()[0].getAnnotationEntries().length;
382 assertEquals(1, i, "Wrong number of annotations of main method prior to dumping");
383 dumpClass(cg, "temp1" + File.separator + "HelloWorld.class");
384 final JavaClass jc2 = getClassFrom("temp1", "HelloWorld");
385
386 i = jc2.getMethods()[0].getAnnotationEntries().length;
387 assertEquals(1, i, "Wrong number of annotation on JavaClass");
388 final ClassGen cg2 = new ClassGen(jc2);
389
390 final Method[] m = cg2.getMethods();
391 i = m[0].getAnnotationEntries().length;
392 assertEquals(1, i, "Wrong number of annotations on the main 'Method'");
393 final FieldGenOrMethodGen mg = new MethodGen(m[0], cg2.getClassName(), cg2.getConstantPool());
394
395 i = mg.getAnnotationEntries().length;
396 assertEquals(1, i, "Wrong number of annotations on the main 'MethodGen'");
397
398 assertTrue(delete("temp1", "HelloWorld.class"));
399 }
400
401
402
403
404
405
406 @Test
407 void testGenerateMethodLevelAnnotations2() throws ClassNotFoundException {
408
409 final ClassGen cg = createClassGen("HelloWorld");
410 final ConstantPoolGen cp = cg.getConstantPool();
411 final InstructionList il = new InstructionList();
412 buildClassContentsWithAnnotatedMethods(cg, cp, il);
413 dumpClass(cg, "temp2", "HelloWorld.class");
414 final JavaClass jc2 = getClassFrom("temp2", "HelloWorld");
415 final ClassGen cg2 = new ClassGen(jc2);
416
417 final Method mainMethod1 = jc2.getMethods()[0];
418 assertEquals(1, mainMethod1.getAnnotationEntries().length, "Wrong number of annotations of the 'Method'");
419 final MethodGen mainMethod2 = new MethodGen(mainMethod1, cg2.getClassName(), cg2.getConstantPool());
420 assertEquals(1, mainMethod2.getAnnotationEntries().length, "Wrong number of annotations of the 'MethodGen'");
421 final AnnotationEntryGen fruit = createFruitAnnotation(cg2.getConstantPool(), "Pear");
422 mainMethod2.addAnnotationEntry(fruit);
423 cg2.removeMethod(mainMethod1);
424 cg2.addMethod(mainMethod2.getMethod());
425 dumpClass(cg2, "temp3", "HelloWorld.class");
426 final JavaClass jc3 = getClassFrom("temp3", "HelloWorld");
427 final ClassGen cg3 = new ClassGen(jc3);
428 final Method mainMethod3 = cg3.getMethods()[1];
429 final int i = mainMethod3.getAnnotationEntries().length;
430 assertEquals(2, i, "Wrong number of annotations on the 'Method'");
431 mainMethod2.removeAnnotationEntry(fruit);
432 assertEquals(1, mainMethod2.getAnnotationEntries().length, "Wrong number of annotations on the 'MethodGen'");
433 mainMethod2.removeAnnotationEntries();
434 assertEquals(0, mainMethod2.getAnnotationEntries().length, 0, "Wrong number of annotations on the 'MethodGen'");
435 assertTrue(delete("temp2", "HelloWorld.class"));
436 assertTrue(delete("temp3", "HelloWorld.class"));
437 }
438
439
440
441
442 @Test
443 void testModifyingClasses1() throws ClassNotFoundException {
444 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleAnnotatedClass");
445 final ClassGen cgen = new ClassGen(jc);
446 final ConstantPoolGen cp = cgen.getConstantPool();
447 cgen.addAnnotationEntry(createFruitAnnotation(cp, "Pineapple"));
448 assertEquals(2, cgen.getAnnotationEntries().length, "Wrong number of annotations");
449 dumpClass(cgen, "SimpleAnnotatedClass.class");
450 assertTrue(delete("SimpleAnnotatedClass.class"));
451 }
452
453
454
455
456 @Test
457 void testModifyingClasses2() throws ClassNotFoundException {
458 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleAnnotatedClass");
459 final ClassGen cgen = new ClassGen(jc);
460 final ConstantPoolGen cp = cgen.getConstantPool();
461 cgen.addAnnotationEntry(createCombinedAnnotation(cp));
462 assertEquals(2, cgen.getAnnotationEntries().length, "Wrong number of annotations");
463 dumpClass(cgen, "SimpleAnnotatedClass.class");
464 final JavaClass jc2 = getClassFrom(".", "SimpleAnnotatedClass");
465 jc2.getAnnotationEntries();
466 assertTrue(delete("SimpleAnnotatedClass.class"));
467
468 }
469
470
471
472
473
474 @Test
475 void testTransformClassToClassGen_ArrayAndAnnotationTypes() throws ClassNotFoundException {
476 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnnotatedWithCombinedAnnotation");
477 final ClassGen cgen = new ClassGen(jc);
478
479 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
480 assertEquals(1, annotations.length, "Wrong number of annotations");
481 final AnnotationEntryGen a = annotations[0];
482 assertEquals(1, a.getValues().size(), "Wrong number of values for the annotation");
483 final ElementValuePairGen nvp = a.getValues().get(0);
484 final ElementValueGen value = nvp.getValue();
485 assertInstanceOf(ArrayElementValueGen.class, value, "Value should be ArrayElementValueGen but is " + value);
486 final ArrayElementValueGen arrayValue = (ArrayElementValueGen) value;
487 assertEquals(1, arrayValue.getElementValuesSize(), "Wrong size of the array");
488 final ElementValueGen innerValue = arrayValue.getElementValues().get(0);
489 assertInstanceOf(AnnotationElementValueGen.class, innerValue, "Value in the array should be AnnotationElementValueGen but is " + innerValue);
490 final AnnotationElementValueGen innerAnnotationValue = (AnnotationElementValueGen) innerValue;
491 assertEquals("L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", innerAnnotationValue.getAnnotation().getTypeSignature(), "Wrong type signature");
492
493
494 final Method[] methods = cgen.getMethods();
495 assertEquals(3, methods.length);
496 for (final Method method : methods) {
497 final String methodName = method.getName();
498 switch (methodName) {
499 case "<init>":
500 assertMethodAnnotations(method, 0, 1);
501 assertParameterAnnotations(method, 0, 1);
502 break;
503 case "methodWithArrayOfZeroAnnotations":
504 assertMethodAnnotations(method, 1, 0);
505 break;
506 case "methodWithArrayOfTwoAnnotations":
507 assertMethodAnnotations(method, 1, 2);
508 break;
509 default:
510 fail(() -> "unexpected method " + method.getName());
511 break;
512 }
513 }
514 }
515
516
517
518
519
520 @Test
521 void testTransformClassToClassGen_EnumType() throws ClassNotFoundException {
522 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnnotatedWithEnumClass");
523 final ClassGen cgen = new ClassGen(jc);
524
525 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
526 assertEquals(1, annotations.length, "Wrong number of annotations");
527 }
528
529
530
531
532
533 @Test
534 void testTransformClassToClassGen_SimpleTypes() throws ClassNotFoundException {
535 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.SimpleAnnotatedClass");
536 final ClassGen cgen = new ClassGen(jc);
537
538 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
539 assertEquals(1, annotations.length, "Wrong number of annotations");
540 }
541
542
543
544
545 @Test
546 void testTransformComplexClassToClassGen() throws ClassNotFoundException {
547 final JavaClass jc = getTestJavaClass(PACKAGE_BASE_NAME + ".data.ComplexAnnotatedClass");
548 final ClassGen cgen = new ClassGen(jc);
549
550 final AnnotationEntryGen[] annotations = cgen.getAnnotationEntries();
551 assertEquals(1, annotations.length, "Wrong number of annotations");
552 final List<?> l = annotations[0].getValues();
553 boolean found = false;
554 for (final Object name : l) {
555 final ElementValuePairGen element = (ElementValuePairGen) name;
556 if (element.getNameString().equals("dval") && element.getValue().stringifyValue().equals("33.4")) {
557 found = true;
558 }
559 }
560 assertTrue(found, "Did not find double annotation value with value 33.4");
561 }
562 }