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.

RuntimeSupport.java 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Javassist, a Java-bytecode translator toolkit.
  3. * Copyright (C) 1999-2005 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.util.proxy;
  16. import java.lang.reflect.Method;
  17. /**
  18. * Runtime support routines that the classes generated by ProxyFactory use.
  19. *
  20. * @see ProxyFactory
  21. */
  22. public class RuntimeSupport {
  23. /**
  24. * Finds a method with the given name and descriptor.
  25. * It searches only the class of self.
  26. *
  27. * @throws RuntimeException if the method is not found.
  28. */
  29. public static Method findMethod(Object self, String name, String desc) {
  30. Method m = findMethod2(self.getClass(), name, desc);
  31. if (m == null)
  32. error(self, name, desc);
  33. return m;
  34. }
  35. /**
  36. * Finds a method that has the given name and descriptor and is declared
  37. * in the super class.
  38. *
  39. * @throws RuntimeException if the method is not found.
  40. */
  41. public static Method findSuperMethod(Object self, String name, String desc) {
  42. Class clazz = self.getClass();
  43. Method m = findSuperMethod2(clazz.getSuperclass(), name, desc);
  44. if (m == null)
  45. m = searchInterfaces(clazz, name, desc);
  46. if (m == null)
  47. error(self, name, desc);
  48. return m;
  49. }
  50. private static void error(Object self, String name, String desc) {
  51. throw new RuntimeException("not found " + name + ":" + desc
  52. + " in " + self.getClass().getName());
  53. }
  54. private static Method findSuperMethod2(Class clazz, String name, String desc) {
  55. Method m = findMethod2(clazz, name, desc);
  56. if (m != null)
  57. return m;
  58. Class superClass = clazz.getSuperclass();
  59. if (superClass != null) {
  60. m = findSuperMethod2(superClass, name, desc);
  61. if (m != null)
  62. return m;
  63. }
  64. return searchInterfaces(clazz, name, desc);
  65. }
  66. private static Method searchInterfaces(Class clazz, String name, String desc) {
  67. Method m = null;
  68. Class[] interfaces = clazz.getInterfaces();
  69. for (int i = 0; i < interfaces.length; i++) {
  70. m = findSuperMethod2(interfaces[i], name, desc);
  71. if (m != null)
  72. return m;
  73. }
  74. return m;
  75. }
  76. private static Method findMethod2(Class clazz, String name, String desc) {
  77. Method[] methods = clazz.getDeclaredMethods();
  78. int n = methods.length;
  79. for (int i = 0; i < n; i++)
  80. if (methods[i].getName().equals(name)
  81. && makeDescriptor(methods[i]).equals(desc))
  82. return methods[i];
  83. return null;
  84. }
  85. /**
  86. * Makes a descriptor for a given method.
  87. */
  88. public static String makeDescriptor(Method m) {
  89. Class[] params = m.getParameterTypes();
  90. return makeDescriptor(params, m.getReturnType());
  91. }
  92. /**
  93. * Makes a descriptor for a given method.
  94. *
  95. * @param params parameter types.
  96. * @param retType return type.
  97. */
  98. public static String makeDescriptor(Class[] params, Class retType) {
  99. StringBuffer sbuf = new StringBuffer();
  100. sbuf.append('(');
  101. for (int i = 0; i < params.length; i++)
  102. makeDesc(sbuf, params[i]);
  103. sbuf.append(')');
  104. makeDesc(sbuf, retType);
  105. return sbuf.toString();
  106. }
  107. private static void makeDesc(StringBuffer sbuf, Class type) {
  108. if (type.isArray()) {
  109. sbuf.append('[');
  110. makeDesc(sbuf, type.getComponentType());
  111. }
  112. else if (type.isPrimitive()) {
  113. if (type == Void.TYPE)
  114. sbuf.append('V');
  115. else if (type == Integer.TYPE)
  116. sbuf.append('I');
  117. else if (type == Byte.TYPE)
  118. sbuf.append('B');
  119. else if (type == Long.TYPE)
  120. sbuf.append('J');
  121. else if (type == Double.TYPE)
  122. sbuf.append('D');
  123. else if (type == Float.TYPE)
  124. sbuf.append('F');
  125. else if (type == Character.TYPE)
  126. sbuf.append('C');
  127. else if (type == Short.TYPE)
  128. sbuf.append('S');
  129. else if (type == Boolean.TYPE)
  130. sbuf.append('Z');
  131. else
  132. throw new RuntimeException("bad type: " + type.getName());
  133. }
  134. else
  135. sbuf.append('L').append(type.getName().replace('.', '/'))
  136. .append(';');
  137. }
  138. }