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
16package javassist.bytecode;
17
18import javassist.CtClass;
19import javassist.bytecode.annotation.AnnotationsWriter;
20import javassist.bytecode.annotation.MemberValue;
21
22import java.io.ByteArrayOutputStream;
23import java.io.DataInputStream;
24import java.io.IOException;
25import 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
65public 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