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

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