mirror of
https://github.com/eclipse-aspectj/aspectj.git
synced 2024-07-24 22:04:44 +02:00
396 lines
17 KiB
Java
396 lines
17 KiB
Java
/* *******************************************************************
|
|
* Copyright (c) 2004 IBM
|
|
* All rights reserved.
|
|
* This program and the accompanying materials are made available
|
|
* under the terms of the Eclipse Public License v1.0
|
|
* which accompanies this distribution and is available at
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
*
|
|
* Contributors:
|
|
* Andy Clement - initial implementation
|
|
* ******************************************************************/
|
|
|
|
package org.aspectj.apache.bcel.classfile.tests;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
|
|
import org.aspectj.apache.bcel.classfile.Attribute;
|
|
import org.aspectj.apache.bcel.classfile.ConstantPool;
|
|
import org.aspectj.apache.bcel.classfile.JavaClass;
|
|
import org.aspectj.apache.bcel.classfile.Utility;
|
|
import org.aspectj.apache.bcel.classfile.annotation.AnnotationElementValueGen;
|
|
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
|
|
import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
|
|
import org.aspectj.apache.bcel.classfile.annotation.ClassElementValueGen;
|
|
import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
|
|
import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
|
|
import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;
|
|
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
|
|
import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValueGen;
|
|
import org.aspectj.apache.bcel.generic.ClassGen;
|
|
import org.aspectj.apache.bcel.util.SyntheticRepository;
|
|
|
|
|
|
public class RuntimeVisibleAnnotationAttributeTest extends BcelTestCase {
|
|
|
|
|
|
protected void setUp() throws Exception {
|
|
super.setUp();
|
|
}
|
|
|
|
public void testSeeAnnotationsAsAttribute() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
|
|
ConstantPool pool = clazz.getConstantPool();
|
|
Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz);
|
|
assertTrue("Expected a RuntimeVisibleAnnotations attribute but found none",
|
|
rvaAttr.length==1);
|
|
}
|
|
|
|
public void testAnnotationsAttributeContainsRightData() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
|
|
ConstantPool pool = clazz.getConstantPool();
|
|
Attribute[] rvaAttr = findAttribute("RuntimeVisibleAnnotations",clazz);
|
|
RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) rvaAttr[0];
|
|
List anns = rva.getAnnotations();
|
|
assertTrue("Should be one annotation but found "+anns.size(),
|
|
anns.size()==1);
|
|
AnnotationGen ann = (AnnotationGen) anns.get(0);
|
|
assertTrue("Should be called 'SimpleAnnotation' but was called "+ann.getTypeName(),
|
|
ann.getTypeName().equals("SimpleAnnotation"));
|
|
List l = ann.getValues();
|
|
assertTrue("Should be one value for annotation 'SimpleAnnotation' but found "+l.size(),
|
|
l.size()==1);
|
|
ElementNameValuePairGen envp = (ElementNameValuePairGen)l.get(0);
|
|
assertTrue("Name of element in SimpleAnnotation should be 'id' but it is "+envp.getNameString(),
|
|
envp.getNameString().equals("id"));
|
|
SimpleElementValueGen evalue = (SimpleElementValueGen)envp.getValue();
|
|
assertTrue("'id' should be of type int, but it is "+evalue.getElementValueType(),evalue.getElementValueType()==SimpleElementValueGen.PRIMITIVE_INT);
|
|
assertTrue("'id' should have value 4 but it is "+evalue.getValueInt(),
|
|
evalue.getValueInt()==4);
|
|
}
|
|
|
|
public void testAccessingAnnotationsOnClazz() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
|
|
ConstantPool pool = clazz.getConstantPool();
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length,
|
|
anns.length==1);
|
|
}
|
|
|
|
public void testReadingWritingAnnotations() throws ClassNotFoundException, IOException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("SimpleAnnotatedClass");
|
|
ConstantPool pool = clazz.getConstantPool();
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns.length,
|
|
anns.length==1);
|
|
|
|
// Write it out
|
|
File tfile = createTestdataFile("SimpleAnnotatedClass.class");
|
|
clazz.dump(tfile);
|
|
|
|
SyntheticRepository repos2 = createRepos(".");
|
|
JavaClass clazz2 = repos.loadClass("SimpleAnnotatedClass");
|
|
ConstantPool pool2 = clazz2.getConstantPool();
|
|
AnnotationGen[] anns2 = clazz2.getAnnotations();
|
|
assertTrue("Expected one annotation on SimpleAnnotatedClass class but got "+anns2.length,
|
|
anns2.length==1);
|
|
|
|
assertTrue(tfile.delete());
|
|
}
|
|
|
|
|
|
|
|
////
|
|
// Test for annotations containing string elements
|
|
|
|
public void testAnnotationStringElement() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedClass");
|
|
verifyAnnotationStringElement(clazz);
|
|
}
|
|
|
|
|
|
public void testAnnotationStringElementReadWrite() throws ClassNotFoundException, IOException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedClass");
|
|
verifyAnnotationStringElement(clazz);
|
|
|
|
// Write it out
|
|
File tfile = createTestdataFile("AnnotatedClass.class");
|
|
clazz.dump(tfile);
|
|
|
|
SyntheticRepository repos2 = createRepos(".");
|
|
JavaClass clazz2 = repos2.loadClass("AnnotatedClass");
|
|
verifyAnnotationStringElement(clazz2);
|
|
|
|
assertTrue(tfile.delete());
|
|
}
|
|
|
|
private void verifyAnnotationStringElement(JavaClass clazz) {
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("should be one annotation but found "+anns.length,anns.length==1);
|
|
AnnotationGen ann = anns[0];
|
|
assertTrue("should be called 'AnnotationStringElement' but was called "+ann.getTypeName(),
|
|
ann.getTypeName().equals("AnnotationStringElement"));
|
|
List l = ann.getValues();
|
|
assertTrue("Should be one value but there were "+l.size(),l.size()==1);
|
|
ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
|
|
assertTrue("Name of element should be 'stringval' but was "+nvp.getNameString(),
|
|
nvp.getNameString().equals("stringval"));
|
|
SimpleElementValueGen ev = (SimpleElementValueGen)nvp.getValue();
|
|
assertTrue("String value should be 'hello' but was '"+ev.getValueString()+"'",
|
|
ev.getValueString().equals("hello"));
|
|
}
|
|
|
|
////
|
|
// Test for complex annotation that includes all primitives
|
|
|
|
public void testComplexAnnotation() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("ComplexAnnotatedClass");
|
|
verifyComplexAnnotation(clazz);
|
|
}
|
|
|
|
|
|
public void testComplexAnnotationsReadWrite() throws ClassNotFoundException, IOException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("ComplexAnnotatedClass");
|
|
verifyComplexAnnotation(clazz);
|
|
|
|
// Write it out
|
|
File tfile = createTestdataFile("ComplexAnnotatedClass.class");
|
|
clazz.dump(tfile);
|
|
|
|
SyntheticRepository repos2 = createRepos(".");
|
|
JavaClass clazz2 = repos.loadClass("ComplexAnnotatedClass");
|
|
verifyComplexAnnotation(clazz2);
|
|
|
|
assertTrue(tfile.delete());
|
|
|
|
}
|
|
|
|
private void verifyComplexAnnotation(JavaClass clazz) {
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("Should be one annotation but found "+anns.length,anns.length==1);
|
|
AnnotationGen ann = anns[0];
|
|
assertTrue("Should be called 'ComplexAnnotation' but was called "+ann.getTypeName(),
|
|
ann.getTypeName().equals("ComplexAnnotation"));
|
|
List l = ann.getValues();
|
|
assertTrue("Should be eight values for annotation 'ComplexAnnotation' but found "+l.size(),
|
|
l.size()==8);
|
|
List names = RuntimeVisibleAnnotationAttributeTest.getListOfAnnotationNames(ann);
|
|
assertTrue("Cant find expected element ",names.contains("ival"));
|
|
assertTrue("Cant find expected element ",names.contains("dval"));
|
|
assertTrue("Cant find expected element ",names.contains("zval"));
|
|
assertTrue("Cant find expected element ",names.contains("fval"));
|
|
assertTrue("Cant find expected element ",names.contains("jval"));
|
|
assertTrue("Cant find expected element ",names.contains("sval"));
|
|
assertTrue("Cant find expected element ",names.contains("bval"));
|
|
assertTrue("Cant find expected element ",names.contains("cval"));
|
|
|
|
checkValue(ann,"ival","4");
|
|
checkValue(ann,"jval","56");
|
|
checkValue(ann,"fval","3.0");
|
|
checkValue(ann,"dval","33.4");
|
|
checkValue(ann,"sval","99");
|
|
checkValue(ann,"bval","2");
|
|
checkValue(ann,"cval",new Character('5').toString());
|
|
checkValue(ann,"zval","false");
|
|
|
|
}
|
|
|
|
private void checkValue(AnnotationGen a,String name,String tostring) {
|
|
for (Iterator i = a.getValues().iterator(); i.hasNext();) {
|
|
ElementNameValuePairGen element = (ElementNameValuePairGen) i.next();
|
|
if (element.getNameString().equals(name)) {
|
|
if (!element.getValue().stringifyValue().equals(tostring)) {
|
|
fail("Expected element "+name+" to have value "+tostring+" but it had value "+element.getValue().stringifyValue());
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
fail("Didnt find named element "+name);
|
|
}
|
|
|
|
////
|
|
// Test an annotation containing a 'Class' element
|
|
|
|
public void testAnnotationClassElement() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedWithClassClass");
|
|
verifyClassAnnotation(clazz);
|
|
}
|
|
|
|
public void testAnnotationClassElementCopying() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedWithClassClass");
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
ClassGen cg = new ClassGen(clazz);
|
|
// Checks we can copy class values in an annotation
|
|
new AnnotationGen(anns[0],cg.getConstantPool(),true);
|
|
new AnnotationGen(anns[0],cg.getConstantPool(),false);
|
|
}
|
|
|
|
public void testAnnotationClassElementReadWrite() throws ClassNotFoundException,IOException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedWithClassClass");
|
|
verifyClassAnnotation(clazz);
|
|
|
|
// Write it out
|
|
File tfile = createTestdataFile("AnnotatedWithClassClass.class");
|
|
clazz.dump(tfile);
|
|
|
|
SyntheticRepository repos2 = createRepos(".");
|
|
JavaClass clazz2 = repos2.loadClass("AnnotatedWithClassClass");
|
|
verifyClassAnnotation(clazz2);
|
|
|
|
assertTrue(wipe("AnnotatedWithClassClass.class"));
|
|
}
|
|
|
|
private void verifyClassAnnotation(JavaClass clazz) {
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("should be one annotation but found "+anns.length,anns.length==1);
|
|
AnnotationGen ann = anns[0];
|
|
assertTrue("should be called 'AnnotationClassElement' but was called "+ann.getTypeName(),
|
|
ann.getTypeName().equals("AnnotationClassElement"));
|
|
List l = ann.getValues();
|
|
assertTrue("Should be one value but there were "+l.size(),l.size()==1);
|
|
ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
|
|
assertTrue("Name of element should be 'clz' but was "+nvp.getNameString(),
|
|
nvp.getNameString().equals("clz"));
|
|
ClassElementValueGen ev = (ClassElementValueGen)nvp.getValue();
|
|
assertTrue("String value should be 'Ljava/lang/Integer;' but was '"+ev.getClassString()+"'",
|
|
ev.getClassString().equals("Ljava/lang/Integer;"));
|
|
|
|
}
|
|
|
|
////
|
|
// Test an annotation containing an enum element
|
|
|
|
public void testAnnotationEnumElement() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass");
|
|
verifyAnnotationEnumElement(clazz);
|
|
}
|
|
|
|
public void testAnnotationEnumElementReadWrite() throws ClassNotFoundException, IOException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedWithEnumClass");
|
|
verifyAnnotationEnumElement(clazz);
|
|
|
|
// Write it out
|
|
File tfile = createTestdataFile("AnnotatedWithEnumClass.class");
|
|
clazz.dump(tfile);
|
|
|
|
SyntheticRepository repos2 = createRepos(".");
|
|
JavaClass clazz2 = repos2.loadClass("AnnotatedWithEnumClass");
|
|
verifyAnnotationEnumElement(clazz2);
|
|
|
|
assertTrue(tfile.delete());
|
|
}
|
|
|
|
public void verifyAnnotationEnumElement(JavaClass clazz) {
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("should be one annotation but found "+anns.length,anns.length==1);
|
|
AnnotationGen ann = anns[0];
|
|
assertTrue("should be called 'AnnotationEnumElement' but was called "+ann.getTypeName(),
|
|
ann.getTypeName().equals("AnnotationEnumElement"));
|
|
List l = ann.getValues();
|
|
assertTrue("Should be one value but there were "+l.size(),l.size()==1);
|
|
ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
|
|
assertTrue("Name of element should be 'enumval' but was "+nvp.getNameString(),
|
|
nvp.getNameString().equals("enumval"));
|
|
ElementValueGen ev = nvp.getValue();
|
|
assertTrue("Should be of type EnumElementValue but is "+ev,ev instanceof EnumElementValueGen);
|
|
EnumElementValueGen eev = (EnumElementValueGen)ev;
|
|
assertTrue("Should be an enum type value but is "+eev.getElementValueType(),eev.getElementValueType()==SimpleElementValueGen.ENUM_CONSTANT);
|
|
assertTrue("Enum type for annotation should be 'SimpleEnum' but is "+Utility.signatureToString(eev.getEnumTypeString()),Utility.signatureToString(eev.getEnumTypeString()).equals("SimpleEnum"));
|
|
assertTrue("String value should be 'Red' but was '"+eev.getEnumValueString()+"'",
|
|
eev.getEnumValueString().equals("Red"));
|
|
}
|
|
|
|
////
|
|
// Test an annotation with an array element
|
|
|
|
public void testAnnotationArraysOfAnnotations() throws ClassNotFoundException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation");
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("should be one annotation but found "+anns.length,anns.length==1);
|
|
checkCombinedAnnotation(anns[0]);
|
|
}
|
|
|
|
public void testAnnotationArraysOfAnnotationsReadWrite() throws ClassNotFoundException, IOException {
|
|
SyntheticRepository repos = createRepos("testcode.jar");
|
|
JavaClass clazz = repos.loadClass("AnnotatedWithCombinedAnnotation");
|
|
AnnotationGen[] anns = clazz.getAnnotations();
|
|
assertTrue("should be one annotation but found "+anns.length,anns.length==1);
|
|
checkCombinedAnnotation(anns[0]);
|
|
|
|
// Write it out
|
|
File tfile = createTestdataFile("AnnotatedWithCombinedAnnotation.class");
|
|
clazz.dump(tfile);
|
|
|
|
SyntheticRepository repos2 = createRepos(".");
|
|
JavaClass clazz2 = repos2.loadClass("AnnotatedWithCombinedAnnotation");
|
|
AnnotationGen[] anns2 = clazz2.getAnnotations();
|
|
assertTrue("should be one annotation but found "+anns2.length,anns2.length==1);
|
|
checkCombinedAnnotation(anns2[0]);
|
|
|
|
assertTrue(tfile.delete());
|
|
}
|
|
|
|
|
|
private void checkCombinedAnnotation(AnnotationGen ann) {
|
|
assertTrue("should be called 'CombinedAnnotation' but was called "+ann.getTypeName(),
|
|
ann.getTypeName().equals("CombinedAnnotation"));
|
|
List l = ann.getValues();
|
|
assertTrue("Should be one value but there were "+l.size(),l.size()==1);
|
|
ElementNameValuePairGen nvp = (ElementNameValuePairGen)l.get(0);
|
|
assertTrue("Name of element should be 'value' but was "+nvp.getNameString(),
|
|
nvp.getNameString().equals("value"));
|
|
ElementValueGen ev = nvp.getValue();
|
|
assertTrue("Should be of type ArrayElementValue but is "+ev,ev instanceof ArrayElementValueGen);
|
|
ArrayElementValueGen aev = (ArrayElementValueGen)ev;
|
|
|
|
assertTrue("Array element value should be of size 1 but is "+aev.getElementValuesArraySize(),
|
|
aev.getElementValuesArraySize()==1);
|
|
ElementValueGen[] evs = aev.getElementValuesArray();
|
|
assertTrue("Entry in the array should be AnnotationElementValue but is "+evs[0],
|
|
evs[0] instanceof AnnotationElementValueGen);
|
|
AnnotationElementValueGen inner_ev = (AnnotationElementValueGen)evs[0];
|
|
AnnotationGen a = inner_ev.getAnnotation();
|
|
assertTrue("Should be SimpleAnnotation but is "+a.getTypeName(),a.getTypeName().equals("SimpleAnnotation"));
|
|
List envps = a.getValues();
|
|
assertTrue("Should be one name value pair but found "+envps.size(),envps.size()==1);
|
|
ElementNameValuePairGen envp = (ElementNameValuePairGen) envps.get(0);
|
|
assertTrue("Name should be 'id' but it is "+envp.getNameString(),envp.getNameString().equals("id"));
|
|
assertTrue("Value of 'id' should be 4 but it is "+envp.getValue().stringifyValue(),
|
|
envp.getValue().stringifyValue().equals("4"));
|
|
}
|
|
|
|
|
|
protected void tearDown() throws Exception {
|
|
super.tearDown();
|
|
}
|
|
|
|
public static List getListOfAnnotationNames(AnnotationGen a) {
|
|
List l = a.getValues();
|
|
List names = new ArrayList();
|
|
for (Iterator i = l.iterator(); i.hasNext();) {
|
|
ElementNameValuePairGen element = (ElementNameValuePairGen) i.next();
|
|
names.add(element.getNameString());
|
|
}
|
|
return names;
|
|
}
|
|
|
|
}
|