You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ParameterAnnotationsAttribute.java 7.1KB

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