/******************************************************************************* * 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.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Collections; import org.aspectj.apache.bcel.Constants; import org.aspectj.apache.bcel.classfile.ConstantPool; import org.aspectj.apache.bcel.classfile.annotation.AnnotationElementValue; import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; import org.aspectj.apache.bcel.classfile.annotation.ElementValue; import org.aspectj.apache.bcel.classfile.annotation.EnumElementValue; import org.aspectj.apache.bcel.classfile.annotation.NameValuePair; import org.aspectj.apache.bcel.classfile.annotation.SimpleElementValue; import org.aspectj.apache.bcel.generic.ClassGen; import org.aspectj.apache.bcel.generic.ObjectType; public class ElementValueGenTest extends BcelTestCase { protected void setUp() throws Exception { super.setUp(); } private ClassGen createClassGen(String classname) { return new ClassGen(classname, "java.lang.Object", "", Constants.ACC_PUBLIC | Constants.ACC_SUPER, null); } // // // Create primitive element values public void testCreateIntegerElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_INT, cp, 555); // Creation of an element like that should leave a new entry in the cpool assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupInteger(555), evg.getIndex() == cp.lookupInteger(555)); checkSerialize(evg, cp); } public void testCreateFloatElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_FLOAT, cp, 111.222f); // Creation of an element like that should leave a new entry in the cpool assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupFloat(111.222f), evg.getIndex() == cp.lookupFloat(111.222f)); checkSerialize(evg, cp); } public void testCreateDoubleElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_DOUBLE, cp, 333.44); // Creation of an element like that should leave a new entry in the cpool int idx = cp.lookupDouble(333.44); assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); checkSerialize(evg, cp); } public void testCreateLongElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_LONG, cp, 3334455L); // Creation of an element like that should leave a new entry in the cpool int idx = cp.lookupLong(3334455L); assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); checkSerialize(evg, cp); } public void testCreateCharElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_CHAR, cp, (char) 't'); // Creation of an element like that should leave a new entry in the cpool int idx = cp.lookupInteger((char) 't'); assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); checkSerialize(evg, cp); } public void testCreateByteElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_CHAR, cp, (byte) 'z'); // Creation of an element like that should leave a new entry in the cpool int idx = cp.lookupInteger((byte) 'z'); assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); checkSerialize(evg, cp); } public void testCreateBooleanElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_BOOLEAN, cp, true); // Creation of an element like that should leave a new entry in the cpool int idx = cp.lookupInteger(1); // 1 == true assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); checkSerialize(evg, cp); } public void testCreateShortElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.PRIMITIVE_SHORT, cp, (short) 42); // Creation of an element like that should leave a new entry in the cpool int idx = cp.lookupInteger(42); assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + idx, evg.getIndex() == idx); checkSerialize(evg, cp); } // // // Create string element values public void testCreateStringElementValue() { // Create HelloWorld ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); SimpleElementValue evg = new SimpleElementValue(ElementValue.STRING, cp, "hello"); // Creation of an element like that should leave a new entry in the cpool assertTrue("Should have the same index in the constantpool but " + evg.getIndex() + "!=" + cp.lookupUtf8("hello"), evg.getIndex() == cp.lookupUtf8("hello")); checkSerialize(evg, cp); } // // // Create enum element value public void testCreateEnumElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); ObjectType enumType = new ObjectType("SimpleEnum"); // Supports rainbow :) EnumElementValue evg = new EnumElementValue(enumType, "Red", cp); // Creation of an element like that should leave a new entry in the cpool assertTrue("The new ElementValue value index should match the contents of the constantpool but " + evg.getValueIndex() + "!=" + cp.lookupUtf8("Red"), evg.getValueIndex() == cp.lookupUtf8("Red")); // BCELBUG: Should the class signature or class name be in the constant pool? (see note in ConstantPool) // assertTrue("The new ElementValue type index should match the contents of the constantpool but "+ // evg.getTypeIndex()+"!="+cp.lookupClass(enumType.getSignature()), // evg.getTypeIndex()==cp.lookupClass(enumType.getSignature())); checkSerialize(evg, cp); } public void testCreateMarkerAnnotationElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); ObjectType annoType = new ObjectType("SimpleMarkerAnnotation"); AnnotationGen annoGen = new AnnotationGen(annoType, Collections. emptyList(), true, cp); AnnotationElementValue evg = new AnnotationElementValue(annoGen, cp); checkSerialize(evg, cp); } // // // Create class element value public void testCreateClassElementValue() { ClassGen cg = createClassGen("HelloWorld"); ConstantPool cp = cg.getConstantPool(); ObjectType classType = new ObjectType("java.lang.Integer"); ClassElementValue evg = new ClassElementValue(classType, cp); assertTrue("Unexpected value for contained class: '" + evg.getClassString() + "'", evg.getClassString().indexOf("Integer") != -1); checkSerialize(evg, cp); } // // // Helper methods private void checkSerialize(ElementValue evgBefore, ConstantPool cpg) { try { String beforeValue = evgBefore.stringifyValue(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); evgBefore.dump(dos); dos.flush(); dos.close(); byte[] bs = baos.toByteArray(); ByteArrayInputStream bais = new ByteArrayInputStream(bs); DataInputStream dis = new DataInputStream(bais); ElementValue evgAfter = ElementValue.readElementValue(dis, cpg); dis.close(); String afterValue = evgAfter.stringifyValue(); if (!beforeValue.equals(afterValue)) { fail("Deserialization failed: before='" + beforeValue + "' after='" + afterValue + "'"); } } catch (IOException ioe) { fail("Unexpected exception whilst checking serialization: " + ioe); } } protected void tearDown() throws Exception { super.tearDown(); } }