From bf8c6f9ca9884e77b0ea328a7b49a008f7f84c39 Mon Sep 17 00:00:00 2001 From: chiba Date: Sun, 27 Feb 2005 15:01:18 +0000 Subject: [PATCH] add support for obtaining default annotation member values (the same patch as Bill's but more javadoc comments) git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@161 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- .../bytecode/AnnotationDefaultAttribute.java | 159 ++++++++++++++++++ .../bytecode/AnnotationsAttribute.java | 53 ++++-- .../javassist/bytecode/AttributeInfo.java | 4 +- .../bytecode/annotation/Annotation.java | 42 +++-- .../annotation/AnnotationMemberValue.java | 5 +- .../bytecode/annotation/ArrayMemberValue.java | 5 +- .../annotation/BooleanMemberValue.java | 5 +- .../bytecode/annotation/ByteMemberValue.java | 5 +- .../bytecode/annotation/CharMemberValue.java | 5 +- .../bytecode/annotation/ClassMemberValue.java | 5 +- .../annotation/DoubleMemberValue.java | 7 +- .../bytecode/annotation/EnumMemberValue.java | 5 +- .../bytecode/annotation/FloatMemberValue.java | 7 +- .../annotation/IntegerMemberValue.java | 5 +- .../bytecode/annotation/LongMemberValue.java | 5 +- .../bytecode/annotation/MemberValue.java | 5 +- .../bytecode/annotation/ShortMemberValue.java | 5 +- .../annotation/StringMemberValue.java | 5 +- 18 files changed, 287 insertions(+), 45 deletions(-) create mode 100644 src/main/javassist/bytecode/AnnotationDefaultAttribute.java diff --git a/src/main/javassist/bytecode/AnnotationDefaultAttribute.java b/src/main/javassist/bytecode/AnnotationDefaultAttribute.java new file mode 100644 index 00000000..196774e5 --- /dev/null +++ b/src/main/javassist/bytecode/AnnotationDefaultAttribute.java @@ -0,0 +1,159 @@ +/* + * Javassist, a Java-bytecode translator toolkit. + * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved. + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. Alternatively, the contents of this file may be used under + * the terms of the GNU Lesser General Public License Version 2.1 or later. + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + */ + +package javassist.bytecode; + +import javassist.CtClass; +import javassist.bytecode.annotation.AnnotationsWriter; +import javassist.bytecode.annotation.MemberValue; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.Map; + +/** + * A class representing AnnotationDefault_attribute. + * + *

For example, if you declare the following annotation type: + * + *

+ * + *

The defautl values of name and age + * are stored as annotation default attributes in Author.class. + * The following code snippet obtains the default value of name: + * + *

+ * + *

If the following statement is executed after the code above, + * the default value of age is set to 80: + * + *

+ * + * @see AnnotationsAttribute + * @see javassist.bytecode.annotation.MemberValue + */ + +public class AnnotationDefaultAttribute extends AttributeInfo { + /** + * The name of the AnnotationDefault attribute. + */ + public static final String tag = "AnnotationDefault"; + + /** + * Constructs an AnnotationDefault_attribute. + * + * @param cp constant pool + * @param info the contents of this attribute. It does not + * include attribute_name_index or + * attribute_length. + */ + public AnnotationDefaultAttribute(ConstPool cp, byte[] info) { + super(cp, tag, info); + } + + /** + * Constructs an empty AnnotationDefault_attribute. + * The default value can be set by setDefaultValue(). + * + * @param cp constant pool + * @see #setDefaultValue(javassist.bytecode.annotation.MemberValue) + */ + public AnnotationDefaultAttribute(ConstPool cp) { + this(cp, new byte[] { 0, 0 }); + } + + /** + * @param n the attribute name. + */ + AnnotationDefaultAttribute(ConstPool cp, int n, DataInputStream in) + throws IOException + { + super(cp, n, in); + } + + /** + * Copies this attribute and returns a new copy. + */ + public AttributeInfo copy(ConstPool newCp, Map classnames) { + AnnotationsAttribute.Copier copier + = new AnnotationsAttribute.Copier(info, constPool, newCp, classnames); + try { + copier.memberValue(0); + return new AnnotationDefaultAttribute(newCp, copier.close()); + } + catch (Exception e) { + throw new RuntimeException(e.toString()); + } + } + + /** + * Obtains the default value represented by this attribute. + */ + public MemberValue getDefaultValue() + { + try { + return new AnnotationsAttribute.Parser(info, constPool) + .parseMemberValue(); + } + catch (Exception e) { + throw new RuntimeException(e.toString()); + } + } + + /** + * Changes the default value represented by this attribute. + * + * @param value the new value. + * @see javassist.bytecode.annotation.Annotation#createMemberValue(ConstPool, CtClass) + */ + public void setDefaultValue(MemberValue value) { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + AnnotationsWriter writer = new AnnotationsWriter(output, constPool); + try { + value.write(writer); + writer.close(); + } + catch (IOException e) { + throw new RuntimeException(e); // should never reach here. + } + + set(output.toByteArray()); + + } + + /** + * Returns a string representation of this object. + */ + public String toString() { + return getDefaultValue().toString(); + } +} diff --git a/src/main/javassist/bytecode/AnnotationsAttribute.java b/src/main/javassist/bytecode/AnnotationsAttribute.java index 34c82c4c..d3cb9494 100644 --- a/src/main/javassist/bytecode/AnnotationsAttribute.java +++ b/src/main/javassist/bytecode/AnnotationsAttribute.java @@ -38,12 +38,14 @@ import javassist.bytecode.annotation.*; *

For example, * *

* @@ -51,6 +53,31 @@ import javassist.bytecode.annotation.*; * from the MethodInfo object specified by minfo. * Then, it prints the value of name in Author. * + *

If the annotation type Author is annotated by a meta annotation: + * + *

+ * + *

Then Author is visible at runtime. Therefore, the third + * statement of the code snippet above must be changed into: + * + *

+ * + *

The attribute tag must be visibleTag instead of + * invisibleTag. + * + *

If the member value of an annotation is not specified, the default value + * is used as that member value. If so, getMemberValue() in + * Annotation returns null + * since the default value is not included in the + * AnnotationsAttribute. It is included in the + * AnnotationDefaultAttribute of the method declared in the + * annotation type. + * *

If you want to record a new AnnotationAttribute object, execute the * following snippet: * @@ -65,6 +92,7 @@ import javassist.bytecode.annotation.*; * cf.addAttribute(attr); * * + * @see AnnotationDefaultAttribute * @see javassist.bytecode.annotation.Annotation */ public class AnnotationsAttribute extends AttributeInfo { @@ -448,7 +476,7 @@ public class AnnotationsAttribute extends AttributeInfo { Annotation[][] allParams; // all parameters Annotation[] allAnno; // all annotations Annotation currentAnno; // current annotation - MemberValue memberValue; + MemberValue currentMember; // current member /** * Constructs a parser. This parser constructs a parse tree of @@ -472,6 +500,11 @@ public class AnnotationsAttribute extends AttributeInfo { return allAnno; } + MemberValue parseMemberValue() throws Exception { + memberValue(0); + return currentMember; + } + void parameters(int numParam, int pos) throws Exception { Annotation[][] params = new Annotation[numParam][]; for (int i = 0; i < numParam; ++i) { @@ -500,7 +533,7 @@ public class AnnotationsAttribute extends AttributeInfo { int memberValuePair(int pos, int nameIndex) throws Exception { pos = super.memberValuePair(pos, nameIndex); - currentAnno.addMemberValue(nameIndex, memberValue); + currentAnno.addMemberValue(nameIndex, currentMember); return pos; } @@ -539,27 +572,27 @@ public class AnnotationsAttribute extends AttributeInfo { throw new RuntimeException("unknown tag:" + tag); } - memberValue = m; + currentMember = m; super.constValueMember(tag, index); } void enumMemberValue(int typeNameIndex, int constNameIndex) throws Exception { - memberValue = new EnumMemberValue(typeNameIndex, + currentMember = new EnumMemberValue(typeNameIndex, constNameIndex, pool); super.enumMemberValue(typeNameIndex, constNameIndex); } void classMemberValue(int index) throws Exception { - memberValue = new ClassMemberValue(index, pool); + currentMember = new ClassMemberValue(index, pool); super.classMemberValue(index); } int annotationMemberValue(int pos) throws Exception { Annotation anno = currentAnno; pos = super.annotationMemberValue(pos); - memberValue = new AnnotationMemberValue(currentAnno, pool); + currentMember = new AnnotationMemberValue(currentAnno, pool); currentAnno = anno; return pos; } @@ -569,11 +602,11 @@ public class AnnotationsAttribute extends AttributeInfo { MemberValue[] elements = new MemberValue[num]; for (int i = 0; i < num; ++i) { pos = memberValue(pos); - elements[i] = memberValue; + elements[i] = currentMember; } amv.setValue(elements); - memberValue = amv; + currentMember = amv; return pos; } } diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java index 6fce7943..8fd598da 100644 --- a/src/main/javassist/bytecode/AttributeInfo.java +++ b/src/main/javassist/bytecode/AttributeInfo.java @@ -72,7 +72,9 @@ public class AttributeInfo { int name = in.readUnsignedShort(); String nameStr = cp.getUtf8Info(name); if (nameStr.charAt(0) < 'L') { - if (nameStr.equals(CodeAttribute.tag)) + if (nameStr.equals(AnnotationDefaultAttribute.tag)) + return new AnnotationDefaultAttribute(cp, name, in); + else if (nameStr.equals(CodeAttribute.tag)) return new CodeAttribute(cp, name, in); else if (nameStr.equals(ConstantAttribute.tag)) return new ConstantAttribute(cp, name, in); diff --git a/src/main/javassist/bytecode/annotation/Annotation.java b/src/main/javassist/bytecode/annotation/Annotation.java index 3373edb4..b9c63b9b 100644 --- a/src/main/javassist/bytecode/annotation/Annotation.java +++ b/src/main/javassist/bytecode/annotation/Annotation.java @@ -109,36 +109,42 @@ public class Annotation { } } - private MemberValue createMemberValue(ConstPool cp, CtClass returnType) + /** + * Makes an instance of MemberValue. + * + * @param cp the constant pool table. + * @param type the type of the member. + */ + public static MemberValue createMemberValue(ConstPool cp, CtClass type) throws javassist.NotFoundException { - if (returnType == CtClass.booleanType) + if (type == CtClass.booleanType) return new BooleanMemberValue(cp); - else if (returnType == CtClass.byteType) + else if (type == CtClass.byteType) return new ByteMemberValue(cp); - else if (returnType == CtClass.charType) + else if (type == CtClass.charType) return new CharMemberValue(cp); - else if (returnType == CtClass.shortType) + else if (type == CtClass.shortType) return new ShortMemberValue(cp); - else if (returnType == CtClass.intType) + else if (type == CtClass.intType) return new IntegerMemberValue(cp); - else if (returnType == CtClass.longType) + else if (type == CtClass.longType) return new LongMemberValue(cp); - else if (returnType == CtClass.floatType) + else if (type == CtClass.floatType) return new FloatMemberValue(cp); - else if (returnType == CtClass.doubleType) + else if (type == CtClass.doubleType) return new DoubleMemberValue(cp); - else if (returnType.getName().equals("java.lang.Class")) + else if (type.getName().equals("java.lang.Class")) return new ClassMemberValue(cp); - else if (returnType.getName().equals("java.lang.String")) + else if (type.getName().equals("java.lang.String")) return new StringMemberValue(cp); - else if (returnType.isArray()) { - CtClass arrayType = returnType.getComponentType(); - MemberValue type = createMemberValue(cp, arrayType); - return new ArrayMemberValue(type, cp); + else if (type.isArray()) { + CtClass arrayType = type.getComponentType(); + MemberValue member = createMemberValue(cp, arrayType); + return new ArrayMemberValue(member, cp); } - else if (returnType.isInterface()) { - Annotation info = new Annotation(cp, returnType); + else if (type.isInterface()) { + Annotation info = new Annotation(cp, type); return new AnnotationMemberValue(info, cp); } else { @@ -146,7 +152,7 @@ public class Annotation { // but JBoss has an Annotation Compiler for JDK 1.4 // and I want it to work with that. - Bill Burke EnumMemberValue emv = new EnumMemberValue(cp); - emv.setType(returnType.getName()); + emv.setType(type.getName()); return emv; } } diff --git a/src/main/javassist/bytecode/annotation/AnnotationMemberValue.java b/src/main/javassist/bytecode/annotation/AnnotationMemberValue.java index 6d99ef33..92b3e2d4 100644 --- a/src/main/javassist/bytecode/annotation/AnnotationMemberValue.java +++ b/src/main/javassist/bytecode/annotation/AnnotationMemberValue.java @@ -63,7 +63,10 @@ public class AnnotationMemberValue extends MemberValue { return value.toString(); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.annotationValue(); value.write(writer); } diff --git a/src/main/javassist/bytecode/annotation/ArrayMemberValue.java b/src/main/javassist/bytecode/annotation/ArrayMemberValue.java index 27c8ddc0..351ffc56 100644 --- a/src/main/javassist/bytecode/annotation/ArrayMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ArrayMemberValue.java @@ -89,7 +89,10 @@ public class ArrayMemberValue extends MemberValue { return buf.toString(); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { int num = values.length; writer.arrayValue(num); for (int i = 0; i < num; ++i) diff --git a/src/main/javassist/bytecode/annotation/BooleanMemberValue.java b/src/main/javassist/bytecode/annotation/BooleanMemberValue.java index 64b1e2f7..4f6507e5 100644 --- a/src/main/javassist/bytecode/annotation/BooleanMemberValue.java +++ b/src/main/javassist/bytecode/annotation/BooleanMemberValue.java @@ -76,7 +76,10 @@ public class BooleanMemberValue extends MemberValue { return getValue() ? "true" : "false"; } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/ByteMemberValue.java b/src/main/javassist/bytecode/annotation/ByteMemberValue.java index 5b9cd3ca..043f1d21 100644 --- a/src/main/javassist/bytecode/annotation/ByteMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ByteMemberValue.java @@ -76,7 +76,10 @@ public class ByteMemberValue extends MemberValue { return Byte.toString(getValue()); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/CharMemberValue.java b/src/main/javassist/bytecode/annotation/CharMemberValue.java index 8bca8183..c01b7b78 100644 --- a/src/main/javassist/bytecode/annotation/CharMemberValue.java +++ b/src/main/javassist/bytecode/annotation/CharMemberValue.java @@ -77,7 +77,10 @@ public class CharMemberValue extends MemberValue { return Character.toString(getValue()); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/ClassMemberValue.java b/src/main/javassist/bytecode/annotation/ClassMemberValue.java index 0be36b24..90da2c41 100644 --- a/src/main/javassist/bytecode/annotation/ClassMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ClassMemberValue.java @@ -85,7 +85,10 @@ public class ClassMemberValue extends MemberValue { return "<" + getValue() + " class>"; } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.classInfoIndex(valueIndex); } diff --git a/src/main/javassist/bytecode/annotation/DoubleMemberValue.java b/src/main/javassist/bytecode/annotation/DoubleMemberValue.java index b4658bbb..131e35f8 100644 --- a/src/main/javassist/bytecode/annotation/DoubleMemberValue.java +++ b/src/main/javassist/bytecode/annotation/DoubleMemberValue.java @@ -23,7 +23,7 @@ import java.io.IOException; * * @author Bill Burke * @author Shigeru Chiba - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ */ public class DoubleMemberValue extends MemberValue { int valueIndex; @@ -78,7 +78,10 @@ public class DoubleMemberValue extends MemberValue { return Double.toString(getValue()); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/EnumMemberValue.java b/src/main/javassist/bytecode/annotation/EnumMemberValue.java index 95c617ad..44430781 100644 --- a/src/main/javassist/bytecode/annotation/EnumMemberValue.java +++ b/src/main/javassist/bytecode/annotation/EnumMemberValue.java @@ -88,7 +88,10 @@ public class EnumMemberValue extends MemberValue { return getType() + "." + getValue(); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.enumConstValue(getType(), getValue()); } diff --git a/src/main/javassist/bytecode/annotation/FloatMemberValue.java b/src/main/javassist/bytecode/annotation/FloatMemberValue.java index 5496e379..87e12ab7 100644 --- a/src/main/javassist/bytecode/annotation/FloatMemberValue.java +++ b/src/main/javassist/bytecode/annotation/FloatMemberValue.java @@ -23,7 +23,7 @@ import java.io.IOException; * * @author Bill Burke * @author Shigeru Chiba - * @version $Revision: 1.4 $ + * @version $Revision: 1.5 $ */ public class FloatMemberValue extends MemberValue { int valueIndex; @@ -78,7 +78,10 @@ public class FloatMemberValue extends MemberValue { return Float.toString(getValue()); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/IntegerMemberValue.java b/src/main/javassist/bytecode/annotation/IntegerMemberValue.java index 9268ee69..e8846276 100644 --- a/src/main/javassist/bytecode/annotation/IntegerMemberValue.java +++ b/src/main/javassist/bytecode/annotation/IntegerMemberValue.java @@ -83,7 +83,10 @@ public class IntegerMemberValue extends MemberValue { return Integer.toString(getValue()); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/LongMemberValue.java b/src/main/javassist/bytecode/annotation/LongMemberValue.java index c7ec125c..4842792f 100644 --- a/src/main/javassist/bytecode/annotation/LongMemberValue.java +++ b/src/main/javassist/bytecode/annotation/LongMemberValue.java @@ -77,7 +77,10 @@ public class LongMemberValue extends MemberValue { return Long.toString(getValue()); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/MemberValue.java b/src/main/javassist/bytecode/annotation/MemberValue.java index f2265522..4d0c3554 100644 --- a/src/main/javassist/bytecode/annotation/MemberValue.java +++ b/src/main/javassist/bytecode/annotation/MemberValue.java @@ -38,7 +38,10 @@ public abstract class MemberValue { */ public abstract void accept(MemberValueVisitor visitor); - abstract void write(AnnotationsWriter w) throws IOException; + /** + * Writes the value. + */ + public abstract void write(AnnotationsWriter w) throws IOException; } diff --git a/src/main/javassist/bytecode/annotation/ShortMemberValue.java b/src/main/javassist/bytecode/annotation/ShortMemberValue.java index cd9f9429..fc0a1702 100644 --- a/src/main/javassist/bytecode/annotation/ShortMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ShortMemberValue.java @@ -77,7 +77,10 @@ public class ShortMemberValue extends MemberValue { return Short.toString(getValue()); } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } diff --git a/src/main/javassist/bytecode/annotation/StringMemberValue.java b/src/main/javassist/bytecode/annotation/StringMemberValue.java index 5e5c9580..4a32e433 100644 --- a/src/main/javassist/bytecode/annotation/StringMemberValue.java +++ b/src/main/javassist/bytecode/annotation/StringMemberValue.java @@ -77,7 +77,10 @@ public class StringMemberValue extends MemberValue { return "\"" + getValue() + "\""; } - void write(AnnotationsWriter writer) throws IOException { + /** + * Writes the value. + */ + public void write(AnnotationsWriter writer) throws IOException { writer.constValueIndex(getValue()); } -- 2.39.5