1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.el;
20
21 import org.apache.myfaces.el.ValueBindingImpl.NotVariableReferenceException;
22
23 import org.apache.commons.beanutils.MethodUtils;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import javax.faces.application.Application;
28 import javax.faces.component.StateHolder;
29 import javax.faces.context.FacesContext;
30 import javax.faces.el.*;
31 import javax.faces.event.AbortProcessingException;
32 import javax.faces.validator.ValidatorException;
33 import javax.servlet.jsp.el.ELException;
34 import java.lang.reflect.InvocationTargetException;
35 import java.lang.reflect.Method;
36
37
38
39
40
41
42 public class MethodBindingImpl extends MethodBinding
43 implements StateHolder
44 {
45 static final Log log = LogFactory.getLog(MethodBindingImpl.class);
46
47
48
49 ValueBindingImpl _valueBinding;
50 Class[] _argClasses;
51
52
53
54 public MethodBindingImpl(Application application, String reference,
55 Class[] argClasses)
56 {
57
58
59
60
61 _valueBinding = new ValueBindingImpl(application, reference.trim());
62 _argClasses = argClasses;
63 }
64
65
66
67 public String getExpressionString()
68 {
69 return _valueBinding._expressionString;
70 }
71
72 public Class getType(FacesContext facesContext)
73 {
74 if (facesContext == null) {
75 throw new NullPointerException("facesContext");
76 }
77 try
78 {
79 Object[] baseAndProperty = resolveToBaseAndProperty(facesContext);
80 Object base = baseAndProperty[0];
81 Object property = baseAndProperty[1];
82
83 Class returnType = base.getClass().getMethod(property.toString(), _argClasses).getReturnType();
84
85 if (returnType.getName().equals("void")) {
86
87
88 return Void.class;
89 }
90 return returnType;
91 }
92 catch (ReferenceSyntaxException e)
93 {
94 throw e;
95 }
96 catch (IndexOutOfBoundsException e)
97 {
98
99 throw new PropertyNotFoundException("Expression: "
100 + getExpressionString(), e);
101 }
102 catch (Exception e)
103 {
104 throw new EvaluationException("Cannot get type for expression "
105 + getExpressionString(), e);
106 }
107 }
108
109 public Object invoke(FacesContext facesContext, Object[] args)
110 throws EvaluationException, MethodNotFoundException
111 {
112 if (facesContext == null) {
113 throw new NullPointerException("facesContext");
114 }
115 try
116 {
117 Object[] baseAndProperty = resolveToBaseAndProperty(facesContext);
118 Object base = baseAndProperty[0];
119 Object property = baseAndProperty[1];
120
121 Method m = base.getClass().getMethod(property.toString(), _argClasses);
122
123
124
125 m = MethodUtils.getAccessibleMethod(m);
126 if (m == null)
127 {
128 throw new MethodNotFoundException(
129 getExpressionString() + " (not accessible!)");
130 }
131
132 return m.invoke(base, args);
133 }
134 catch (ReferenceSyntaxException e)
135 {
136 throw e;
137 }
138 catch (IndexOutOfBoundsException e)
139 {
140
141 throw new PropertyNotFoundException("Expression: "
142 + getExpressionString(), e);
143 }
144 catch (InvocationTargetException e)
145 {
146 Throwable cause = e.getCause();
147 if (cause != null)
148 {
149 if (cause instanceof ValidatorException ||
150 cause instanceof AbortProcessingException)
151 {
152 throw new EvaluationException(cause);
153 }
154 else
155 {
156 throw new EvaluationException("Exception while invoking expression "
157 + getExpressionString(), cause);
158 }
159 }
160 else
161 {
162 throw new EvaluationException("Exception while invoking expression "
163 + getExpressionString(), e);
164 }
165 }
166 catch (Exception e)
167 {
168 throw new EvaluationException("Exception while invoking expression "
169 + getExpressionString(), e);
170 }
171 }
172
173 protected Object[] resolveToBaseAndProperty(FacesContext facesContext)
174 throws ELException
175 {
176 if (facesContext == null)
177 {
178 throw new NullPointerException("facesContext");
179 }
180
181 try
182 {
183 Object base = _valueBinding.resolveToBaseAndProperty(facesContext);
184
185 if (!(base instanceof Object[]))
186 {
187 String errorMessage = "Expression not a valid method binding: "
188 + getExpressionString();
189 throw new ReferenceSyntaxException(errorMessage);
190 }
191
192 return (Object[]) base;
193 }
194 catch (NotVariableReferenceException e)
195 {
196 throw new ReferenceSyntaxException("Expression: "
197 + getExpressionString(), e);
198 }
199 }
200
201 public String toString()
202 {
203 return _valueBinding.toString();
204 }
205
206
207
208 private boolean _transient = false;
209
210
211
212
213
214 public MethodBindingImpl()
215 {
216 _valueBinding = null;
217 _argClasses = null;
218 }
219
220 public Object saveState(FacesContext facescontext)
221 {
222 return new Object[] { _valueBinding.saveState(facescontext),
223 _argClasses};
224 }
225
226 public void restoreState(FacesContext facescontext, Object obj)
227 {
228 Object[] ar = (Object[]) obj;
229 _valueBinding = new ValueBindingImpl();
230 _valueBinding.restoreState(facescontext, ar[0]);
231 _argClasses = (Class[]) ar[1];
232 }
233
234 public boolean isTransient()
235 {
236 return _transient;
237 }
238
239 public void setTransient(boolean flag)
240 {
241 _transient = flag;
242 }
243
244 }