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.

Callback.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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.tools;
  17. import javassist.CannotCompileException;
  18. import javassist.CtBehavior;
  19. import java.util.HashMap;
  20. import java.util.UUID;
  21. /**
  22. * Creates bytecode that when executed calls back to the instance's result method.
  23. *
  24. * <p>Example of how to create and insert a callback:</p>
  25. * <pre>
  26. * ctMethod.insertAfter(new Callback("Thread.currentThread()") {
  27. * public void result(Object... objects) {
  28. * Thread thread = (Thread) objects[0];
  29. * // do something with thread...
  30. * }
  31. * }.sourceCode());
  32. * </pre>
  33. * <p>Contains utility methods for inserts callbacks in <code>CtBehaviour</code>, example:</p>
  34. * <pre>
  35. * insertAfter(ctBehaviour, new Callback("Thread.currentThread(), dummyString") {
  36. * public void result(Object... objects) {
  37. * Thread thread = (Thread) objects[0];
  38. * // do something with thread...
  39. * }
  40. * });
  41. * </pre>
  42. *
  43. * @author Marten Hedborg
  44. */
  45. public abstract class Callback {
  46. public static HashMap<String, Callback> callbacks = new HashMap<String, Callback>();
  47. private final String sourceCode;
  48. /**
  49. * Constructs a new <code>Callback</code> object.
  50. *
  51. * @param src The source code representing the inserted callback bytecode.
  52. * Can be one or many single statements each returning one object.
  53. * If many single statements are used they must be comma separated.
  54. */
  55. public Callback(String src){
  56. String uuid = UUID.randomUUID().toString();
  57. callbacks.put(uuid, this);
  58. sourceCode = "((javassist.tools.Callback) javassist.tools.Callback.callbacks.get(\""+uuid+"\")).result(new Object[]{"+src+"});";
  59. }
  60. /**
  61. * Gets called when bytecode is executed
  62. *
  63. * @param objects Objects that the bytecode in callback returns
  64. */
  65. public abstract void result(Object... objects);
  66. @Override
  67. public String toString(){
  68. return sourceCode();
  69. }
  70. public String sourceCode(){
  71. return sourceCode;
  72. }
  73. /**
  74. * Utility method to insert callback at the beginning of the body.
  75. *
  76. * @param callback The callback
  77. *
  78. * @see CtBehavior#insertBefore(String)
  79. */
  80. public static void insertBefore(CtBehavior behavior, Callback callback)
  81. throws CannotCompileException
  82. {
  83. behavior.insertBefore(callback.toString());
  84. }
  85. /**
  86. * Utility method to inserts callback at the end of the body.
  87. * The callback is inserted just before every return instruction.
  88. * It is not executed when an exception is thrown.
  89. *
  90. * @param behavior The behaviour to insert callback in
  91. * @param callback The callback
  92. *
  93. * @see CtBehavior#insertAfter(String, boolean)
  94. */
  95. public static void insertAfter(CtBehavior behavior,Callback callback)
  96. throws CannotCompileException
  97. {
  98. behavior.insertAfter(callback.toString(), false);
  99. }
  100. /**
  101. * Utility method to inserts callback at the end of the body.
  102. * The callback is inserted just before every return instruction.
  103. * It is not executed when an exception is thrown.
  104. *
  105. * @param behavior The behaviour to insert callback in
  106. * @param callback The callback representing the inserted.
  107. * @param asFinally True if the inserted is executed
  108. * Not only when the control normally returns
  109. * but also when an exception is thrown.
  110. * If this parameter is true, the inserted code cannot
  111. * access local variables.
  112. *
  113. * @see CtBehavior#insertAfter(String, boolean)
  114. */
  115. public static void insertAfter(CtBehavior behavior, Callback callback, boolean asFinally)
  116. throws CannotCompileException
  117. {
  118. behavior.insertAfter(callback.toString(), asFinally);
  119. }
  120. /**
  121. * Utility method to inserts callback at the specified line in the body.
  122. *
  123. * @param behavior The behaviour to insert callback in
  124. * @param callback The callback representing.
  125. * @param lineNum The line number. The callback is inserted at the
  126. * beginning of the code at the line specified by this
  127. * line number.
  128. *
  129. * @return The line number at which the callback has been inserted.
  130. *
  131. * @see CtBehavior#insertAt(int, String)
  132. */
  133. public static int insertAt(CtBehavior behavior, Callback callback, int lineNum)
  134. throws CannotCompileException
  135. {
  136. return behavior.insertAt(lineNum, callback.toString());
  137. }
  138. }