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