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 @SuppressWarnings("deprecation")
47 public class ValueBindingToValueExpression extends ValueExpression implements StateHolder
48 {
49 private static final long serialVersionUID = 8071429285360496554L;
50
51
52 private static final Logger logger = 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 return true;
155 if (obj == null)
156 return false;
157 if (getClass() != obj.getClass())
158 return false;
159 final ValueBindingToValueExpression other = (ValueBindingToValueExpression) obj;
160 if (_transient != other._transient)
161 return false;
162 if (_valueBinding == null)
163 {
164 if (other._valueBinding != null)
165 return false;
166 }
167 else if (!_valueBinding.equals(other._valueBinding))
168 return false;
169 return true;
170 }
171
172 @Override
173 public boolean isLiteralText()
174 {
175 return false;
176 }
177
178 @Override
179 public String getExpressionString()
180 {
181 return getNotNullValueBinding().getExpressionString();
182 }
183
184 @Override
185 public Class<?> getExpectedType()
186 {
187 if (_valueBinding != null)
188 {
189 try
190 {
191 Object value = getNotNullValueBinding().getValue(FacesContext.getCurrentInstance());
192 if (value != null)
193 {
194 return value.getClass();
195 }
196 }
197 catch (Throwable e)
198 {
199 logger.log(Level.WARNING, "Could not determine expected type for '" + _valueBinding.getExpressionString() + "': "
200 + e.getMessage(), e);
201 }
202 }
203 return null;
204 }
205
206 public void restoreState(FacesContext context, Object state)
207 {
208 if (state instanceof ValueBinding)
209 {
210 _valueBinding = (ValueBinding) state;
211 }
212 else if (state != null)
213 {
214 Object[] stateArray = (Object[]) state;
215 _valueBinding = (ValueBinding) ClassUtils.newInstance((String) stateArray[0], ValueBinding.class);
216 ((StateHolder) _valueBinding).restoreState(context, stateArray[1]);
217 }
218 }
219
220 public Object saveState(FacesContext context)
221 {
222 if (!_transient)
223 {
224 if (_valueBinding instanceof StateHolder)
225 {
226 Object[] state = new Object[2];
227 state[0] = _valueBinding.getClass().getName();
228 state[1] = ((StateHolder) _valueBinding).saveState(context);
229 return state;
230 }
231 return _valueBinding;
232 }
233 return null;
234 }
235
236 public void setTransient(boolean newTransientValue)
237 {
238 _transient = newTransientValue;
239 }
240
241 public boolean isTransient()
242 {
243 return _transient;
244 }
245
246 private FacesContext getFacesContext(ELContext context)
247 {
248 if (context == null)
249 {
250 throw new IllegalArgumentException("el context must not be null.");
251 }
252 FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class);
253 if (facesContext == null)
254 {
255 throw new IllegalStateException("faces context not available in el context.");
256 }
257 return facesContext;
258 }
259
260 private <T> T invoke(Invoker<T> invoker)
261 {
262 try
263 {
264 return invoker.invoke();
265 }
266 catch (javax.faces.el.PropertyNotFoundException e)
267 {
268 throw new PropertyNotFoundException(e.getMessage(), e);
269 }
270 catch (EvaluationException e)
271 {
272 throw new ELException(e.getMessage(), e);
273 }
274 }
275
276 private interface Invoker<T>
277 {
278 T invoke();
279 }
280 }