169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.annotation.AnnotationsWriter;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.annotation.MemberValue;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.ByteArrayOutputStream;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.DataInputStream;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.IOException;
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Map;
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A class representing <code>AnnotationDefault_attribute</code>.
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>For example, if you declare the following annotation type:
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * &#64;interface Author {
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   String name() default "Shakespeare";
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *   int age() default 99;
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * }
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul>
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>The defautl values of <code>name</code> and <code>age</code>
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * are stored as annotation default attributes in <code>Author.class</code>.
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The following code snippet obtains the default value of <code>name</code>:
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ClassPool pool = ...
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * CtClass cc = pool.get("Author");
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * CtMethod cm = cc.getDeclaredMethod("age");
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * MethodInfo minfo = cm.getMethodInfo();
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * AnnotationDefaultAttribute ada
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *         = (AnnotationDefaultAttribute)
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *           minfo.getAttribute(AnnotationDefaultAttribute.tag);
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * MemberValue value = ada.getDefaultValue());    // default value of age
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul>
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>If the following statement is executed after the code above,
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the default value of age is set to 80:
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <ul><pre>
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ada.setDefaultValue(new IntegerMemberValue(minfo.getConstPool(), 80));
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * </pre></ul>
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see AnnotationsAttribute
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.bytecode.annotation.MemberValue
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class AnnotationDefaultAttribute extends AttributeInfo {
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The name of the <code>AnnotationDefault</code> attribute.
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static final String tag = "AnnotationDefault";
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Constructs an <code>AnnotationDefault_attribute</code>.
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param cp            constant pool
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param info          the contents of this attribute.  It does not
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      include <code>attribute_name_index</code> or
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *                      <code>attribute_length</code>.
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public AnnotationDefaultAttribute(ConstPool cp, byte[] info) {
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super(cp, tag, info);
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Constructs an empty <code>AnnotationDefault_attribute</code>.
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The default value can be set by <code>setDefaultValue()</code>.
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param cp            constant pool
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see #setDefaultValue(javassist.bytecode.annotation.MemberValue)
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public AnnotationDefaultAttribute(ConstPool cp) {
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this(cp, new byte[] { 0, 0 });
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param n     the attribute name.
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    AnnotationDefaultAttribute(ConstPool cp, int n, DataInputStream in)
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throws IOException
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super(cp, n, in);
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Copies this attribute and returns a new copy.
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public AttributeInfo copy(ConstPool newCp, Map classnames) {
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        AnnotationsAttribute.Copier copier
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            = new AnnotationsAttribute.Copier(info, constPool, newCp, classnames);
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            copier.memberValue(0);
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new AnnotationDefaultAttribute(newCp, copier.close());
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (Exception e) {
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException(e.toString());
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Obtains the default value represented by this attribute.
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public MemberValue getDefaultValue()
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    {
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       try {
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal           return new AnnotationsAttribute.Parser(info, constPool)
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                          .parseMemberValue();
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       }
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       catch (Exception e) {
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal           throw new RuntimeException(e.toString());
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal       }
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Changes the default value represented by this attribute.
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param value         the new value.
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @see javassist.bytecode.annotation.Annotation#createMemberValue(ConstPool, CtClass)
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void setDefaultValue(MemberValue value) {
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        ByteArrayOutputStream output = new ByteArrayOutputStream();
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        AnnotationsWriter writer = new AnnotationsWriter(output, constPool);
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        try {
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            value.write(writer);
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            writer.close();
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        catch (IOException e) {
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new RuntimeException(e);      // should never reach here.
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        set(output.toByteArray());
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Returns a string representation of this object.
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public String toString() {
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return getDefaultValue().toString();
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
160