1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.el;
18
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.ArrayList;
24
25 import javax.servlet.jsp.el.ELException;
26 import javax.servlet.jsp.el.FunctionMapper;
27 import javax.servlet.jsp.el.VariableResolver;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32
33
34
35
36
37
38
39 public class FunctionInvocation
40 extends Expression
41 {
42
43
44
45 private static Log log = LogFactory.getLog(FunctionInvocation.class);
46
47
48
49
50
51
52 private String functionName;
53 private List argumentList;
54 public String getFunctionName() { return functionName; }
55 public void setFunctionName(String f) { functionName = f; }
56 public List getArgumentList() { return argumentList; }
57 public void setArgumentList(List l) { argumentList = l; }
58
59
60
61
62
63 public FunctionInvocation (String functionName, List argumentList)
64 {
65 this.functionName = functionName;
66 this.argumentList = argumentList;
67 }
68
69
70
71
72
73
74
75 public String getExpressionString ()
76 {
77 StringBuffer b = new StringBuffer();
78 b.append(functionName);
79 b.append("(");
80 Iterator i = argumentList.iterator();
81 while (i.hasNext()) {
82 b.append(((Expression) i.next()).getExpressionString());
83 if (i.hasNext())
84 b.append(", ");
85 }
86 b.append(")");
87 return b.toString();
88 }
89
90
91
92
93
94
95
96 public Object evaluate (VariableResolver pResolver,
97 FunctionMapper functions)
98 throws ELException
99 {
100
101 Method target = resolveFunction(functions);
102 if (target == null) {
103 if (log.isErrorEnabled()) {
104 String message = MessageUtil.getMessageWithArgs(
105 Constants.UNKNOWN_FUNCTION, functionName);
106 log.error(message);
107 throw new ELException(message);
108 }
109 }
110
111
112 Class[] params = target.getParameterTypes();
113 if (params.length != argumentList.size()) {
114 if (log.isErrorEnabled()) {
115 String message = MessageUtil.getMessageWithArgs(
116 Constants.INAPPROPRIATE_FUNCTION_ARG_COUNT,
117 functionName, new Integer(params.length),
118 new Integer(argumentList.size()));
119 log.error(message);
120 throw new ELException(message);
121 }
122 }
123
124
125 Object[] arguments = new Object[argumentList.size()];
126 for (int i = 0; i < params.length; i++) {
127
128 arguments[i] = ((Expression) argumentList.get(i)).evaluate(pResolver,
129 functions);
130
131 arguments[i] = Coercions.coerce(arguments[i], params[i]);
132 }
133
134
135 try {
136 return (target.invoke(null, arguments));
137 } catch (InvocationTargetException ex) {
138 if (log.isErrorEnabled()) {
139 String message = MessageUtil.getMessageWithArgs(
140 Constants.FUNCTION_INVOCATION_ERROR,
141 functionName);
142 Throwable t = ex.getTargetException();
143 log.error(message, t);
144 throw new ELException(message, t);
145 }
146 return null;
147 } catch (Throwable t) {
148 if (log.isErrorEnabled()) {
149 String message = MessageUtil.getMessageWithArgs(
150 Constants.FUNCTION_INVOCATION_ERROR,
151 functionName);
152 log.error(message, t);
153 throw new ELException(message, t);
154 }
155 return null;
156 }
157 }
158
159
160
161
162
163
164
165
166 protected Method resolveFunction(FunctionMapper functions) throws ELException {
167
168 if (functions == null) {
169 return null;
170 }
171
172
173 String prefix = null;
174 String localName = null;
175 int index = functionName.indexOf( ':' );
176 if (index == -1) {
177 prefix = "";
178 localName = functionName;
179 } else {
180 prefix = functionName.substring( 0, index );
181 localName = functionName.substring( index + 1 );
182 }
183
184
185 Method target = (Method) functions.resolveFunction(prefix, localName);
186
187 return target;
188 }
189
190 public Expression bindFunctions(final FunctionMapper functions)
191 throws ELException {
192 final List argList = new ArrayList(argumentList.size());
193 for (Iterator argIter = argumentList.iterator(); argIter.hasNext();) {
194 Expression arg = (Expression) argIter.next();
195 argList.add(arg.bindFunctions(functions));
196 }
197 return new BoundFunctionInvocation(
198 resolveFunction(functions),
199 functionName,
200 argList);
201 }
202
203
204 }