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