2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.test.mock;
19
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.Map;
23
24 import javax.faces.application.Application;
25 import javax.faces.component.StateHolder;
26 import javax.faces.context.ExternalContext;
27 import javax.faces.context.FacesContext;
28 import javax.faces.el.EvaluationException;
29 import javax.faces.el.PropertyNotFoundException;
30 import javax.faces.el.PropertyResolver;
31 import javax.faces.el.ReferenceSyntaxException;
32 import javax.faces.el.ValueBinding;
33 import javax.faces.el.VariableResolver;
34
35
36 /***
37 * <p>Mock implementation of <code>ValueBinding</code>.</p>
38 */
39
40 public class MockValueBinding extends ValueBinding implements StateHolder {
41
42
43
44
45
46 /***
47 * <p>Construct a default instance.</p>
48 */
49 public MockValueBinding() {
50
51 this(null, null);
52
53 }
54
55
56 /***
57 * <p>Construct a new value binding for the specified expression.</p>
58 *
59 * @param application Application instance to be wrapped
60 * @param ref Expression to be wrapped
61 */
62 public MockValueBinding(Application application, String ref) {
63
64 this.application = application;
65 if (ref != null) {
66 if (ref.startsWith("#{") && ref.endsWith("}")) {
67 ref = ref.substring(2, ref.length() - 1);
68 }
69 }
70 this.ref = ref;
71
72 }
73
74
75
76
77
78 /***
79 * <p>Return the expression string for this value binding.</p>
80 */
81 public String ref() {
82
83 return this.ref;
84
85 }
86
87
88
89
90
91 /***
92 * <p>The <code>Application</code> instance for this application.</p>
93 */
94 private transient Application application;
95
96
97 /***
98 * <p>The expression this value binding will evaluate.</p>
99 */
100 private String ref;
101
102
103
104
105
106 /*** {@inheritDoc} */
107 public Object getValue(FacesContext context)
108 throws EvaluationException, PropertyNotFoundException {
109
110 if (context == null) {
111 throw new NullPointerException();
112 }
113 List names = parse(ref);
114
115
116 VariableResolver vr = application().getVariableResolver();
117 String name = (String) names.get(0);
118 Object base = vr.resolveVariable(context, name);
119 if (names.size() < 2) {
120 return (base);
121 }
122
123
124 PropertyResolver pr = application().getPropertyResolver();
125 for (int i = 1; i < names.size(); i++) {
126 base = pr.getValue(base, (String) names.get(i));
127 }
128
129
130 return (base);
131
132 }
133
134
135 /*** {@inheritDoc} */
136 public void setValue(FacesContext context, Object value)
137 throws EvaluationException, PropertyNotFoundException {
138
139 if (context == null) {
140 throw new NullPointerException();
141 }
142 List names = parse(ref);
143
144
145 VariableResolver vr = application().getVariableResolver();
146 String name = (String) names.get(0);
147 Object base = vr.resolveVariable(context, name);
148 if (names.size() < 2) {
149 if ("applicationScope".equals(name)
150 || "requestScope".equals(name)
151 || "sessionScope".equals(name)) {
152 throw new ReferenceSyntaxException("Cannot set '"
153 + name + "'");
154 }
155 Map map = econtext().getRequestMap();
156 if (map.containsKey(name)) {
157 map.put(name, value);
158 return;
159 }
160 map = econtext().getSessionMap();
161 if ((map != null) && (map.containsKey(name))) {
162 map.put(name, value);
163 return;
164 }
165 map = econtext().getApplicationMap();
166 if (map.containsKey(name)) {
167 map.put(name, value);
168 return;
169 }
170 econtext().getRequestMap().put(name, value);
171 return;
172 }
173
174
175 PropertyResolver pr = application().getPropertyResolver();
176 for (int i = 1; i < (names.size() - 1); i++) {
177
178 base = pr.getValue(base, (String) names.get(i));
179 }
180
181
182 pr.setValue(base, (String) names.get(names.size() - 1), value);
183
184 }
185
186
187 /*** {@inheritDoc} */
188 public boolean isReadOnly(FacesContext context)
189 throws PropertyNotFoundException {
190
191 if (context == null) {
192 throw new NullPointerException();
193 }
194 List names = parse(ref);
195
196
197 VariableResolver vr = application().getVariableResolver();
198 String name = (String) names.get(0);
199 Object base = vr.resolveVariable(context, name);
200 if (names.size() < 2) {
201 return true;
202 }
203
204
205 PropertyResolver pr = application().getPropertyResolver();
206 for (int i = 1; i < names.size() - 1; i++) {
207 base = pr.getValue(base, (String) names.get(i));
208 }
209
210
211 return pr.isReadOnly(base, (String) names.get(names.size() - 1));
212
213 }
214
215
216 /*** {@inheritDoc} */
217 public Class getType(FacesContext context)
218 throws PropertyNotFoundException {
219
220 if (context == null) {
221 throw new NullPointerException();
222 }
223 List names = parse(ref);
224
225
226 VariableResolver vr = application().getVariableResolver();
227 String name = (String) names.get(0);
228 Object base = vr.resolveVariable(context, name);
229 if (names.size() < 2) {
230 return base.getClass();
231 }
232
233
234 PropertyResolver pr = application().getPropertyResolver();
235 for (int i = 1; i < names.size() - 1; i++) {
236 base = pr.getValue(base, (String) names.get(i));
237 }
238
239
240 return pr.getType(base, (String) names.get(names.size() - 1));
241
242 }
243
244 /*** {@inheritDoc} */
245 public String getExpressionString() {
246
247 return "#{" + ref + "}";
248
249 }
250
251
252
253
254
255 /*** {@inheritDoc} */
256 public Object saveState(FacesContext context) {
257
258 Object[] values = new Object[1];
259 values[0] = ref;
260 return values;
261
262 }
263
264
265 /*** {@inheritDoc} */
266 public void restoreState(FacesContext context, Object state) {
267
268 Object[] values = (Object[]) state;
269 ref = (String) values[0];
270
271 }
272
273
274 /***
275 * <p>Flag indicating that this value is transient.</p>
276 */
277 private boolean transientFlag = false;
278
279
280 /*** {@inheritDoc} */
281 public boolean isTransient() {
282
283 return this.transientFlag;
284
285 }
286
287
288 /*** {@inheritDoc} */
289 public void setTransient(boolean transientFlag) {
290
291 this.transientFlag = transientFlag;
292
293 }
294
295
296
297
298
299 /***
300 * <p>Return the relevant <code>Application</code> instance.</p>
301 */
302 private Application application() {
303
304 if (application == null) {
305 application = FacesContext.getCurrentInstance().getApplication();
306 }
307 return (application);
308
309 }
310
311
312 /***
313 * <p>Return the relevant <code>ExternalContext</code> instance.</p>
314 */
315 private ExternalContext econtext() {
316
317 return (FacesContext.getCurrentInstance().getExternalContext());
318
319 }
320
321
322 /***
323 * <p>Return a list of the expression elements in this expression.</p>
324 *
325 * @param ref Expression to be parsed
326 */
327 private List parse(String ref) {
328
329 List names = new ArrayList();
330 StringBuffer expr = new StringBuffer(ref);
331 boolean isBlockOn = false;
332 for (int i = expr.length() - 1; i > -1; i--) {
333 if (expr.charAt(i) == ' ') {
334 expr.deleteCharAt(i);
335 } else if (expr.charAt(i) == ']') {
336 expr.deleteCharAt(i);
337 } else if (expr.charAt(i) == '[') {
338 expr.deleteCharAt(i);
339 } else if (expr.charAt(i) == '\'') {
340 if (!isBlockOn) {
341 expr.deleteCharAt(i);
342 } else {
343 names.add(0, expr.substring(i + 1));
344 expr.delete(i, expr.length());
345 }
346 isBlockOn = !isBlockOn;
347 } else if (expr.charAt(i) == '.' && !isBlockOn) {
348 names.add(0, expr.substring(i + 1));
349 expr.delete(i, expr.length());
350 }
351 }
352
353 if (expr.length() > 0) {
354 names.add(0, expr.toString());
355 }
356
357 if (names.size() < 1) {
358 throw new ReferenceSyntaxException("No expression in '"
359 + ref + "'");
360 }
361 for (int i = 0; i < names.size(); i++) {
362 String name = (String) names.get(i);
363 if (name.length() < 1) {
364 throw new ReferenceSyntaxException("Invalid expression '"
365 + ref + "'");
366 }
367 }
368 return (names);
369
370 }
371
372
373 }