• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 package javassist.bytecode;
17 
18 import java.util.HashMap;
19 import java.util.Map;
20 import java.io.IOException;
21 import java.io.DataInputStream;
22 import java.io.ByteArrayOutputStream;
23 
24 import javassist.bytecode.AnnotationsAttribute.Copier;
25 import javassist.bytecode.AnnotationsAttribute.Parser;
26 import javassist.bytecode.AnnotationsAttribute.Renamer;
27 import javassist.bytecode.annotation.*;
28 
29 /**
30  * A class representing <code>RuntimeVisibleAnnotations_attribute</code> and
31  * <code>RuntimeInvisibleAnnotations_attribute</code>.
32  *
33  * <p>To obtain an ParameterAnnotationAttribute object, invoke
34  * <code>getAttribute(ParameterAnnotationsAttribute.invisibleTag)</code>
35  * in <code>MethodInfo</code>.
36  * The obtained attribute is a
37  * runtime invisible annotations attribute.
38  * If the parameter is
39  * <code>ParameterAnnotationAttribute.visibleTag</code>, then the obtained
40  * attribute is a runtime visible one.
41  */
42 public class ParameterAnnotationsAttribute extends AttributeInfo {
43     /**
44      * The name of the <code>RuntimeVisibleParameterAnnotations</code>
45      * attribute.
46      */
47     public static final String visibleTag
48         = "RuntimeVisibleParameterAnnotations";
49 
50     /**
51      * The name of the <code>RuntimeInvisibleParameterAnnotations</code>
52      * attribute.
53      */
54     public static final String invisibleTag
55         = "RuntimeInvisibleParameterAnnotations";
56     /**
57      * Constructs
58      * a <code>Runtime(In)VisibleParameterAnnotations_attribute</code>.
59      *
60      * @param cp            constant pool
61      * @param attrname      attribute name (<code>visibleTag</code> or
62      *                      <code>invisibleTag</code>).
63      * @param info          the contents of this attribute.  It does not
64      *                      include <code>attribute_name_index</code> or
65      *                      <code>attribute_length</code>.
66      */
ParameterAnnotationsAttribute(ConstPool cp, String attrname, byte[] info)67     public ParameterAnnotationsAttribute(ConstPool cp, String attrname,
68                                          byte[] info) {
69         super(cp, attrname, info);
70     }
71 
72     /**
73      * Constructs an empty
74      * <code>Runtime(In)VisibleParameterAnnotations_attribute</code>.
75      * A new annotation can be later added to the created attribute
76      * by <code>setAnnotations()</code>.
77      *
78      * @param cp            constant pool
79      * @param attrname      attribute name (<code>visibleTag</code> or
80      *                      <code>invisibleTag</code>).
81      * @see #setAnnotations(Annotation[][])
82      */
ParameterAnnotationsAttribute(ConstPool cp, String attrname)83     public ParameterAnnotationsAttribute(ConstPool cp, String attrname) {
84         this(cp, attrname, new byte[] { 0 });
85     }
86 
87     /**
88      * @param n     the attribute name.
89      */
ParameterAnnotationsAttribute(ConstPool cp, int n, DataInputStream in)90     ParameterAnnotationsAttribute(ConstPool cp, int n, DataInputStream in)
91         throws IOException
92     {
93         super(cp, n, in);
94     }
95 
96     /**
97      * Returns <code>num_parameters</code>.
98      */
numParameters()99     public int numParameters() {
100         return info[0] & 0xff;
101     }
102 
103     /**
104      * Copies this attribute and returns a new copy.
105      */
copy(ConstPool newCp, Map classnames)106     public AttributeInfo copy(ConstPool newCp, Map classnames) {
107         Copier copier = new Copier(info, constPool, newCp, classnames);
108         try {
109             copier.parameters();
110             return new ParameterAnnotationsAttribute(newCp, getName(),
111                                                      copier.close());
112         }
113         catch (Exception e) {
114             throw new RuntimeException(e.toString());
115         }
116     }
117 
118     /**
119      * Parses the annotations and returns a data structure representing
120      * that parsed annotations.  Note that changes of the node values of the
121      * returned tree are not reflected on the annotations represented by
122      * this object unless the tree is copied back to this object by
123      * <code>setAnnotations()</code>.
124      *
125      * @return Each element of the returned array represents an array of
126      * annotations that are associated with each method parameter.
127      *
128      * @see #setAnnotations(Annotation[][])
129      */
getAnnotations()130     public Annotation[][] getAnnotations() {
131         try {
132             return new Parser(info, constPool).parseParameters();
133         }
134         catch (Exception e) {
135             throw new RuntimeException(e.toString());
136         }
137     }
138 
139     /**
140      * Changes the annotations represented by this object according to
141      * the given array of <code>Annotation</code> objects.
142      *
143      * @param params        the data structure representing the
144      *                      new annotations. Every element of this array
145      *                      is an array of <code>Annotation</code> and
146      *                      it represens annotations of each method parameter.
147      */
setAnnotations(Annotation[][] params)148     public void setAnnotations(Annotation[][] params) {
149         ByteArrayOutputStream output = new ByteArrayOutputStream();
150         AnnotationsWriter writer = new AnnotationsWriter(output, constPool);
151         try {
152             int n = params.length;
153             writer.numParameters(n);
154             for (int i = 0; i < n; ++i) {
155                 Annotation[] anno = params[i];
156                 writer.numAnnotations(anno.length);
157                 for (int j = 0; j < anno.length; ++j)
158                     anno[j].write(writer);
159             }
160 
161             writer.close();
162         }
163         catch (IOException e) {
164             throw new RuntimeException(e);      // should never reach here.
165         }
166 
167         set(output.toByteArray());
168     }
169 
170     /**
171      * @param oldname       a JVM class name.
172      * @param newname       a JVM class name.
173      */
renameClass(String oldname, String newname)174     void renameClass(String oldname, String newname) {
175         HashMap map = new HashMap();
176         map.put(oldname, newname);
177         renameClass(map);
178     }
179 
renameClass(Map classnames)180     void renameClass(Map classnames) {
181         Renamer renamer = new Renamer(info, getConstPool(), classnames);
182         try {
183             renamer.parameters();
184         } catch (Exception e) {
185             throw new RuntimeException(e);
186         }
187     }
188 
getRefClasses(Map classnames)189     void getRefClasses(Map classnames) { renameClass(classnames); }
190 
191     /**
192      * Returns a string representation of this object.
193      */
toString()194     public String toString() {
195         Annotation[][] aa = getAnnotations();
196         StringBuilder sbuf = new StringBuilder();
197         int k = 0;
198         while (k < aa.length) {
199             Annotation[] a = aa[k++];
200             int i = 0;
201             while (i < a.length) {
202                 sbuf.append(a[i++].toString());
203                 if (i != a.length)
204                     sbuf.append(" ");
205             }
206 
207             if (k != aa.length)
208                 sbuf.append(", ");
209         }
210 
211         return sbuf.toString();
212 
213     }
214 }
215