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