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 29KB

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