Kaynağa Gözat

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
tags/rel_3_17_1_ga
chiba 19 yıl önce
ebeveyn
işleme
bf8c6f9ca9

+ 159
- 0
src/main/javassist/bytecode/AnnotationDefaultAttribute.java Dosyayı Görüntüle

@@ -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 <code>AnnotationDefault_attribute</code>.
*
* <p>For example, if you declare the following annotation type:
*
* <ul><pre>
* &#64;interface Author {
* String name() default "Shakespeare";
* int age() default 99;
* }
* </pre></ul>
*
* <p>The defautl values of <code>name</code> and <code>age</code>
* are stored as annotation default attributes in <code>Author.class</code>.
* The following code snippet obtains the default value of <code>name</code>:
*
* <ul><pre>
* ClassPool pool = ...
* CtClass cc = pool.get("Author");
* CtMethod cm = cc.getDeclaredMethod("age");
* MethodInfo minfo = cm.getMethodInfo();
* AnnotationDefaultAttribute ada
* = (AnnotationDefaultAttribute)
* minfo.getAttribute(AnnotationDefaultAttribute.tag);
* MemberValue value = ada.getDefaultValue()); // default value of age
* </pre></ul>
*
* <p>If the following statement is executed after the code above,
* the default value of age is set to 80:
*
* <ul><pre>
* ada.setDefaultValue(new IntegerMemberValue(minfo.getConstPool(), 80));
* </pre></ul>
*
* @see AnnotationsAttribute
* @see javassist.bytecode.annotation.MemberValue
*/

public class AnnotationDefaultAttribute extends AttributeInfo {
/**
* The name of the <code>AnnotationDefault</code> attribute.
*/
public static final String tag = "AnnotationDefault";

/**
* Constructs an <code>AnnotationDefault_attribute</code>.
*
* @param cp constant pool
* @param info the contents of this attribute. It does not
* include <code>attribute_name_index</code> or
* <code>attribute_length</code>.
*/
public AnnotationDefaultAttribute(ConstPool cp, byte[] info) {
super(cp, tag, info);
}

/**
* Constructs an empty <code>AnnotationDefault_attribute</code>.
* The default value can be set by <code>setDefaultValue()</code>.
*
* @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();
}
}

+ 43
- 10
src/main/javassist/bytecode/AnnotationsAttribute.java Dosyayı Görüntüle

@@ -38,12 +38,14 @@ import javassist.bytecode.annotation.*;
* <p>For example,
*
* <ul><pre>
* import javassist.bytecode.annotation.Annotation;
* :
* CtMethod m = ... ;
* MethodInfo minfo = m.getMethodInfo();
* AnnotationsAttribute attr = (AnnotationsAttribute)
* minfo.getAttribute(AnnotationsAttribute.visibleTag);
* minfo.getAttribute(AnnotationsAttribute.invisibleTag);
* Annotation an = attr.getAnnotation("Author");
* String s = ((StringMemberValue)a.getMemberValue("name")).getValue();
* String s = ((StringMemberValue)an.getMemberValue("name")).getValue();
* System.out.println("@Author(name=" + s + ")");
* </pre></ul>
*
@@ -51,6 +53,31 @@ import javassist.bytecode.annotation.*;
* from the <code>MethodInfo</code> object specified by <code>minfo</code>.
* Then, it prints the value of <code>name</code> in <code>Author</code>.
*
* <p>If the annotation type <code>Author</code> is annotated by a meta annotation:
*
* <ul><pre>
* &#64;Retention(RetentionPolicy.RUNTIME)
* </pre></ul>
*
* <p>Then <code>Author</code> is visible at runtime. Therefore, the third
* statement of the code snippet above must be changed into:
*
* <ul><pre>
* AnnotationsAttribute attr = (AnnotationsAttribute)
* minfo.getAttribute(AnnotationsAttribute.visibleTag);
* </pre></ul>
*
* <p>The attribute tag must be <code>visibleTag</code> instead of
* <code>invisibleTag</code>.
*
* <p>If the member value of an annotation is not specified, the default value
* is used as that member value. If so, <code>getMemberValue()</code> in
* <code>Annotation</code> returns <code>null</code>
* since the default value is not included in the
* <code>AnnotationsAttribute</code>. It is included in the
* <code>AnnotationDefaultAttribute</code> of the method declared in the
* annotation type.
*
* <p>If you want to record a new AnnotationAttribute object, execute the
* following snippet:
*
@@ -65,6 +92,7 @@ import javassist.bytecode.annotation.*;
* cf.addAttribute(attr);
* </pre></ul>
*
* @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;
}
}

+ 3
- 1
src/main/javassist/bytecode/AttributeInfo.java Dosyayı Görüntüle

@@ -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);

+ 24
- 18
src/main/javassist/bytecode/annotation/Annotation.java Dosyayı Görüntüle

@@ -109,36 +109,42 @@ public class Annotation {
}
}

private MemberValue createMemberValue(ConstPool cp, CtClass returnType)
/**
* Makes an instance of <code>MemberValue</code>.
*
* @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;
}
}

+ 4
- 1
src/main/javassist/bytecode/annotation/AnnotationMemberValue.java Dosyayı Görüntüle

@@ -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);
}

+ 4
- 1
src/main/javassist/bytecode/annotation/ArrayMemberValue.java Dosyayı Görüntüle

@@ -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)

+ 4
- 1
src/main/javassist/bytecode/annotation/BooleanMemberValue.java Dosyayı Görüntüle

@@ -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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/ByteMemberValue.java Dosyayı Görüntüle

@@ -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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/CharMemberValue.java Dosyayı Görüntüle

@@ -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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/ClassMemberValue.java Dosyayı Görüntüle

@@ -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);
}


+ 5
- 2
src/main/javassist/bytecode/annotation/DoubleMemberValue.java Dosyayı Görüntüle

@@ -23,7 +23,7 @@ import java.io.IOException;
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
* @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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/EnumMemberValue.java Dosyayı Görüntüle

@@ -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());
}


+ 5
- 2
src/main/javassist/bytecode/annotation/FloatMemberValue.java Dosyayı Görüntüle

@@ -23,7 +23,7 @@ import java.io.IOException;
*
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
* @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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/IntegerMemberValue.java Dosyayı Görüntüle

@@ -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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/LongMemberValue.java Dosyayı Görüntüle

@@ -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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/MemberValue.java Dosyayı Görüntüle

@@ -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;
}



+ 4
- 1
src/main/javassist/bytecode/annotation/ShortMemberValue.java Dosyayı Görüntüle

@@ -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());
}


+ 4
- 1
src/main/javassist/bytecode/annotation/StringMemberValue.java Dosyayı Görüntüle

@@ -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());
}


Loading…
İptal
Kaydet