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 java.util.HashMap; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Map; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.IOException; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.DataInputStream; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.ByteArrayOutputStream; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.AnnotationsAttribute.Copier; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.AnnotationsAttribute.Parser; 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.AnnotationsAttribute.Renamer; 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.annotation.*; 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A class representing <code>RuntimeVisibleAnnotations_attribute</code> and 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>RuntimeInvisibleAnnotations_attribute</code>. 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>To obtain an ParameterAnnotationAttribute object, invoke 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>getAttribute(ParameterAnnotationsAttribute.invisibleTag)</code> 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * in <code>MethodInfo</code>. 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The obtained attribute is a 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * runtime invisible annotations attribute. 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the parameter is 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>ParameterAnnotationAttribute.visibleTag</code>, then the obtained 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * attribute is a runtime visible one. 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class ParameterAnnotationsAttribute extends AttributeInfo { 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The name of the <code>RuntimeVisibleParameterAnnotations</code> 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * attribute. 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final String visibleTag 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = "RuntimeVisibleParameterAnnotations"; 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The name of the <code>RuntimeInvisibleParameterAnnotations</code> 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * attribute. 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final String invisibleTag 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = "RuntimeInvisibleParameterAnnotations"; 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a <code>Runtime(In)VisibleParameterAnnotations_attribute</code>. 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp constant pool 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param attrname attribute name (<code>visibleTag</code> or 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>invisibleTag</code>). 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param info the contents of this attribute. It does not 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * include <code>attribute_name_index</code> or 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>attribute_length</code>. 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ParameterAnnotationsAttribute(ConstPool cp, String attrname, 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] info) { 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(cp, attrname, info); 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs an empty 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Runtime(In)VisibleParameterAnnotations_attribute</code>. 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A new annotation can be later added to the created attribute 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * by <code>setAnnotations()</code>. 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp constant pool 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param attrname attribute name (<code>visibleTag</code> or 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>invisibleTag</code>). 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see #setAnnotations(Annotation[][]) 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ParameterAnnotationsAttribute(ConstPool cp, String attrname) { 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this(cp, attrname, new byte[] { 0 }); 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param n the attribute name. 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ParameterAnnotationsAttribute(ConstPool cp, int n, DataInputStream in) 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws IOException 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(cp, n, in); 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns <code>num_parameters</code>. 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int numParameters() { 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return info[0] & 0xff; 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 Copier copier = new Copier(info, constPool, newCp, classnames); 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal copier.parameters(); 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new ParameterAnnotationsAttribute(newCp, getName(), 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 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 * Parses the annotations and returns a data structure representing 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * that parsed annotations. Note that changes of the node values of the 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * returned tree are not reflected on the annotations represented by 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * this object unless the tree is copied back to this object by 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>setAnnotations()</code>. 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return Each element of the returned array represents an array of 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * annotations that are associated with each method parameter. 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see #setAnnotations(Annotation[][]) 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Annotation[][] getAnnotations() { 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new Parser(info, constPool).parseParameters(); 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (Exception e) { 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new RuntimeException(e.toString()); 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Changes the annotations represented by this object according to 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the given array of <code>Annotation</code> objects. 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param params the data structure representing the 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * new annotations. Every element of this array 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is an array of <code>Annotation</code> and 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * it represens annotations of each method parameter. 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setAnnotations(Annotation[][] params) { 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteArrayOutputStream output = new ByteArrayOutputStream(); 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal AnnotationsWriter writer = new AnnotationsWriter(output, constPool); 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = params.length; 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writer.numParameters(n); 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) { 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Annotation[] anno = params[i]; 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writer.numAnnotations(anno.length); 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int j = 0; j < anno.length; ++j) 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal anno[j].write(writer); 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writer.close(); 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IOException e) { 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new RuntimeException(e); // should never reach here. 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal set(output.toByteArray()); 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param oldname a JVM class name. 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param newname a JVM class name. 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void renameClass(String oldname, String newname) { 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal HashMap map = new HashMap(); 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal map.put(oldname, newname); 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal renameClass(map); 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void renameClass(Map classnames) { 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Renamer renamer = new Renamer(info, getConstPool(), classnames); 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal renamer.parameters(); 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } catch (Exception e) { 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new RuntimeException(e); 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void getRefClasses(Map classnames) { renameClass(classnames); } 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns a string representation of this object. 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Annotation[][] aa = getAnnotations(); 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuilder sbuf = new StringBuilder(); 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int k = 0; 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (k < aa.length) { 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Annotation[] a = aa[k++]; 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = 0; 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (i < a.length) { 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(a[i++].toString()); 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i != a.length) 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" "); 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (k != aa.length) 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(", "); 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf.toString(); 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 215