]> source.dussan.org Git - javassist.git/commitdiff
add support for obtaining default annotation member values (the same patch as Bill...
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 27 Feb 2005 15:01:18 +0000 (15:01 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Sun, 27 Feb 2005 15:01:18 +0000 (15:01 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@161 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

18 files changed:
src/main/javassist/bytecode/AnnotationDefaultAttribute.java [new file with mode: 0644]
src/main/javassist/bytecode/AnnotationsAttribute.java
src/main/javassist/bytecode/AttributeInfo.java
src/main/javassist/bytecode/annotation/Annotation.java
src/main/javassist/bytecode/annotation/AnnotationMemberValue.java
src/main/javassist/bytecode/annotation/ArrayMemberValue.java
src/main/javassist/bytecode/annotation/BooleanMemberValue.java
src/main/javassist/bytecode/annotation/ByteMemberValue.java
src/main/javassist/bytecode/annotation/CharMemberValue.java
src/main/javassist/bytecode/annotation/ClassMemberValue.java
src/main/javassist/bytecode/annotation/DoubleMemberValue.java
src/main/javassist/bytecode/annotation/EnumMemberValue.java
src/main/javassist/bytecode/annotation/FloatMemberValue.java
src/main/javassist/bytecode/annotation/IntegerMemberValue.java
src/main/javassist/bytecode/annotation/LongMemberValue.java
src/main/javassist/bytecode/annotation/MemberValue.java
src/main/javassist/bytecode/annotation/ShortMemberValue.java
src/main/javassist/bytecode/annotation/StringMemberValue.java

diff --git a/src/main/javassist/bytecode/AnnotationDefaultAttribute.java b/src/main/javassist/bytecode/AnnotationDefaultAttribute.java
new file mode 100644 (file)
index 0000000..196774e
--- /dev/null
@@ -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();
+    }
+}
index 34c82c4c645e9d3ea8cd266ffc4d97b3d8920426..d3cb9494a0883ed3994df30089c0dcd53ea21327 100644 (file)
@@ -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;
         }
     }
index 6fce79439a56dad6ead3a3ec4c6748f16d1bbd9e..8fd598da5a4664af523c158cfa6d36eca79b3e05 100644 (file)
@@ -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);
index 3373edb4ebae17b5b36ec32647d4bb94d3b1600a..b9c63b9be87b91b1344996f97fa821bddd9b649e 100644 (file)
@@ -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;
         }
     }
index 6d99ef334917c13a01df823bc7719cfd6151873c..92b3e2d4876ac3e284079d2fa7f0448ca95b09ea 100644 (file)
@@ -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);
     }
index 27c8ddc0912f772f4c6bac39c9ea1f3e3e067a80..351ffc56cce86b9e997bfc9c78037316534cd423 100644 (file)
@@ -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)
index 64b1e2f75e02518bba72cc8ee540d4f86560f6d7..4f6507e5822e6369009132e9826232ed4eb0d4df 100644 (file)
@@ -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());
     }
 
index 5b9cd3ca39e19f48a45124762a812facbc701cde..043f1d2186b9fc4f3789343c99aaeb3b6630bc07 100644 (file)
@@ -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());
     }
 
index 8bca818371d2e92b5b9aef7a5ae12b7bd641e872..c01b7b78c2edaaaadc46ffe89b739ce593f38a8e 100644 (file)
@@ -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());
     }
 
index 0be36b24ce857b54cbf7cee5545e18fee59e0312..90da2c41b6e517974b3ddf9ae67435e38bcc6f20 100644 (file)
@@ -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);
     }
 
index b4658bbba9506ad584045db7328dbcbdaae9204d..131e35f82f02b25963b6352436a9459dbbe116a6 100644 (file)
@@ -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());
     }
 
index 95c617adcd1302726352f28c7645fe98ff628a42..44430781312ca3797e3ab0aea2240b993305010d 100644 (file)
@@ -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());
     }
 
index 5496e379e9f4aeafb15220db9f68023bebb701df..87e12ab7cceec8539b2c378ca9e3f34322458e3d 100644 (file)
@@ -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());
     }
 
index 9268ee691df9aa9d8393c3c94f9c4a3685355d77..e88462764a0cf744ec517f6e5e2fa94b87853842 100644 (file)
@@ -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());
     }
 
index c7ec125ca2d0176cd21e0768f5fb50289db61a5c..4842792f81a40098c91145d5195ff62e95aca66d 100644 (file)
@@ -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());
     }
 
index f2265522af26ff5e1b34097217750b464f935f7a..4d0c3554876949ae7bdb64b24961ddb092b2371a 100644 (file)
@@ -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;
 }
 
 
index cd9f9429fb09246b5f6d44dcea35d97e90bf207c..fc0a1702cab9d65245f3cf9da1ecdda605f8fa59 100644 (file)
@@ -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());
     }
 
index 5e5c9580c3ed6982f0c2bf786def0d2c0bdd0242..4a32e433bb1990f91f57160005ff4e220b71f5f7 100644 (file)
@@ -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());
     }