Home | History | Annotate | Download | only in bytecode
      1 /*
      2  * Javassist, a Java-bytecode translator toolkit.
      3  * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
      4  *
      5  * The contents of this file are subject to the Mozilla Public License Version
      6  * 1.1 (the "License"); you may not use this file except in compliance with
      7  * the License.  Alternatively, the contents of this file may be used under
      8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
      9  *
     10  * Software distributed under the License is distributed on an "AS IS" basis,
     11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     12  * for the specific language governing rights and limitations under the
     13  * License.
     14  */
     15 
     16 package javassist.bytecode;
     17 
     18 import javassist.CtClass;
     19 import javassist.bytecode.annotation.AnnotationsWriter;
     20 import javassist.bytecode.annotation.MemberValue;
     21 
     22 import java.io.ByteArrayOutputStream;
     23 import java.io.DataInputStream;
     24 import java.io.IOException;
     25 import java.util.Map;
     26 
     27 /**
     28  * A class representing <code>AnnotationDefault_attribute</code>.
     29  *
     30  * <p>For example, if you declare the following annotation type:
     31  *
     32  * <ul><pre>
     33  * &#64;interface Author {
     34  *   String name() default "Shakespeare";
     35  *   int age() default 99;
     36  * }
     37  * </pre></ul>
     38  *
     39  * <p>The defautl values of <code>name</code> and <code>age</code>
     40  * are stored as annotation default attributes in <code>Author.class</code>.
     41  * The following code snippet obtains the default value of <code>name</code>:
     42  *
     43  * <ul><pre>
     44  * ClassPool pool = ...
     45  * CtClass cc = pool.get("Author");
     46  * CtMethod cm = cc.getDeclaredMethod("age");
     47  * MethodInfo minfo = cm.getMethodInfo();
     48  * AnnotationDefaultAttribute ada
     49  *         = (AnnotationDefaultAttribute)
     50  *           minfo.getAttribute(AnnotationDefaultAttribute.tag);
     51  * MemberValue value = ada.getDefaultValue());    // default value of age
     52  * </pre></ul>
     53  *
     54  * <p>If the following statement is executed after the code above,
     55  * the default value of age is set to 80:
     56  *
     57  * <ul><pre>
     58  * ada.setDefaultValue(new IntegerMemberValue(minfo.getConstPool(), 80));
     59  * </pre></ul>
     60  *
     61  * @see AnnotationsAttribute
     62  * @see javassist.bytecode.annotation.MemberValue
     63  */
     64 
     65 public class AnnotationDefaultAttribute extends AttributeInfo {
     66     /**
     67      * The name of the <code>AnnotationDefault</code> attribute.
     68      */
     69     public static final String tag = "AnnotationDefault";
     70 
     71     /**
     72      * Constructs an <code>AnnotationDefault_attribute</code>.
     73      *
     74      * @param cp            constant pool
     75      * @param info          the contents of this attribute.  It does not
     76      *                      include <code>attribute_name_index</code> or
     77      *                      <code>attribute_length</code>.
     78      */
     79     public AnnotationDefaultAttribute(ConstPool cp, byte[] info) {
     80         super(cp, tag, info);
     81     }
     82 
     83     /**
     84      * Constructs an empty <code>AnnotationDefault_attribute</code>.
     85      * The default value can be set by <code>setDefaultValue()</code>.
     86      *
     87      * @param cp            constant pool
     88      * @see #setDefaultValue(javassist.bytecode.annotation.MemberValue)
     89      */
     90     public AnnotationDefaultAttribute(ConstPool cp) {
     91         this(cp, new byte[] { 0, 0 });
     92     }
     93 
     94     /**
     95      * @param n     the attribute name.
     96      */
     97     AnnotationDefaultAttribute(ConstPool cp, int n, DataInputStream in)
     98         throws IOException
     99     {
    100         super(cp, n, in);
    101     }
    102 
    103     /**
    104      * Copies this attribute and returns a new copy.
    105      */
    106     public AttributeInfo copy(ConstPool newCp, Map classnames) {
    107         AnnotationsAttribute.Copier copier
    108             = new AnnotationsAttribute.Copier(info, constPool, newCp, classnames);
    109         try {
    110             copier.memberValue(0);
    111             return new AnnotationDefaultAttribute(newCp, copier.close());
    112         }
    113         catch (Exception e) {
    114             throw new RuntimeException(e.toString());
    115         }
    116     }
    117 
    118     /**
    119      * Obtains the default value represented by this attribute.
    120      */
    121     public MemberValue getDefaultValue()
    122     {
    123        try {
    124            return new AnnotationsAttribute.Parser(info, constPool)
    125                                           .parseMemberValue();
    126        }
    127        catch (Exception e) {
    128            throw new RuntimeException(e.toString());
    129        }
    130     }
    131 
    132     /**
    133      * Changes the default value represented by this attribute.
    134      *
    135      * @param value         the new value.
    136      * @see javassist.bytecode.annotation.Annotation#createMemberValue(ConstPool, CtClass)
    137      */
    138     public void setDefaultValue(MemberValue value) {
    139         ByteArrayOutputStream output = new ByteArrayOutputStream();
    140         AnnotationsWriter writer = new AnnotationsWriter(output, constPool);
    141         try {
    142             value.write(writer);
    143             writer.close();
    144         }
    145         catch (IOException e) {
    146             throw new RuntimeException(e);      // should never reach here.
    147         }
    148 
    149         set(output.toByteArray());
    150 
    151     }
    152 
    153     /**
    154      * Returns a string representation of this object.
    155      */
    156     public String toString() {
    157         return getDefaultValue().toString();
    158     }
    159 }
    160