/modules/kernel/src/com/caucho/el/StaticMethodExpr.java

https://github.com/GEFFROY/Quercus · Java · 265 lines · 163 code · 40 blank · 62 comment · 18 complexity · 561477c9a3238aed0d9f425a1d62be09 MD5 · raw file

  1. /*
  2. * Copyright (c) 1998-2010 Caucho Technology -- all rights reserved
  3. *
  4. * This file is part of Resin(R) Open Source
  5. *
  6. * Each copy or derived work must preserve the copyright notice and this
  7. * notice unmodified.
  8. *
  9. * Resin Open Source is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * Resin Open Source is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
  17. * of NON-INFRINGEMENT. See the GNU General Public License for more
  18. * details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with Resin Open Source; if not, write to the
  22. *
  23. * Free Software Foundation, Inc.
  24. * 59 Temple Place, Suite 330
  25. * Boston, MA 02111-1307 USA
  26. *
  27. * @author Scott Ferguson
  28. */
  29. package com.caucho.el;
  30. import java.io.IOException;
  31. import java.io.Serializable;
  32. import java.lang.reflect.Method;
  33. import java.lang.reflect.InvocationTargetException;
  34. import javax.el.ELContext;
  35. import javax.el.ELException;
  36. import com.caucho.config.types.Signature;
  37. import com.caucho.vfs.WriteStream;
  38. /**
  39. * Represents a method call. The expr will evaluate to a method.
  40. */
  41. public class StaticMethodExpr extends Expr {
  42. private static final Object []NULL_ARGS = new Object[0];
  43. private Method _method;
  44. private Marshall []_marshall;
  45. private boolean _isVoid;
  46. /**
  47. * Creates a new method expression.
  48. *
  49. * @param method - the target method
  50. */
  51. public StaticMethodExpr(Method method)
  52. {
  53. _method = method;
  54. initMethod();
  55. }
  56. /**
  57. * Creates a new static method.
  58. *
  59. * @param signature signature
  60. */
  61. public StaticMethodExpr(String signature)
  62. {
  63. try {
  64. Signature sig = new Signature();
  65. sig.addText(signature);
  66. sig.init();
  67. _method = sig.getMethod();
  68. if (_method == null)
  69. throw new RuntimeException(L.l("'{0}' is an unknown method",
  70. sig));
  71. } catch (RuntimeException e) {
  72. throw e;
  73. } catch (Exception e) {
  74. throw new RuntimeException(e);
  75. // log.log(Level.FINE, e.toString(), e);
  76. }
  77. initMethod();
  78. }
  79. /**
  80. * Initialize the marshall arguments.
  81. */
  82. private void initMethod()
  83. {
  84. Class []param = _method.getParameterTypes();
  85. _marshall = new Marshall[param.length];
  86. for (int i = 0; i < _marshall.length; i++) {
  87. _marshall[i] = Marshall.create(param[i]);
  88. }
  89. _isVoid = void.class.equals(_method.getReturnType());
  90. }
  91. /**
  92. * Evaluate the expression as an object.
  93. *
  94. * @param env the variable environment
  95. */
  96. @Override
  97. public Object getValue(ELContext env)
  98. throws ELException
  99. {
  100. return _method;
  101. }
  102. /**
  103. * Evaluate the expression as an object.
  104. *
  105. * @param env the variable environment
  106. */
  107. public Object evalMethod(Expr []args,
  108. ELContext env)
  109. throws ELException
  110. {
  111. if (_marshall.length != args.length) {
  112. // jsp/18i8
  113. throw new ELParseException(L.l("Arguments to '{0}' do not match expected length {1}.", _method.getName(), _marshall.length));
  114. }
  115. try {
  116. Object []objs;
  117. if (args.length > 0) {
  118. objs = new Object[args.length];
  119. for (int i = 0; i < _marshall.length; i++)
  120. objs[i] = _marshall[i].marshall(args[i], env);
  121. }
  122. else
  123. objs = NULL_ARGS;
  124. if (! _isVoid)
  125. return _method.invoke(null, objs);
  126. else {
  127. _method.invoke(null, objs);
  128. return null;
  129. }
  130. } catch (ELException e) {
  131. throw e;
  132. } catch (InvocationTargetException e) {
  133. throw new ELException(e.getCause());
  134. } catch (Exception e) {
  135. throw new ELException(e);
  136. }
  137. }
  138. /**
  139. * Prints the code to create an LongLiteral.
  140. */
  141. public void printCreate(WriteStream os)
  142. throws IOException
  143. {
  144. os.print("new com.caucho.el.StaticMethodExpr(\"");
  145. printType(os, _method.getReturnType());
  146. os.print(" ");
  147. os.print(_method.getDeclaringClass().getName());
  148. os.print(".");
  149. os.print(_method.getName());
  150. os.print("(");
  151. Class<?> []parameterTypes = _method.getParameterTypes();
  152. for (int i = 0; i < parameterTypes.length; i++) {
  153. if (i != 0)
  154. os.print(", ");
  155. printType(os, parameterTypes[i]);
  156. }
  157. os.print(")");
  158. os.print("\")");
  159. }
  160. private void printType(WriteStream os, Class<?> cl)
  161. throws IOException
  162. {
  163. if (cl.isArray()) {
  164. printType(os, cl.getComponentType());
  165. os.print("[]");
  166. }
  167. else
  168. os.print(cl.getName());
  169. }
  170. private Object writeReplace()
  171. {
  172. StringBuilder sig = new StringBuilder();
  173. addType(sig, _method.getReturnType());
  174. sig.append(" ");
  175. sig.append(_method.getDeclaringClass().getName());
  176. sig.append(".");
  177. sig.append(_method.getName());
  178. sig.append("(");
  179. Class<?> []param = _method.getParameterTypes();
  180. for (int i = 0; i < param.length; i++) {
  181. if (i != 0)
  182. sig.append(",");
  183. addType(sig, param[i]);
  184. }
  185. sig.append(")");
  186. return new Handle(sig.toString());
  187. }
  188. private void addType(StringBuilder sb, Class<?> cl)
  189. {
  190. if (cl.isArray()) {
  191. addType(sb, cl.getComponentType());
  192. sb.append("[]");
  193. }
  194. else
  195. sb.append(cl.getName());
  196. }
  197. /**
  198. * Returns true for equal strings.
  199. */
  200. public boolean equals(Object o)
  201. {
  202. if (! (o instanceof StaticMethodExpr))
  203. return false;
  204. StaticMethodExpr expr = (StaticMethodExpr) o;
  205. return _method.equals(expr._method);
  206. }
  207. public String toString()
  208. {
  209. return _method.getName();
  210. }
  211. static class Handle implements Serializable {
  212. private String _signature;
  213. private Handle()
  214. {
  215. }
  216. private Handle(String signature)
  217. {
  218. _signature = signature;
  219. }
  220. public Object readResolve()
  221. {
  222. return new StaticMethodExpr(_signature);
  223. }
  224. }
  225. }