1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 1999 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowlegement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowlegement may appear in the software itself,
  24. * if and wherever such third-party acknowlegements normally appear.
  25. *
  26. * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Group.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. *
  54. */
  55. package org.apache.commons.el;
  56. import java.util.List;
  57. import java.util.Map;
  58. import java.util.Iterator;
  59. import java.lang.reflect.*;
  60. import javax.servlet.jsp.el.ELException;
  61. import javax.servlet.jsp.el.VariableResolver;
  62. import javax.servlet.jsp.el.FunctionMapper;
  63. /**
  64. *
  65. * <p>Represents a function call.</p>
  66. *
  67. * @author Shawn Bayern (in the style of Nathan's other classes)
  68. **/
  69. public class FunctionInvocation
  70. extends Expression
  71. {
  72. //-------------------------------------
  73. // Properties
  74. //-------------------------------------
  75. // property index
  76. private String functionName;
  77. private List argumentList;
  78. public String getFunctionName() { return functionName; }
  79. public void setFunctionName(String f) { functionName = f; }
  80. public List getArgumentList() { return argumentList; }
  81. public void setArgumentList(List l) { argumentList = l; }
  82. //-------------------------------------
  83. /**
  84. * Constructor
  85. **/
  86. public FunctionInvocation (String functionName, List argumentList)
  87. {
  88. this.functionName = functionName;
  89. this.argumentList = argumentList;
  90. }
  91. //-------------------------------------
  92. // Expression methods
  93. //-------------------------------------
  94. /**
  95. * Returns the expression in the expression language syntax
  96. **/
  97. public String getExpressionString ()
  98. {
  99. StringBuffer b = new StringBuffer();
  100. b.append(functionName);
  101. b.append("(");
  102. Iterator i = argumentList.iterator();
  103. while (i.hasNext()) {
  104. b.append(((Expression) i.next()).getExpressionString());
  105. if (i.hasNext())
  106. b.append(", ");
  107. }
  108. b.append(")");
  109. return b.toString();
  110. }
  111. //-------------------------------------
  112. /**
  113. *
  114. * Evaluates by looking up the name in the VariableResolver
  115. **/
  116. public Object evaluate (VariableResolver pResolver,
  117. FunctionMapper functions,
  118. Logger pLogger)
  119. throws ELException
  120. {
  121. // if the Map is null, then the function is invalid
  122. if (functions == null)
  123. pLogger.logError(Constants.UNKNOWN_FUNCTION, functionName);
  124. // normalize function name
  125. String prefix = null;
  126. String localName = null;
  127. int index = functionName.indexOf( ':' );
  128. if (index == -1) {
  129. prefix = "";
  130. localName = functionName;
  131. } else {
  132. prefix = functionName.substring( 0, index );
  133. localName = functionName.substring( index + 1 );
  134. }
  135. // ensure that the function's name is mapped
  136. Method target = (Method) functions.resolveFunction(prefix, localName);
  137. if (target == null)
  138. pLogger.logError(Constants.UNKNOWN_FUNCTION, functionName);
  139. // ensure that the number of arguments matches the number of parameters
  140. Class[] params = target.getParameterTypes();
  141. if (params.length != argumentList.size())
  142. pLogger.logError(Constants.INAPPROPRIATE_FUNCTION_ARG_COUNT,
  143. functionName, new Integer(params.length),
  144. new Integer(argumentList.size()));
  145. // now, walk through each parameter, evaluating and casting its argument
  146. Object[] arguments = new Object[argumentList.size()];
  147. for (int i = 0; i < params.length; i++) {
  148. // evaluate
  149. arguments[i] = ((Expression) argumentList.get(i)).evaluate(pResolver,
  150. functions,
  151. pLogger);
  152. // coerce
  153. arguments[i] = Coercions.coerce(arguments[i], params[i], pLogger);
  154. }
  155. // finally, invoke the target method, which we know to be static
  156. try {
  157. return (target.invoke(null, arguments));
  158. } catch (InvocationTargetException ex) {
  159. pLogger.logError(Constants.FUNCTION_INVOCATION_ERROR,
  160. ex.getTargetException(),
  161. functionName);
  162. return null;
  163. } catch (Exception ex) {
  164. pLogger.logError(Constants.FUNCTION_INVOCATION_ERROR, ex, functionName);
  165. return null;
  166. }
  167. }
  168. //-------------------------------------
  169. }