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.

AnnotationsWriter.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2006 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. package javassist.bytecode.annotation;
  16. import java.io.*;
  17. import javassist.bytecode.ByteArray;
  18. import javassist.bytecode.ConstPool;
  19. /**
  20. * A convenience class for constructing a
  21. * <code>..Annotations_attribute</code>.
  22. * See the source code of the <code>AnnotationsAttribute.Copier</code> class.
  23. *
  24. * <p>The following code snippet is an example of use of this class:
  25. *
  26. * <ul><pre>
  27. * ConstPool pool = ...;
  28. * output = new ByteArrayOutputStream();
  29. * writer = new AnnotationsWriter(output, pool);
  30. *
  31. * writer.numAnnotations(1);
  32. * writer.annotation("Author", 2);
  33. * writer.memberValuePair("name");
  34. * writer.constValueIndex("chiba");
  35. * writer.memberValuePair("address");
  36. * writer.constValueIndex("tokyo");
  37. *
  38. * writer.close();
  39. * byte[] attribute_info = output.toByteArray();
  40. * AnnotationsAttribute anno
  41. * = new AnnotationsAttribute(pool, AnnotationsAttribute.visibleTag,
  42. * attribute_info);
  43. * </pre></ul>
  44. *
  45. * <p>The code snippet above generates the annotation attribute
  46. * corresponding to this annotation:
  47. *
  48. * <ul><pre>
  49. * &nbsp;@Author(name = "chiba", address = "tokyo")
  50. * </pre></ul>
  51. *
  52. * @see javassist.bytecode.AnnotationsAttribute
  53. * @see javassist.bytecode.ParameterAnnotationsAttribute
  54. */
  55. public class AnnotationsWriter {
  56. private OutputStream output;
  57. private ConstPool pool;
  58. /**
  59. * Constructs with the given output stream.
  60. *
  61. * @param os the output stream.
  62. * @param cp the constant pool.
  63. */
  64. public AnnotationsWriter(OutputStream os, ConstPool cp) {
  65. output = os;
  66. pool = cp;
  67. }
  68. /**
  69. * Obtains the constant pool given to the constructor.
  70. */
  71. public ConstPool getConstPool() {
  72. return pool;
  73. }
  74. /**
  75. * Closes the output stream.
  76. *
  77. */
  78. public void close() throws IOException {
  79. output.close();
  80. }
  81. /**
  82. * Writes <code>num_parameters</code> in
  83. * <code>Runtime(In)VisibleParameterAnnotations_attribute</code>.
  84. * This method must be followed by <code>num</code> calls to
  85. * <code>numAnnotations()</code>.
  86. */
  87. public void numParameters(int num) throws IOException {
  88. output.write(num);
  89. }
  90. /**
  91. * Writes <code>num_annotations</code> in
  92. * <code>Runtime(In)VisibleAnnotations_attribute</code>.
  93. * This method must be followed by <code>num</code> calls to
  94. * <code>annotation()</code>.
  95. */
  96. public void numAnnotations(int num) throws IOException {
  97. write16bit(num);
  98. }
  99. /**
  100. * Writes <code>annotation</code>.
  101. * This method must be followed by <code>numMemberValuePairs</code>
  102. * calls to <code>memberValuePair()</code>.
  103. *
  104. * @param type the annotation interface name.
  105. * @param numMemberValuePairs <code>num_member_value_pairs</code>
  106. * in <code>annotation</code>.
  107. */
  108. public void annotation(String type, int numMemberValuePairs)
  109. throws IOException
  110. {
  111. annotation(pool.addUtf8Info(type), numMemberValuePairs);
  112. }
  113. /**
  114. * Writes <code>annotation</code>.
  115. * This method must be followed by <code>numMemberValuePairs</code>
  116. * calls to <code>memberValuePair()</code>.
  117. *
  118. * @param typeIndex <code>type_index</code> in <code>annotation</code>.
  119. * @param numMemberValuePairs <code>num_member_value_pairs</code>
  120. * in <code>annotation</code>.
  121. */
  122. public void annotation(int typeIndex, int numMemberValuePairs)
  123. throws IOException
  124. {
  125. write16bit(typeIndex);
  126. write16bit(numMemberValuePairs);
  127. }
  128. /**
  129. * Writes an element of a <code>member_value_pairs</code> array
  130. * in <code>annotation</code>.
  131. * This method must be followed by a
  132. * call to <code>constValueIndex()</code>, <code>enumConstValue()</code>,
  133. * etc.
  134. *
  135. * @param memberName the name of the annotation type member.
  136. */
  137. public void memberValuePair(String memberName) throws IOException {
  138. memberValuePair(pool.addUtf8Info(memberName));
  139. }
  140. /**
  141. * Writes an element of a <code>member_value_pairs</code> array
  142. * in <code>annotation</code>.
  143. * This method must be followed by a
  144. * call to <code>constValueIndex()</code>, <code>enumConstValue()</code>,
  145. * etc.
  146. *
  147. * @param memberNameIndex <code>member_name_index</code>
  148. * in <code>member_value_pairs</code> array.
  149. */
  150. public void memberValuePair(int memberNameIndex) throws IOException {
  151. write16bit(memberNameIndex);
  152. }
  153. /**
  154. * Writes <code>tag</code> and <code>const_value_index</code>
  155. * in <code>member_value</code>.
  156. *
  157. * @param value the constant value.
  158. */
  159. public void constValueIndex(boolean value) throws IOException {
  160. constValueIndex('Z', pool.addIntegerInfo(value ? 1 : 0));
  161. }
  162. /**
  163. * Writes <code>tag</code> and <code>const_value_index</code>
  164. * in <code>member_value</code>.
  165. *
  166. * @param value the constant value.
  167. */
  168. public void constValueIndex(byte value) throws IOException {
  169. constValueIndex('B', pool.addIntegerInfo(value));
  170. }
  171. /**
  172. * Writes <code>tag</code> and <code>const_value_index</code>
  173. * in <code>member_value</code>.
  174. *
  175. * @param value the constant value.
  176. */
  177. public void constValueIndex(char value) throws IOException {
  178. constValueIndex('C', pool.addIntegerInfo(value));
  179. }
  180. /**
  181. * Writes <code>tag</code> and <code>const_value_index</code>
  182. * in <code>member_value</code>.
  183. *
  184. * @param value the constant value.
  185. */
  186. public void constValueIndex(short value) throws IOException {
  187. constValueIndex('S', pool.addIntegerInfo(value));
  188. }
  189. /**
  190. * Writes <code>tag</code> and <code>const_value_index</code>
  191. * in <code>member_value</code>.
  192. *
  193. * @param value the constant value.
  194. */
  195. public void constValueIndex(int value) throws IOException {
  196. constValueIndex('I', pool.addIntegerInfo(value));
  197. }
  198. /**
  199. * Writes <code>tag</code> and <code>const_value_index</code>
  200. * in <code>member_value</code>.
  201. *
  202. * @param value the constant value.
  203. */
  204. public void constValueIndex(long value) throws IOException {
  205. constValueIndex('J', pool.addLongInfo(value));
  206. }
  207. /**
  208. * Writes <code>tag</code> and <code>const_value_index</code>
  209. * in <code>member_value</code>.
  210. *
  211. * @param value the constant value.
  212. */
  213. public void constValueIndex(float value) throws IOException {
  214. constValueIndex('F', pool.addFloatInfo(value));
  215. }
  216. /**
  217. * Writes <code>tag</code> and <code>const_value_index</code>
  218. * in <code>member_value</code>.
  219. *
  220. * @param value the constant value.
  221. */
  222. public void constValueIndex(double value) throws IOException {
  223. constValueIndex('D', pool.addDoubleInfo(value));
  224. }
  225. /**
  226. * Writes <code>tag</code> and <code>const_value_index</code>
  227. * in <code>member_value</code>.
  228. *
  229. * @param value the constant value.
  230. */
  231. public void constValueIndex(String value) throws IOException {
  232. constValueIndex('s', pool.addUtf8Info(value));
  233. }
  234. /**
  235. * Writes <code>tag</code> and <code>const_value_index</code>
  236. * in <code>member_value</code>.
  237. *
  238. * @param tag <code>tag</code> in <code>member_value</code>.
  239. * @param index <code>const_value_index</code>
  240. * in <code>member_value</code>.
  241. */
  242. public void constValueIndex(int tag, int index)
  243. throws IOException
  244. {
  245. output.write(tag);
  246. write16bit(index);
  247. }
  248. /**
  249. * Writes <code>tag</code> and <code>enum_const_value</code>
  250. * in <code>member_value</code>.
  251. *
  252. * @param typeName the type name of the enum constant.
  253. * @param constName the simple name of the enum constant.
  254. */
  255. public void enumConstValue(String typeName, String constName)
  256. throws IOException
  257. {
  258. enumConstValue(pool.addUtf8Info(typeName),
  259. pool.addUtf8Info(constName));
  260. }
  261. /**
  262. * Writes <code>tag</code> and <code>enum_const_value</code>
  263. * in <code>member_value</code>.
  264. *
  265. * @param typeNameIndex <code>type_name_index</code>
  266. * in <code>member_value</code>.
  267. * @param constNameIndex <code>const_name_index</code>
  268. * in <code>member_value</code>.
  269. */
  270. public void enumConstValue(int typeNameIndex, int constNameIndex)
  271. throws IOException
  272. {
  273. output.write('e');
  274. write16bit(typeNameIndex);
  275. write16bit(constNameIndex);
  276. }
  277. /**
  278. * Writes <code>tag</code> and <code>class_info_index</code>
  279. * in <code>member_value</code>.
  280. *
  281. * @param name the class name.
  282. */
  283. public void classInfoIndex(String name) throws IOException {
  284. classInfoIndex(pool.addUtf8Info(name));
  285. }
  286. /**
  287. * Writes <code>tag</code> and <code>class_info_index</code>
  288. * in <code>member_value</code>.
  289. *
  290. * @param index <code>class_info_index</code>
  291. */
  292. public void classInfoIndex(int index) throws IOException {
  293. output.write('c');
  294. write16bit(index);
  295. }
  296. /**
  297. * Writes <code>tag</code> and <code>annotation_value</code>
  298. * in <code>member_value</code>.
  299. * This method must be followed by a call to <code>annotation()</code>.
  300. */
  301. public void annotationValue() throws IOException {
  302. output.write('@');
  303. }
  304. /**
  305. * Writes <code>tag</code> and <code>array_value</code>
  306. * in <code>member_value</code>.
  307. * This method must be followed by <code>numValues</code> calls
  308. * to <code>constValueIndex()</code>, <code>enumConstValue()</code>,
  309. * etc.
  310. *
  311. * @param numValues <code>num_values</code>
  312. * in <code>array_value</code>.
  313. */
  314. public void arrayValue(int numValues) throws IOException {
  315. output.write('[');
  316. write16bit(numValues);
  317. }
  318. private void write16bit(int value) throws IOException {
  319. byte[] buf = new byte[2];
  320. ByteArray.write16bit(value, buf, 0);
  321. output.write(buf);
  322. }
  323. }