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