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