1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.el.convert;
20
21 import java.util.logging.Level;
22 import java.util.logging.Logger;
23
24 import javax.el.ELContext;
25 import javax.el.ELException;
26 import javax.el.PropertyNotFoundException;
27 import javax.el.PropertyNotWritableException;
28 import javax.el.ValueExpression;
29 import javax.faces.component.StateHolder;
30 import javax.faces.context.FacesContext;
31 import javax.faces.el.EvaluationException;
32 import javax.faces.el.ValueBinding;
33
34 import org.apache.myfaces.shared.util.ClassUtils;
35
36
37
38
39
40
41
42
43
44
45
46
47 @SuppressWarnings("deprecation")
48 public class ValueBindingToValueExpression extends ValueExpression implements StateHolder
49 {
50 private static final long serialVersionUID = 8071429285360496554L;
51
52 private static final Logger log = Logger.getLogger(ValueBindingToValueExpression.class.getName());
53
54 private ValueBinding _valueBinding;
55
56 private boolean _transient;
57
58
59
60
61 public ValueBindingToValueExpression()
62 {
63 }
64
65 private ValueBinding getNotNullValueBinding()
66 {
67 if (_valueBinding == null)
68 {
69 throw new IllegalStateException("value binding is null");
70 }
71 return _valueBinding;
72 }
73
74
75 public ValueBindingToValueExpression(ValueBinding valueBinding)
76 {
77 if (valueBinding == null)
78 {
79 throw new IllegalArgumentException("value binding must not be null");
80 }
81 this._valueBinding = valueBinding;
82 }
83
84 public ValueBinding getValueBinding()
85 {
86 return _valueBinding;
87 }
88
89 @Override
90 public boolean isReadOnly(final ELContext context) throws NullPointerException, PropertyNotFoundException,
91 ELException
92 {
93 return invoke(new Invoker<Boolean>()
94 {
95 public Boolean invoke()
96 {
97 return getNotNullValueBinding().isReadOnly(getFacesContext(context));
98 }
99 });
100 }
101
102 @Override
103 public Object getValue(final ELContext context) throws NullPointerException, PropertyNotFoundException, ELException
104 {
105 return invoke(new Invoker<Object>()
106 {
107 public Object invoke()
108 {
109 return getNotNullValueBinding().getValue(getFacesContext(context));
110 }
111 });
112 }
113
114 @Override
115 public Class<?> getType(final ELContext context) throws NullPointerException, PropertyNotFoundException,
116 ELException
117 {
118 return invoke(new Invoker<Class<?>>()
119 {
120 public Class<?> invoke()
121 {
122 return getNotNullValueBinding().getType(getFacesContext(context));
123 }
124 });
125 }
126
127 @Override
128 public void setValue(final ELContext context, final Object value) throws NullPointerException,
129 PropertyNotFoundException, PropertyNotWritableException, ELException
130 {
131 invoke(new Invoker<Object>()
132 {
133 public Object invoke()
134 {
135 getNotNullValueBinding().setValue(getFacesContext(context), value);
136 return null;
137 }
138 });
139 }
140
141 @Override
142 public int hashCode()
143 {
144 int result = 1;
145 result = 31 * result + (_transient ? 1231 : 1237);
146 result = 31 * result + ((_valueBinding == null) ? 0 : _valueBinding.hashCode());
147 return result;
148 }
149
150 @Override
151 public boolean equals(Object obj)
152 {
153 if (this == obj)
154 {
155 return true;
156 }
157 if (obj == null)
158 {
159 return false;
160 }
161 if (getClass() != obj.getClass())
162 {
163 return false;
164 }
165 final ValueBindingToValueExpression other = (ValueBindingToValueExpression) obj;
166 if (_transient != other._transient)
167 {
168 return false;
169 }
170 if (_valueBinding == null)
171 {
172 if (other._valueBinding != null)
173 {
174 return false;
175 }
176 }
177 else if (!_valueBinding.equals(other._valueBinding))
178 {
179 return false;
180 }
181 return true;
182 }
183
184 @Override
185 public boolean isLiteralText()
186 {
187 return false;
188 }
189
190 @Override
191 public String getExpressionString()
192 {
193 return getNotNullValueBinding().getExpressionString();
194 }
195
196 @Override
197 public Class<?> getExpectedType()
198 {
199 if (_valueBinding != null)
200 {
201 try
202 {
203 Object value = getNotNullValueBinding().getValue(FacesContext.getCurrentInstance());
204 if (value != null)
205 {
206 return value.getClass();
207 }
208 }
209 catch (Throwable e)
210 {
211 log.log(Level.WARNING, "Could not determine expected type for '"
212 + _valueBinding.getExpressionString() + "': "
213 + e.getMessage(), e);
214 }
215 }
216 return null;
217 }
218
219 public void restoreState(FacesContext context, Object state)
220 {
221 if (state instanceof ValueBinding)
222 {
223 _valueBinding = (ValueBinding) state;
224 }
225 else if (state != null)
226 {
227 Object[] stateArray = (Object[]) state;
228 _valueBinding = (ValueBinding) ClassUtils.newInstance((String) stateArray[0], ValueBinding.class);
229 ((StateHolder) _valueBinding).restoreState(context, stateArray[1]);
230 }
231 }
232
233 public Object saveState(FacesContext context)
234 {
235 if (!_transient)
236 {
237 if (_valueBinding instanceof StateHolder)
238 {
239 Object[] state = new Object[2];
240 state[0] = _valueBinding.getClass().getName();
241 state[1] = ((StateHolder) _valueBinding).saveState(context);
242 return state;
243 }
244 return _valueBinding;
245 }
246 return null;
247 }
248
249 public void setTransient(boolean newTransientValue)
250 {
251 _transient = newTransientValue;
252 }
253
254 public boolean isTransient()
255 {
256 return _transient;
257 }
258
259 private FacesContext getFacesContext(ELContext context)
260 {
261 if (context == null)
262 {
263 throw new IllegalArgumentException("el context must not be null.");
264 }
265 FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
266 if (facesContext == null)
267 {
268 throw new IllegalStateException("faces context not available in el context.");
269 }
270 return facesContext;
271 }
272
273 private <T> T invoke(Invoker<T> invoker)
274 {
275 try
276 {
277 return invoker.invoke();
278 }
279 catch (javax.faces.el.PropertyNotFoundException e)
280 {
281 throw new PropertyNotFoundException(e.getMessage(), e);
282 }
283 catch (EvaluationException e)
284 {
285 throw new ELException(e.getMessage(), e);
286 }
287 }
288
289 private interface Invoker<T>
290 {
291 T invoke();
292 }
293 }