Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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.util.proxy;
  17. import java.lang.reflect.Method;
  18. import java.io.Serializable;
  19. /**
  20. * Runtime support routines that the classes generated by ProxyFactory use.
  21. *
  22. * @see ProxyFactory
  23. */
  24. public class RuntimeSupport {
  25. /**
  26. * A method handler that only executes a method.
  27. */
  28. public static MethodHandler default_interceptor = new DefaultMethodHandler();
  29. static class DefaultMethodHandler implements MethodHandler, Serializable {
  30. public Object invoke(Object self, Method m,
  31. Method proceed, Object[] args)
  32. throws Exception
  33. {
  34. return proceed.invoke(self, args);
  35. }
  36. };
  37. /**
  38. * Finds two methods specified by the parameters and stores them
  39. * into the given array.
  40. *
  41. * @throws RuntimeException if the methods are not found.
  42. * @see javassist.util.proxy.ProxyFactory
  43. */
  44. public static void find2Methods(Object self, String superMethod,
  45. String thisMethod, int index,
  46. String desc, java.lang.reflect.Method[] methods)
  47. {
  48. synchronized (methods) {
  49. if (methods[index] == null) {
  50. methods[index + 1] = thisMethod == null ? null
  51. : findMethod(self, thisMethod, desc);
  52. methods[index] = findSuperMethod(self, superMethod, desc);
  53. }
  54. }
  55. }
  56. /**
  57. * Finds a method with the given name and descriptor.
  58. * It searches only the class of self.
  59. *
  60. * @throws RuntimeException if the method is not found.
  61. */
  62. public static Method findMethod(Object self, String name, String desc) {
  63. Method m = findMethod2(self.getClass(), name, desc);
  64. if (m == null)
  65. error(self, name, desc);
  66. return m;
  67. }
  68. /**
  69. * Finds a method that has the given name and descriptor and is declared
  70. * in the super class.
  71. *
  72. * @throws RuntimeException if the method is not found.
  73. */
  74. public static Method findSuperMethod(Object self, String name, String desc) {
  75. Class clazz = self.getClass();
  76. Method m = findSuperMethod2(clazz.getSuperclass(), name, desc);
  77. if (m == null)
  78. m = searchInterfaces(clazz, name, desc);
  79. if (m == null)
  80. error(self, name, desc);
  81. return m;
  82. }
  83. private static void error(Object self, String name, String desc) {
  84. throw new RuntimeException("not found " + name + ":" + desc
  85. + " in " + self.getClass().getName());
  86. }
  87. private static Method findSuperMethod2(Class clazz, String name, String desc) {
  88. Method m = findMethod2(clazz, name, desc);
  89. if (m != null)
  90. return m;
  91. Class superClass = clazz.getSuperclass();
  92. if (superClass != null) {
  93. m = findSuperMethod2(superClass, name, desc);
  94. if (m != null)
  95. return m;
  96. }
  97. return searchInterfaces(clazz, name, desc);
  98. }
  99. private static Method searchInterfaces(Class clazz, String name, String desc) {
  100. Method m = null;
  101. Class[] interfaces = clazz.getInterfaces();
  102. for (int i = 0; i < interfaces.length; i++) {
  103. m = findSuperMethod2(interfaces[i], name, desc);
  104. if (m != null)
  105. return m;
  106. }
  107. return m;
  108. }
  109. private static Method findMethod2(Class clazz, String name, String desc) {
  110. Method[] methods = SecurityActions.getDeclaredMethods(clazz);
  111. int n = methods.length;
  112. for (int i = 0; i < n; i++)
  113. if (methods[i].getName().equals(name)
  114. && makeDescriptor(methods[i]).equals(desc))
  115. return methods[i];
  116. return null;
  117. }
  118. /**
  119. * Makes a descriptor for a given method.
  120. */
  121. public static String makeDescriptor(Method m) {
  122. Class[] params = m.getParameterTypes();
  123. return makeDescriptor(params, m.getReturnType());
  124. }
  125. /**
  126. * Makes a descriptor for a given method.
  127. *
  128. * @param params parameter types.
  129. * @param retType return type.
  130. */
  131. public static String makeDescriptor(Class[] params, Class retType) {
  132. StringBuffer sbuf = new StringBuffer();
  133. sbuf.append('(');
  134. for (int i = 0; i < params.length; i++)
  135. makeDesc(sbuf, params[i]);
  136. sbuf.append(')');
  137. if (retType != null)
  138. makeDesc(sbuf, retType);
  139. return sbuf.toString();
  140. }
  141. /**
  142. * Makes a descriptor for a given method.
  143. *
  144. * @param params the descriptor of parameter types.
  145. * @param retType return type.
  146. */
  147. public static String makeDescriptor(String params, Class retType) {
  148. StringBuffer sbuf = new StringBuffer(params);
  149. makeDesc(sbuf, retType);
  150. return sbuf.toString();
  151. }
  152. private static void makeDesc(StringBuffer sbuf, Class type) {
  153. if (type.isArray()) {
  154. sbuf.append('[');
  155. makeDesc(sbuf, type.getComponentType());
  156. }
  157. else if (type.isPrimitive()) {
  158. if (type == Void.TYPE)
  159. sbuf.append('V');
  160. else if (type == Integer.TYPE)
  161. sbuf.append('I');
  162. else if (type == Byte.TYPE)
  163. sbuf.append('B');
  164. else if (type == Long.TYPE)
  165. sbuf.append('J');
  166. else if (type == Double.TYPE)
  167. sbuf.append('D');
  168. else if (type == Float.TYPE)
  169. sbuf.append('F');
  170. else if (type == Character.TYPE)
  171. sbuf.append('C');
  172. else if (type == Short.TYPE)
  173. sbuf.append('S');
  174. else if (type == Boolean.TYPE)
  175. sbuf.append('Z');
  176. else
  177. throw new RuntimeException("bad type: " + type.getName());
  178. }
  179. else
  180. sbuf.append('L').append(type.getName().replace('.', '/'))
  181. .append(';');
  182. }
  183. /**
  184. * Converts a proxy object to an object that is writable to an
  185. * object stream. This method is called by <code>writeReplace()</code>
  186. * in a proxy class.
  187. *
  188. * @since 3.4
  189. */
  190. public static SerializedProxy makeSerializedProxy(Object proxy)
  191. throws java.io.InvalidClassException
  192. {
  193. Class clazz = proxy.getClass();
  194. MethodHandler methodHandler = null;
  195. if (proxy instanceof ProxyObject)
  196. methodHandler = ((ProxyObject)proxy).getHandler();
  197. else if (proxy instanceof Proxy)
  198. methodHandler = ProxyFactory.getHandler((Proxy)proxy);
  199. return new SerializedProxy(clazz, ProxyFactory.getFilterSignature(clazz), methodHandler);
  200. }
  201. }