1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.component;
20
21 import javax.el.ELContext;
22 import javax.el.ELException;
23 import javax.el.MethodExpression;
24 import javax.el.MethodInfo;
25 import javax.el.MethodNotFoundException;
26 import javax.el.PropertyNotFoundException;
27 import javax.faces.component.StateHolder;
28 import javax.faces.context.FacesContext;
29 import javax.faces.el.EvaluationException;
30 import javax.faces.el.MethodBinding;
31
32 import org.apache.myfaces.shared_tomahawk.util.ClassUtils;
33
34
35
36
37
38
39
40
41
42
43
44 @SuppressWarnings("deprecation")
45 public class MethodBindingToMethodExpression extends MethodExpression implements StateHolder
46 {
47 private static final Class[] EXPECTED_TYPES = new Class[] { MethodBinding.class, StateHolder.class };
48
49 private MethodBinding methodBinding;
50
51 private boolean _transientFlag;
52
53 private transient MethodInfo methodInfo;
54
55
56
57
58 public MethodBindingToMethodExpression()
59 {
60 }
61
62
63 public MethodBindingToMethodExpression(MethodBinding methodBinding)
64 {
65 checkNullArgument(methodBinding, "methodBinding");
66 this.methodBinding = methodBinding;
67 }
68
69
70
71
72 public MethodBinding getMethodBinding()
73 {
74 return methodBinding;
75 }
76
77 void setMethodBinding(MethodBinding methodBinding)
78 {
79 this.methodBinding = methodBinding;
80 }
81
82
83
84
85
86
87
88 public MethodInfo getMethodInfo(ELContext context) throws PropertyNotFoundException, MethodNotFoundException,
89 ELException
90 {
91 checkNullArgument(context, "elcontext");
92 checkNullState(methodBinding, "methodBinding");
93
94 if (methodInfo == null)
95 {
96 final FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
97 if (facesContext != null)
98 {
99 methodInfo = invoke(new Invoker<MethodInfo>()
100 {
101 public MethodInfo invoke()
102 {
103 return new MethodInfo(null, methodBinding.getType(facesContext), null);
104 }
105 });
106 }
107 }
108 return methodInfo;
109 }
110
111 public Object invoke(ELContext context, final Object[] params) throws PropertyNotFoundException,
112 MethodNotFoundException, ELException
113 {
114 checkNullArgument(context, "elcontext");
115 checkNullState(methodBinding, "methodBinding");
116 final FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
117 if (facesContext != null)
118 {
119 return invoke(new Invoker<Object>()
120 {
121 public Object invoke()
122 {
123 return methodBinding.invoke(facesContext, params);
124 }
125 });
126 }
127 return null;
128 }
129
130 public boolean isLiteralText()
131 {
132 if (methodBinding == null)
133 throw new IllegalStateException("methodBinding is null");
134 String expr = methodBinding.getExpressionString();
135 return !(expr.startsWith("#{") && expr.endsWith("}"));
136 }
137
138 public String getExpressionString()
139 {
140 return methodBinding.getExpressionString();
141 }
142
143 public Object saveState(FacesContext context)
144 {
145 if (!isTransient())
146 {
147 if (methodBinding instanceof StateHolder)
148 {
149 Object[] state = new Object[2];
150 state[0] = methodBinding.getClass().getName();
151 state[1] = ((StateHolder) methodBinding).saveState(context);
152 return state;
153 }
154 else
155 {
156 return methodBinding;
157 }
158 }
159 return null;
160 }
161
162 public void restoreState(FacesContext context, Object state)
163 {
164 if (state instanceof MethodBinding)
165 {
166 methodBinding = (MethodBinding) state;
167 methodInfo = null;
168 }
169 else if (state != null)
170 {
171 Object[] values = (Object[]) state;
172 methodBinding = (MethodBinding) ClassUtils.newInstance(values[0].toString(), EXPECTED_TYPES);
173 ((StateHolder) methodBinding).restoreState(context, values[1]);
174 methodInfo = null;
175 }
176 }
177
178 public void setTransient(boolean transientFlag)
179 {
180 _transientFlag = transientFlag;
181 }
182
183 public boolean isTransient()
184 {
185 return _transientFlag;
186 }
187
188 @Override
189 public int hashCode()
190 {
191 final int PRIME = 31;
192 int result = 1;
193 result = PRIME * result + ((methodBinding == null) ? 0 : methodBinding.hashCode());
194 return result;
195 }
196
197 @Override
198 public boolean equals(Object obj)
199 {
200 if (this == obj)
201 return true;
202 if (obj == null)
203 return false;
204 if (getClass() != obj.getClass())
205 return false;
206 final MethodBindingToMethodExpression other = (MethodBindingToMethodExpression) obj;
207 if (methodBinding == null)
208 {
209 if (other.methodBinding != null)
210 return false;
211 }
212 else if (!methodBinding.equals(other.methodBinding))
213 return false;
214 return true;
215 }
216
217 private void checkNullState(Object notNullInstance, String instanceName)
218 {
219 if (notNullInstance == null)
220 throw new IllegalStateException(instanceName + " is null");
221 }
222
223 private void checkNullArgument(Object notNullInstance, String instanceName)
224 {
225 if (notNullInstance == null)
226 throw new IllegalArgumentException(instanceName + " is null");
227 }
228
229 private <T> T invoke(Invoker<T> invoker)
230 {
231 try
232 {
233 return invoker.invoke();
234 }
235 catch (javax.faces.el.MethodNotFoundException e)
236 {
237 throw new MethodNotFoundException(e.getMessage(), e);
238 }
239 catch (EvaluationException e)
240 {
241 throw new ELException(e.getMessage(), e);
242 }
243 }
244
245 private interface Invoker<T>
246 {
247 T invoke();
248 }
249 }