• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 package org.apache.bcel.generic;
20 
21 import java.io.File;
22 import java.io.IOException;
23 
24 import org.apache.bcel.AbstractTestCase;
25 import org.apache.bcel.classfile.AnnotationEntry;
26 import org.apache.bcel.classfile.ElementValuePair;
27 import org.apache.bcel.classfile.Field;
28 import org.apache.bcel.classfile.JavaClass;
29 import org.apache.bcel.util.SyntheticRepository;
30 
31 public class FieldAnnotationsTestCase extends AbstractTestCase
32 {
33     /**
34      * Check field AnnotationEntrys are retrievable.
35      */
testFieldAnnotationEntrys()36     public void testFieldAnnotationEntrys() throws ClassNotFoundException
37     {
38         final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME+".data.AnnotatedFields");
39         // TODO L...;?
40         checkAnnotatedField(clazz, "i", "L"+PACKAGE_BASE_SIG+"/data/SimpleAnnotation;", "id", "1");
41         checkAnnotatedField(clazz, "s", "L"+PACKAGE_BASE_SIG+"/data/SimpleAnnotation;", "id", "2");
42     }
43 
44     /**
45      * Check field AnnotationEntrys (de)serialize ok.
46      */
testFieldAnnotationEntrysReadWrite()47     public void testFieldAnnotationEntrysReadWrite() throws ClassNotFoundException,
48             IOException
49     {
50         final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME+".data.AnnotatedFields");
51         checkAnnotatedField(clazz, "i", "L"+PACKAGE_BASE_SIG+"/data/SimpleAnnotation;", "id", "1");
52         checkAnnotatedField(clazz, "s", "L"+PACKAGE_BASE_SIG+"/data/SimpleAnnotation;", "id", "2");
53         // Write it out
54         final File tfile = createTestdataFile("AnnotatedFields.class");
55         clazz.dump(tfile);
56         final SyntheticRepository repos2 = createRepos(".");
57         repos2.loadClass("AnnotatedFields");
58         checkAnnotatedField(clazz, "i", "L"+PACKAGE_BASE_SIG+"/data/SimpleAnnotation;", "id", "1");
59         checkAnnotatedField(clazz, "s", "L"+PACKAGE_BASE_SIG+"/data/SimpleAnnotation;", "id", "2");
60         assertTrue(tfile.delete());
61     }
62 
63     /**
64      * Check we can load in a class, modify its field AnnotationEntrys, save it,
65      * reload it and everything is correct.
66      */
testFieldAnnotationModification()67     public void testFieldAnnotationModification()
68             throws ClassNotFoundException
69     {
70         final boolean dbg = false;
71         final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME+".data.AnnotatedFields");
72         final ClassGen clg = new ClassGen(clazz);
73         Field f = clg.getFields()[0];
74         if (dbg) {
75             System.err.println("Field in freshly constructed class is: " + f);
76         }
77         if (dbg) {
78             System.err.println("AnnotationEntrys on field are: "
79                     + dumpAnnotationEntries(f.getAnnotationEntries()));
80         }
81         final AnnotationEntryGen fruitBasedAnnotationEntry = createFruitAnnotationEntry(clg
82                 .getConstantPool(), "Tomato", false);
83         final FieldGen fg = new FieldGen(f, clg.getConstantPool());
84         if (dbg) {
85             System.err.println("Adding AnnotationEntry to the field");
86         }
87         fg.addAnnotationEntry(fruitBasedAnnotationEntry);
88         if (dbg) {
89             System.err.println("FieldGen (mutable field) is " + fg);
90         }
91         if (dbg) {
92             System.err.println("with AnnotationEntrys: "
93                     + dumpAnnotationEntries(fg.getAnnotationEntries()));
94         }
95         if (dbg) {
96             System.err
97                     .println("Replacing original field with new field that has extra AnnotationEntry");
98         }
99         clg.removeField(f);
100         clg.addField(fg.getField());
101         f = clg.getFields()[1]; // there are two fields in the class, removing
102                                 // and readding has changed the order
103         // so this time index [1] is the 'int i' field
104         if (dbg) {
105             System.err.println("Field now looks like this: " + f);
106         }
107         if (dbg) {
108             System.err.println("With AnnotationEntrys: "
109                     + dumpAnnotationEntries(f.getAnnotationEntries()));
110         }
111         assertTrue("Should be 2 AnnotationEntrys on this field, but there are "
112                 + f.getAnnotationEntries().length, f.getAnnotationEntries().length == 2);
113     }
114 
115     // helper methods
checkAnnotatedField(final JavaClass clazz, final String fieldname, final String AnnotationEntryName, final String AnnotationEntryElementName, final String AnnotationEntryElementValue)116     public void checkAnnotatedField(final JavaClass clazz, final String fieldname,
117             final String AnnotationEntryName, final String AnnotationEntryElementName,
118             final String AnnotationEntryElementValue)
119     {
120         final Field[] fields = clazz.getFields();
121         for (final Field f : fields) {
122             final AnnotationEntry[] fieldAnnotationEntrys = f.getAnnotationEntries();
123             if (f.getName().equals(fieldname))
124             {
125                 checkAnnotationEntry(fieldAnnotationEntrys[0], AnnotationEntryName,
126                         AnnotationEntryElementName, AnnotationEntryElementValue);
127             }
128         }
129     }
130 
checkAnnotationEntry(final AnnotationEntry a, final String name, final String elementname, final String elementvalue)131     private void checkAnnotationEntry(final AnnotationEntry a, final String name, final String elementname,
132             final String elementvalue)
133     {
134         assertTrue("Expected AnnotationEntry to have name " + name
135                 + " but it had name " + a.getAnnotationType(), a.getAnnotationType()
136                 .equals(name));
137         assertTrue("Expected AnnotationEntry to have one element but it had "
138                 + a.getElementValuePairs().length, a.getElementValuePairs().length == 1);
139         final ElementValuePair envp = a.getElementValuePairs()[0];
140         assertTrue("Expected element name " + elementname + " but was "
141                 + envp.getNameString(), elementname
142                 .equals(envp.getNameString()));
143         assertTrue("Expected element value " + elementvalue + " but was "
144                 + envp.getValue().stringifyValue(), elementvalue.equals(envp
145                 .getValue().stringifyValue()));
146     }
147 
148     // helper methods
checkValue(final AnnotationEntry a, final String name, final String tostring)149     public void checkValue(final AnnotationEntry a, final String name, final String tostring)
150     {
151         for (int i = 0; i < a.getElementValuePairs().length; i++)
152         {
153             final ElementValuePair element = a.getElementValuePairs()[i];
154             if (element.getNameString().equals(name))
155             {
156                 if (!element.getValue().stringifyValue().equals(tostring))
157                 {
158                     fail("Expected element " + name + " to have value "
159                             + tostring + " but it had value "
160                             + element.getValue().stringifyValue());
161                 }
162                 return;
163             }
164         }
165         fail("Didnt find named element " + name);
166     }
167 }
168