| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * https://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.bcel.generic; |
| |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| |
| import java.io.File; |
| import java.io.IOException; |
| |
| import org.apache.bcel.AbstractTest; |
| import org.apache.bcel.Const; |
| import org.apache.bcel.classfile.AnnotationEntry; |
| import org.apache.bcel.classfile.ElementValuePair; |
| import org.apache.bcel.classfile.Field; |
| import org.apache.bcel.classfile.JavaClass; |
| import org.apache.bcel.util.SyntheticRepository; |
| import org.junit.jupiter.api.Test; |
| |
| class FieldAnnotationsTest extends AbstractTest { |
| // helper methods |
| public void checkAnnotatedField(final JavaClass clazz, final String fieldname, final String AnnotationEntryName, final String AnnotationEntryElementName, |
| final String AnnotationEntryElementValue) { |
| final Field[] fields = clazz.getFields(); |
| for (final Field f : fields) { |
| final AnnotationEntry[] fieldAnnotationEntrys = f.getAnnotationEntries(); |
| if (f.getName().equals(fieldname)) { |
| checkAnnotationEntry(fieldAnnotationEntrys[0], AnnotationEntryName, AnnotationEntryElementName, AnnotationEntryElementValue); |
| assertNotNull(f.getAttribute(Const.ATTR_RUNTIME_VISIBLE_ANNOTATIONS)); |
| assertNull(f.getAttribute(Const.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS)); |
| } |
| } |
| } |
| |
| private void checkAnnotationEntry(final AnnotationEntry a, final String name, final String elementname, final String elementvalue) { |
| assertEquals(name, a.getAnnotationType(), "Wrong AnnotationEntry name"); |
| assertEquals(1, a.getElementValuePairs().length, "Wrong number of AnnotationEntry elements"); |
| final ElementValuePair envp = a.getElementValuePairs()[0]; |
| assertEquals(envp.getNameString(), elementname, "Wrong element name"); |
| assertEquals(envp.getValue().stringifyValue(), elementvalue, "Wrong element value"); |
| } |
| |
| /** |
| * Check field AnnotationEntrys are retrievable. |
| */ |
| @Test |
| void testFieldAnnotationEntrys() throws ClassNotFoundException { |
| final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnnotatedFields"); |
| // TODO L...;? |
| checkAnnotatedField(clazz, "i", "L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", "id", "1"); |
| checkAnnotatedField(clazz, "s", "L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", "id", "2"); |
| } |
| |
| /** |
| * Check field AnnotationEntrys (de)serialize ok. |
| */ |
| @Test |
| void testFieldAnnotationEntrysReadWrite() throws ClassNotFoundException, IOException { |
| final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnnotatedFields"); |
| checkAnnotatedField(clazz, "i", "L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", "id", "1"); |
| checkAnnotatedField(clazz, "s", "L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", "id", "2"); |
| // Write it out |
| final File tfile = createTestdataFile("AnnotatedFields.class"); |
| clazz.dump(tfile); |
| final SyntheticRepository repos2 = createRepos("."); |
| repos2.loadClass("AnnotatedFields"); |
| checkAnnotatedField(clazz, "i", "L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", "id", "1"); |
| checkAnnotatedField(clazz, "s", "L" + PACKAGE_BASE_SIG + "/data/SimpleAnnotation;", "id", "2"); |
| assertTrue(tfile.delete()); |
| } |
| |
| /** |
| * Check we can load in a class, modify its field AnnotationEntrys, save it, reload it and everything is correct. |
| */ |
| @Test |
| void testFieldAnnotationModification() throws ClassNotFoundException { |
| final boolean dbg = false; |
| final JavaClass clazz = getTestJavaClass(PACKAGE_BASE_NAME + ".data.AnnotatedFields"); |
| final ClassGen clg = new ClassGen(clazz); |
| Field f = clg.getFields()[0]; |
| if (dbg) { |
| System.err.println("Field in freshly constructed class is: " + f); |
| } |
| assertEquals("[@Lorg/apache/bcel/data/SimpleAnnotation;(id=1)]", dumpAnnotationEntries(f.getAnnotationEntries())); |
| if (dbg) { |
| System.err.println("AnnotationEntrys on field are: " + dumpAnnotationEntries(f.getAnnotationEntries())); |
| } |
| final AnnotationEntryGen fruitBasedAnnotationEntry = createFruitAnnotationEntry(clg.getConstantPool(), "Tomato", false); |
| final FieldGen fg = new FieldGen(f, clg.getConstantPool()); |
| if (dbg) { |
| System.err.println("Adding AnnotationEntry to the field"); |
| } |
| fg.addAnnotationEntry(fruitBasedAnnotationEntry); |
| if (dbg) { |
| System.err.println("FieldGen (mutable field) is " + fg); |
| } |
| if (dbg) { |
| System.err.println("with AnnotationEntrys: " + dumpAnnotationEntries(fg.getAnnotationEntries())); |
| } |
| if (dbg) { |
| System.err.println("Replacing original field with new field that has extra AnnotationEntry"); |
| } |
| clg.removeField(f); |
| clg.addField(fg.getField()); |
| f = clg.getFields()[1]; // there are two fields in the class, removing |
| // and readding has changed the order |
| // so this time index [1] is the 'int i' field |
| if (dbg) { |
| System.err.println("Field now looks like this: " + f); |
| } |
| if (dbg) { |
| System.err.println("With AnnotationEntrys: " + dumpAnnotationEntries(f.getAnnotationEntries())); |
| } |
| assertEquals(2, f.getAnnotationEntries().length, "Wrong number of AnnotationEntries"); |
| } |
| } |