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.

CodeConverter.java 28KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  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;
  17. import javassist.bytecode.*;
  18. import javassist.convert.*;
  19. /**
  20. * Simple translator of method bodies
  21. * (also see the <code>javassist.expr</code> package).
  22. *
  23. * <p>Instances of this class specifies how to instrument of the
  24. * bytecodes representing a method body. They are passed to
  25. * <code>CtClass.instrument()</code> or
  26. * <code>CtMethod.instrument()</code> as a parameter.
  27. *
  28. * <p>Example:
  29. * <ul><pre>
  30. * ClassPool cp = ClassPool.getDefault();
  31. * CtClass point = cp.get("Point");
  32. * CtClass singleton = cp.get("Singleton");
  33. * CtClass client = cp.get("Client");
  34. * CodeConverter conv = new CodeConverter();
  35. * conv.replaceNew(point, singleton, "makePoint");
  36. * client.instrument(conv);
  37. * </pre></ul>
  38. *
  39. * <p>This program substitutes "<code>Singleton.makePoint()</code>"
  40. * for all occurrences of "<code>new Point()</code>"
  41. * appearing in methods declared in a <code>Client</code> class.
  42. *
  43. * @see javassist.CtClass#instrument(CodeConverter)
  44. * @see javassist.CtMethod#instrument(CodeConverter)
  45. * @see javassist.expr.ExprEditor
  46. */
  47. public class CodeConverter {
  48. protected Transformer transformers = null;
  49. /**
  50. * Modify a method body so that instantiation of the specified class
  51. * is replaced with a call to the specified static method. For example,
  52. * <code>replaceNew(ctPoint, ctSingleton, "createPoint")</code>
  53. * (where <code>ctPoint</code> and <code>ctSingleton</code> are
  54. * compile-time classes for class <code>Point</code> and class
  55. * <code>Singleton</code>, respectively)
  56. * replaces all occurrences of:
  57. *
  58. * <ul><code>new Point(x, y)</code></ul>
  59. *
  60. * in the method body with:
  61. *
  62. * <ul><code>Singleton.createPoint(x, y)</code></ul>
  63. *
  64. * <p>This enables to intercept instantiation of <code>Point</code>
  65. * and change the samentics. For example, the following
  66. * <code>createPoint()</code> implements the singleton pattern:
  67. *
  68. * <ul><pre>public static Point createPoint(int x, int y) {
  69. * if (aPoint == null)
  70. * aPoint = new Point(x, y);
  71. * return aPoint;
  72. * }
  73. * </pre></ul>
  74. *
  75. * <p>The static method call substituted for the original <code>new</code>
  76. * expression must be
  77. * able to receive the same set of parameters as the original
  78. * constructor. If there are multiple constructors with different
  79. * parameter types, then there must be multiple static methods
  80. * with the same name but different parameter types.
  81. *
  82. * <p>The return type of the substituted static method must be
  83. * the exactly same as the type of the instantiated class specified by
  84. * <code>newClass</code>.
  85. *
  86. * @param newClass the instantiated class.
  87. * @param calledClass the class in which the static method is
  88. * declared.
  89. * @param calledMethod the name of the static method.
  90. */
  91. public void replaceNew(CtClass newClass,
  92. CtClass calledClass, String calledMethod) {
  93. transformers = new TransformNew(transformers, newClass.getName(),
  94. calledClass.getName(), calledMethod);
  95. }
  96. /**
  97. * Modify a method body so that instantiation of the class
  98. * specified by <code>oldClass</code>
  99. * is replaced with instantiation of another class <code>newClass</code>.
  100. * For example,
  101. * <code>replaceNew(ctPoint, ctPoint2)</code>
  102. * (where <code>ctPoint</code> and <code>ctPoint2</code> are
  103. * compile-time classes for class <code>Point</code> and class
  104. * <code>Point2</code>, respectively)
  105. * replaces all occurrences of:
  106. *
  107. * <ul><code>new Point(x, y)</code></ul>
  108. *
  109. * in the method body with:
  110. *
  111. * <ul><code>new Point2(x, y)</code></ul>
  112. *
  113. * <p>Note that <code>Point2</code> must be type-compatible with <code>Point</code>.
  114. * It must have the same set of methods, fields, and constructors as the
  115. * replaced class.
  116. */
  117. public void replaceNew(CtClass oldClass, CtClass newClass) {
  118. transformers = new TransformNewClass(transformers, oldClass.getName(),
  119. newClass.getName());
  120. }
  121. /**
  122. * Modify a method body so that field read/write expressions access
  123. * a different field from the original one.
  124. *
  125. * <p>Note that this method changes only the filed name and the class
  126. * declaring the field; the type of the target object does not change.
  127. * Therefore, the substituted field must be declared in the same class
  128. * or a superclass of the original class.
  129. *
  130. * <p>Also, <code>clazz</code> and <code>newClass</code> must specify
  131. * the class directly declaring the field. They must not specify
  132. * a subclass of that class.
  133. *
  134. * @param field the originally accessed field.
  135. * @param newClass the class declaring the substituted field.
  136. * @param newFieldname the name of the substituted field.
  137. */
  138. public void redirectFieldAccess(CtField field,
  139. CtClass newClass, String newFieldname) {
  140. transformers = new TransformFieldAccess(transformers, field,
  141. newClass.getName(),
  142. newFieldname);
  143. }
  144. /**
  145. * Modify a method body so that an expression reading the specified
  146. * field is replaced with a call to the specified <i>static</i> method.
  147. * This static method receives the target object of the original
  148. * read expression as a parameter. It must return a value of
  149. * the same type as the field.
  150. *
  151. * <p>For example, the program below
  152. *
  153. * <ul><pre>Point p = new Point();
  154. * int newX = p.x + 3;</pre></ul>
  155. *
  156. * <p>can be translated into:
  157. *
  158. * <ul><pre>Point p = new Point();
  159. * int newX = Accessor.readX(p) + 3;</pre></ul>
  160. *
  161. * <p>where
  162. *
  163. * <ul><pre>public class Accessor {
  164. * public static int readX(Object target) { ... }
  165. * }</pre></ul>
  166. *
  167. * <p>The type of the parameter of <code>readX()</code> must
  168. * be <code>java.lang.Object</code> independently of the actual
  169. * type of <code>target</code>. The return type must be the same
  170. * as the field type.
  171. *
  172. * @param field the field.
  173. * @param calledClass the class in which the static method is
  174. * declared.
  175. * @param calledMethod the name of the static method.
  176. */
  177. public void replaceFieldRead(CtField field,
  178. CtClass calledClass, String calledMethod) {
  179. transformers = new TransformReadField(transformers, field,
  180. calledClass.getName(),
  181. calledMethod);
  182. }
  183. /**
  184. * Modify a method body so that an expression writing the specified
  185. * field is replaced with a call to the specified static method.
  186. * This static method receives two parameters: the target object of
  187. * the original
  188. * write expression and the assigned value. The return type of the
  189. * static method is <code>void</code>.
  190. *
  191. * <p>For example, the program below
  192. *
  193. * <ul><pre>Point p = new Point();
  194. * p.x = 3;</pre></ul>
  195. *
  196. * <p>can be translated into:
  197. *
  198. * <ul><pre>Point p = new Point();
  199. * Accessor.writeX(3);</pre></ul>
  200. *
  201. * <p>where
  202. *
  203. * <ul><pre>public class Accessor {
  204. * public static void writeX(Object target, int value) { ... }
  205. * }</pre></ul>
  206. *
  207. * <p>The type of the first parameter of <code>writeX()</code> must
  208. * be <code>java.lang.Object</code> independently of the actual
  209. * type of <code>target</code>. The type of the second parameter
  210. * is the same as the field type.
  211. *
  212. * @param field the field.
  213. * @param calledClass the class in which the static method is
  214. * declared.
  215. * @param calledMethod the name of the static method.
  216. */
  217. public void replaceFieldWrite(CtField field,
  218. CtClass calledClass, String calledMethod) {
  219. transformers = new TransformWriteField(transformers, field,
  220. calledClass.getName(),
  221. calledMethod);
  222. }
  223. /**
  224. * Modify a method body, so that ALL accesses to an array are replaced with
  225. * calls to static methods within another class. In the case of reading an
  226. * element from the array, this is replaced with a call to a static method with
  227. * the array and the index as arguments, the return value is the value read from
  228. * the array. If writing to an array, this is replaced with a call to a static
  229. * method with the array, index and new value as parameters, the return value of
  230. * the static method is <code>void</code>.
  231. *
  232. * <p>The <code>calledClass</code> parameter is the class containing the static methods to be used
  233. * for array replacement. The <code>names</code> parameter points to an implementation of
  234. * <code>ArrayAccessReplacementMethodNames</code> which specifies the names of the method to be
  235. * used for access for each type of array. For example reading from an <code>int[]</code> will
  236. * require a different method than if writing to an <code>int[]</code>, and writing to a <code>long[]</code>
  237. * will require a different method than if writing to a <code>byte[]</code>. If the implementation
  238. * of <code>ArrayAccessReplacementMethodNames</code> does not contain the name for access for a
  239. * type of array, that access is not replaced.
  240. *
  241. * <p>A default implementation of <code>ArrayAccessReplacementMethodNames</code> called
  242. * <code>DefaultArrayAccessReplacementMethodNames</code> has been provided and is what is used in the
  243. * following example. This also assumes that <code>'foo.ArrayAdvisor'</code> is the name of the
  244. * <code>CtClass</code> passed in.
  245. *
  246. * <p>If we have the following class:
  247. * <pre>class POJO{
  248. * int[] ints = new int[]{1, 2, 3, 4, 5};
  249. * long[] longs = new int[]{10, 20, 30};
  250. * Object objects = new Object[]{true, false};
  251. * Integer[] integers = new Integer[]{new Integer(10)};
  252. * }
  253. * </pre>
  254. * and this is accessed as:
  255. * <pre>POJO p = new POJO();
  256. *
  257. * //Write to int array
  258. * p.ints[2] = 7;
  259. *
  260. * //Read from int array
  261. * int i = p.ints[2];
  262. *
  263. * //Write to long array
  264. * p.longs[2] = 1000L;
  265. *
  266. * //Read from long array
  267. * long l = p.longs[2];
  268. *
  269. * //Write to Object array
  270. * p.objects[2] = "Hello";
  271. *
  272. * //Read from Object array
  273. * Object o = p.objects[2];
  274. *
  275. * //Write to Integer array
  276. * Integer integer = new Integer(5);
  277. * p.integers[0] = integer;
  278. *
  279. * //Read from Object array
  280. * integer = p.integers[0];
  281. * </pre>
  282. *
  283. * Following instrumentation we will have
  284. * <pre>POJO p = new POJO();
  285. *
  286. * //Write to int array
  287. * ArrayAdvisor.arrayWriteInt(p.ints, 2, 7);
  288. *
  289. * //Read from int array
  290. * int i = ArrayAdvisor.arrayReadInt(p.ints, 2);
  291. *
  292. * //Write to long array
  293. * ArrayAdvisor.arrayWriteLong(p.longs, 2, 1000L);
  294. *
  295. * //Read from long array
  296. * long l = ArrayAdvisor.arrayReadLong(p.longs, 2);
  297. *
  298. * //Write to Object array
  299. * ArrayAdvisor.arrayWriteObject(p.objects, 2, "Hello");
  300. *
  301. * //Read from Object array
  302. * Object o = ArrayAdvisor.arrayReadObject(p.objects, 2);
  303. *
  304. * //Write to Integer array
  305. * Integer integer = new Integer(5);
  306. * ArrayAdvisor.arrayWriteObject(p.integers, 0, integer);
  307. *
  308. * //Read from Object array
  309. * integer = ArrayAdvisor.arrayWriteObject(p.integers, 0);
  310. * </pre>
  311. *
  312. * @see DefaultArrayAccessReplacementMethodNames
  313. *
  314. * @param calledClass the class containing the static methods.
  315. * @param names contains the names of the methods to replace
  316. * the different kinds of array access with.
  317. */
  318. public void replaceArrayAccess(CtClass calledClass, ArrayAccessReplacementMethodNames names)
  319. throws NotFoundException
  320. {
  321. transformers = new TransformAccessArrayField(transformers, calledClass.getName(), names);
  322. }
  323. /**
  324. * Modify method invocations in a method body so that a different
  325. * method will be invoked.
  326. *
  327. * <p>Note that the target object, the parameters, or
  328. * the type of invocation
  329. * (static method call, interface call, or private method call)
  330. * are not modified. Only the method name is changed. The substituted
  331. * method must have the same signature that the original one has.
  332. * If the original method is a static method, the substituted method
  333. * must be static.
  334. *
  335. * @param origMethod original method
  336. * @param substMethod substituted method
  337. */
  338. public void redirectMethodCall(CtMethod origMethod,
  339. CtMethod substMethod)
  340. throws CannotCompileException
  341. {
  342. String d1 = origMethod.getMethodInfo2().getDescriptor();
  343. String d2 = substMethod.getMethodInfo2().getDescriptor();
  344. if (!d1.equals(d2))
  345. throw new CannotCompileException("signature mismatch: "
  346. + substMethod.getLongName());
  347. int mod1 = origMethod.getModifiers();
  348. int mod2 = substMethod.getModifiers();
  349. if (Modifier.isStatic(mod1) != Modifier.isStatic(mod2)
  350. || (Modifier.isPrivate(mod1) && !Modifier.isPrivate(mod2))
  351. || origMethod.getDeclaringClass().isInterface()
  352. != substMethod.getDeclaringClass().isInterface())
  353. throw new CannotCompileException("invoke-type mismatch "
  354. + substMethod.getLongName());
  355. transformers = new TransformCall(transformers, origMethod,
  356. substMethod);
  357. }
  358. /**
  359. * Correct invocations to a method that has been renamed.
  360. * If a method is renamed, calls to that method must be also
  361. * modified so that the method with the new name will be called.
  362. *
  363. * <p>The method must be declared in the same class before and
  364. * after it is renamed.
  365. *
  366. * <p>Note that the target object, the parameters, or
  367. * the type of invocation
  368. * (static method call, interface call, or private method call)
  369. * are not modified. Only the method name is changed.
  370. *
  371. * @param oldMethodName the old name of the method.
  372. * @param newMethod the method with the new name.
  373. * @see javassist.CtMethod#setName(String)
  374. */
  375. public void redirectMethodCall(String oldMethodName,
  376. CtMethod newMethod)
  377. throws CannotCompileException
  378. {
  379. transformers
  380. = new TransformCall(transformers, oldMethodName, newMethod);
  381. }
  382. /**
  383. * Insert a call to another method before an existing method call.
  384. * That "before" method must be static. The return type must be
  385. * <code>void</code>. As parameters, the before method receives
  386. * the target object and all the parameters to the originally invoked
  387. * method. For example, if the originally invoked method is
  388. * <code>move()</code>:
  389. *
  390. * <ul><pre>class Point {
  391. * Point move(int x, int y) { ... }
  392. * }</pre></ul>
  393. *
  394. * <p>Then the before method must be something like this:
  395. *
  396. * <ul><pre>class Verbose {
  397. * static void print(Point target, int x, int y) { ... }
  398. * }</pre></ul>
  399. *
  400. * <p>The <code>CodeConverter</code> would translate bytecode
  401. * equivalent to:
  402. *
  403. * <ul><pre>Point p2 = p.move(x + y, 0);</pre></ul>
  404. *
  405. * <p>into the bytecode equivalent to:
  406. *
  407. * <ul><pre>int tmp1 = x + y;
  408. * int tmp2 = 0;
  409. * Verbose.print(p, tmp1, tmp2);
  410. * Point p2 = p.move(tmp1, tmp2);</pre></ul>
  411. *
  412. * @param origMethod the method originally invoked.
  413. * @param beforeMethod the method invoked before
  414. * <code>origMethod</code>.
  415. */
  416. public void insertBeforeMethod(CtMethod origMethod,
  417. CtMethod beforeMethod)
  418. throws CannotCompileException
  419. {
  420. try {
  421. transformers = new TransformBefore(transformers, origMethod,
  422. beforeMethod);
  423. }
  424. catch (NotFoundException e) {
  425. throw new CannotCompileException(e);
  426. }
  427. }
  428. /**
  429. * Inserts a call to another method after an existing method call.
  430. * That "after" method must be static. The return type must be
  431. * <code>void</code>. As parameters, the after method receives
  432. * the target object and all the parameters to the originally invoked
  433. * method. For example, if the originally invoked method is
  434. * <code>move()</code>:
  435. *
  436. * <ul><pre>class Point {
  437. * Point move(int x, int y) { ... }
  438. * }</pre></ul>
  439. *
  440. * <p>Then the after method must be something like this:
  441. *
  442. * <ul><pre>class Verbose {
  443. * static void print(Point target, int x, int y) { ... }
  444. * }</pre></ul>
  445. *
  446. * <p>The <code>CodeConverter</code> would translate bytecode
  447. * equivalent to:
  448. *
  449. * <ul><pre>Point p2 = p.move(x + y, 0);</pre></ul>
  450. *
  451. * <p>into the bytecode equivalent to:
  452. *
  453. * <ul><pre>int tmp1 = x + y;
  454. * int tmp2 = 0;
  455. * Point p2 = p.move(tmp1, tmp2);
  456. * Verbose.print(p, tmp1, tmp2);</pre></ul>
  457. *
  458. * @param origMethod the method originally invoked.
  459. * @param afterMethod the method invoked after
  460. * <code>origMethod</code>.
  461. */
  462. public void insertAfterMethod(CtMethod origMethod,
  463. CtMethod afterMethod)
  464. throws CannotCompileException
  465. {
  466. try {
  467. transformers = new TransformAfter(transformers, origMethod,
  468. afterMethod);
  469. }
  470. catch (NotFoundException e) {
  471. throw new CannotCompileException(e);
  472. }
  473. }
  474. /**
  475. * Performs code conversion.
  476. */
  477. protected void doit(CtClass clazz, MethodInfo minfo, ConstPool cp)
  478. throws CannotCompileException
  479. {
  480. Transformer t;
  481. CodeAttribute codeAttr = minfo.getCodeAttribute();
  482. if (codeAttr == null || transformers == null)
  483. return;
  484. for (t = transformers; t != null; t = t.getNext())
  485. t.initialize(cp, clazz, minfo);
  486. CodeIterator iterator = codeAttr.iterator();
  487. while (iterator.hasNext()) {
  488. try {
  489. int pos = iterator.next();
  490. for (t = transformers; t != null; t = t.getNext())
  491. pos = t.transform(clazz, pos, iterator, cp);
  492. }
  493. catch (BadBytecode e) {
  494. throw new CannotCompileException(e);
  495. }
  496. }
  497. int locals = 0;
  498. int stack = 0;
  499. for (t = transformers; t != null; t = t.getNext()) {
  500. int s = t.extraLocals();
  501. if (s > locals)
  502. locals = s;
  503. s = t.extraStack();
  504. if (s > stack)
  505. stack = s;
  506. }
  507. for (t = transformers; t != null; t = t.getNext())
  508. t.clean();
  509. if (locals > 0)
  510. codeAttr.setMaxLocals(codeAttr.getMaxLocals() + locals);
  511. if (stack > 0)
  512. codeAttr.setMaxStack(codeAttr.getMaxStack() + stack);
  513. }
  514. /**
  515. * Interface containing the method names to be used
  516. * as array access replacements.
  517. *
  518. * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
  519. * @version $Revision: 1.16 $
  520. */
  521. public interface ArrayAccessReplacementMethodNames
  522. {
  523. /**
  524. * Returns the name of a static method with the signature
  525. * <code>(Ljava/lang/Object;I)B</code> to replace reading from a byte[].
  526. */
  527. String byteOrBooleanRead();
  528. /**
  529. * Returns the name of a static method with the signature
  530. * <code>(Ljava/lang/Object;IB)V</code> to replace writing to a byte[].
  531. */
  532. String byteOrBooleanWrite();
  533. /**
  534. * @return the name of a static method with the signature
  535. * <code>(Ljava/lang/Object;I)C</code> to replace reading from a char[].
  536. */
  537. String charRead();
  538. /**
  539. * Returns the name of a static method with the signature
  540. * <code>(Ljava/lang/Object;IC)V</code> to replace writing to a byte[].
  541. */
  542. String charWrite();
  543. /**
  544. * Returns the name of a static method with the signature
  545. * <code>(Ljava/lang/Object;I)D</code> to replace reading from a double[].
  546. */
  547. String doubleRead();
  548. /**
  549. * Returns the name of a static method with the signature
  550. * <code>(Ljava/lang/Object;ID)V</code> to replace writing to a double[].
  551. */
  552. String doubleWrite();
  553. /**
  554. * Returns the name of a static method with the signature
  555. * <code>(Ljava/lang/Object;I)F</code> to replace reading from a float[].
  556. */
  557. String floatRead();
  558. /**
  559. * Returns the name of a static method with the signature
  560. * <code>(Ljava/lang/Object;IF)V</code> to replace writing to a float[].
  561. */
  562. String floatWrite();
  563. /**
  564. * Returns the name of a static method with the signature
  565. * <code>(Ljava/lang/Object;I)I</code> to replace reading from a int[].
  566. */
  567. String intRead();
  568. /**
  569. * Returns the name of a static method with the signature
  570. * <code>(Ljava/lang/Object;II)V</code> to replace writing to a int[].
  571. */
  572. String intWrite();
  573. /**
  574. * Returns the name of a static method with the signature
  575. * <code>(Ljava/lang/Object;I)J</code> to replace reading from a long[].
  576. */
  577. String longRead();
  578. /**
  579. * Returns the name of a static method with the signature
  580. * <code>(Ljava/lang/Object;IJ)V</code> to replace writing to a long[].
  581. */
  582. String longWrite();
  583. /**
  584. * Returns the name of a static method with the signature
  585. * <code>(Ljava/lang/Object;I)Ljava/lang/Object;</code>
  586. * to replace reading from a Object[] (or any subclass of object).
  587. */
  588. String objectRead();
  589. /**
  590. * Returns the name of a static method with the signature
  591. * <code>(Ljava/lang/Object;ILjava/lang/Object;)V</code>
  592. * to replace writing to a Object[] (or any subclass of object).
  593. */
  594. String objectWrite();
  595. /**
  596. * Returns the name of a static method with the signature
  597. * <code>(Ljava/lang/Object;I)S</code> to replace reading from a short[].
  598. */
  599. String shortRead();
  600. /**
  601. * Returns the name of a static method with the signature
  602. * <code>(Ljava/lang/Object;IS)V</code> to replace writing to a short[].
  603. */
  604. String shortWrite();
  605. }
  606. /**
  607. * Default implementation of the <code>ArrayAccessReplacementMethodNames</code>
  608. * interface giving default values for method names to be used for replacing
  609. * accesses to array elements.
  610. *
  611. * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
  612. * @version $Revision: 1.16 $
  613. */
  614. public static class DefaultArrayAccessReplacementMethodNames
  615. implements ArrayAccessReplacementMethodNames
  616. {
  617. /**
  618. * Returns "arrayReadByteOrBoolean" as the name of the static method with the signature
  619. * (Ljava/lang/Object;I)B to replace reading from a byte[].
  620. */
  621. public String byteOrBooleanRead()
  622. {
  623. return "arrayReadByteOrBoolean";
  624. }
  625. /**
  626. * Returns "arrayWriteByteOrBoolean" as the name of the static method with the signature
  627. * (Ljava/lang/Object;IB)V to replace writing to a byte[].
  628. */
  629. public String byteOrBooleanWrite()
  630. {
  631. return "arrayWriteByteOrBoolean";
  632. }
  633. /**
  634. * Returns "arrayReadChar" as the name of the static method with the signature
  635. * (Ljava/lang/Object;I)C to replace reading from a char[].
  636. */
  637. public String charRead()
  638. {
  639. return "arrayReadChar";
  640. }
  641. /**
  642. * Returns "arrayWriteChar" as the name of the static method with the signature
  643. * (Ljava/lang/Object;IC)V to replace writing to a byte[].
  644. */
  645. public String charWrite()
  646. {
  647. return "arrayWriteChar";
  648. }
  649. /**
  650. * Returns "arrayReadDouble" as the name of the static method with the signature
  651. * (Ljava/lang/Object;I)D to replace reading from a double[].
  652. */
  653. public String doubleRead()
  654. {
  655. return "arrayReadDouble";
  656. }
  657. /**
  658. * Returns "arrayWriteDouble" as the name of the static method with the signature
  659. * (Ljava/lang/Object;ID)V to replace writing to a double[].
  660. */
  661. public String doubleWrite()
  662. {
  663. return "arrayWriteDouble";
  664. }
  665. /**
  666. * Returns "arrayReadFloat" as the name of the static method with the signature
  667. * (Ljava/lang/Object;I)F to replace reading from a float[].
  668. */
  669. public String floatRead()
  670. {
  671. return "arrayReadFloat";
  672. }
  673. /**
  674. * Returns "arrayWriteFloat" as the name of the static method with the signature
  675. * (Ljava/lang/Object;IF)V to replace writing to a float[].
  676. */
  677. public String floatWrite()
  678. {
  679. return "arrayWriteFloat";
  680. }
  681. /**
  682. * Returns "arrayReadInt" as the name of the static method with the signature
  683. * (Ljava/lang/Object;I)I to replace reading from a int[].
  684. */
  685. public String intRead()
  686. {
  687. return "arrayReadInt";
  688. }
  689. /**
  690. * Returns "arrayWriteInt" as the name of the static method with the signature
  691. * (Ljava/lang/Object;II)V to replace writing to a int[].
  692. */
  693. public String intWrite()
  694. {
  695. return "arrayWriteInt";
  696. }
  697. /**
  698. * Returns "arrayReadLong" as the name of the static method with the signature
  699. * (Ljava/lang/Object;I)J to replace reading from a long[].
  700. */
  701. public String longRead()
  702. {
  703. return "arrayReadLong";
  704. }
  705. /**
  706. * Returns "arrayWriteLong" as the name of the static method with the signature
  707. * (Ljava/lang/Object;IJ)V to replace writing to a long[].
  708. */
  709. public String longWrite()
  710. {
  711. return "arrayWriteLong";
  712. }
  713. /**
  714. * Returns "arrayReadObject" as the name of the static method with the signature
  715. * (Ljava/lang/Object;I)Ljava/lang/Object; to replace reading from a Object[] (or any subclass of object).
  716. */
  717. public String objectRead()
  718. {
  719. return "arrayReadObject";
  720. }
  721. /**
  722. * Returns "arrayWriteObject" as the name of the static method with the signature
  723. * (Ljava/lang/Object;ILjava/lang/Object;)V to replace writing to a Object[] (or any subclass of object).
  724. */
  725. public String objectWrite()
  726. {
  727. return "arrayWriteObject";
  728. }
  729. /**
  730. * Returns "arrayReadShort" as the name of the static method with the signature
  731. * (Ljava/lang/Object;I)S to replace reading from a short[].
  732. */
  733. public String shortRead()
  734. {
  735. return "arrayReadShort";
  736. }
  737. /**
  738. * Returns "arrayWriteShort" as the name of the static method with the signature
  739. * (Ljava/lang/Object;IS)V to replace writing to a short[].
  740. */
  741. public String shortWrite()
  742. {
  743. return "arrayWriteShort";
  744. }
  745. }
  746. }