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.view;
19
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.Map;
23
24 import javax.faces.FactoryFinder;
25 import javax.faces.application.Application;
26 import javax.faces.application.FacesMessage;
27 import javax.faces.component.EditableValueHolder;
28 import javax.faces.component.UIComponent;
29 import javax.faces.component.UIViewRoot;
30 import javax.faces.context.ExternalContext;
31 import javax.faces.context.FacesContext;
32 import javax.faces.el.ValueBinding;
33 import javax.faces.lifecycle.Lifecycle;
34 import javax.faces.lifecycle.LifecycleFactory;
35
36 /***
37 * <p>Convenient abstract base class for application beans that wish to
38 * interact with JavaServer Faces request processing facilities.
39 * <strong>WARNING</strong> - These methods are only effective during
40 * the lifecycle of a JavaServer Faces request.</p>
41 *
42 * $Id: AbstractFacesBean.java 464373 2006-10-16 04:21:54Z rahul $
43 */
44 public abstract class AbstractFacesBean {
45
46
47
48
49
50 /***
51 * <p>Retiurn the <code>Application</code> instance for the current
52 * web application.</p>
53 */
54 protected Application getApplication() {
55
56 return FacesContext.getCurrentInstance().getApplication();
57
58 }
59
60
61 /***
62 * <p>Return a <code>Map</code> of the application scope attributes
63 * for this web application.</p>
64 */
65 protected Map getApplicationMap() {
66
67 return getExternalContext().getApplicationMap();
68
69 }
70
71
72 /***
73 * <p>Return the <code>ExternalContext</code> instance for the
74 * current request.</p>
75 */
76 protected ExternalContext getExternalContext() {
77
78 return FacesContext.getCurrentInstance().getExternalContext();
79
80 }
81
82
83 /***
84 * <p>Return the <code>FacesContext</code> instance for the
85 * current request.</p>
86 */
87 protected FacesContext getFacesContext() {
88
89 return FacesContext.getCurrentInstance();
90
91 }
92
93
94 /***
95 * <p>Return the configured <code>Lifecycle</code> instance for
96 * the current application.</p>
97 */
98 protected Lifecycle getLifecycle() {
99
100 String lifecycleId =
101 getExternalContext().getInitParameter("javax.faces.LIFECYCLE_ID");
102 if (lifecycleId == null || lifecycleId.length() == 0) {
103 lifecycleId = LifecycleFactory.DEFAULT_LIFECYCLE;
104 }
105 LifecycleFactory lifecycleFactory = (LifecycleFactory)
106 FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
107 return lifecycleFactory.getLifecycle(lifecycleId);
108
109 }
110
111
112 /***
113 * <p>Return a <code>Map</code> of the request headers included in this
114 * request. If there is more than one header for a particular header
115 * name, only the first value is included in this map.</p>
116 */
117 protected Map getRequestHeaderMap() {
118
119 return getExternalContext().getRequestHeaderMap();
120
121 }
122
123
124 /***
125 * <p>Return a <code>Map</code> of the request scope attributes
126 * for this request.</p>
127 */
128 protected Map getRequestMap() {
129
130 return getExternalContext().getRequestMap();
131
132 }
133
134
135 /***
136 * <p>Return a <code>Map</code> of the request parameters included in this
137 * request. If there is more than one value for a particular parameter
138 * name, only the first value is included in this map.</p>
139 */
140 protected Map getRequestParameterMap() {
141
142 return getExternalContext().getRequestParameterMap();
143
144 }
145
146
147 /***
148 * <p>Return a <code>Map</code> of the session scope attributes
149 * for the current user.</p>
150 */
151 protected Map getSessionMap() {
152
153 return getExternalContext().getSessionMap();
154
155 }
156
157
158
159
160
161 /***
162 * <p>Return the named bean from request, session, or application scope.
163 * If this is a managed bean, it might also get created as a side effect.
164 * Return <code>null</code> if no such bean can be found or created.</p>
165 *
166 * @param name Name of the desired bean
167 */
168 protected Object getBean(String name) {
169
170 FacesContext context = getFacesContext();
171 return context.getApplication().getVariableResolver().
172 resolveVariable(context, name);
173
174 }
175
176
177 /***
178 * <p>Replace the value of any attribute stored in request scope,
179 * session scope, or application scope, under the specified name.
180 * If there is no such value, store this value as a new request
181 * scope attribute under the specified name.</p>
182 *
183 * @param name Name of the attribute to replace or create
184 * @param value Value to be stored
185 */
186 protected void setBean(String name, Object value) {
187
188 setValue("#{" + name + "}", value);
189
190 }
191
192
193
194
195
196 /***
197 * <p>Evaluate the specified value binding expression and return
198 * the value it points at.</p>
199 *
200 * @param expr Value binding expression to be evaluated
201 */
202 protected Object getValue(String expr) {
203
204 ValueBinding vb = getApplication().createValueBinding(expr);
205 return vb.getValue(getFacesContext());
206
207 }
208
209
210 /***
211 * <p>Evaluate the specified value binding expression, and replace
212 * the value it points at.</p>
213 *
214 * @param expr Value binding expression pointing at a writeable property
215 * @param value New value to store there
216 */
217 protected void setValue(String expr, Object value) {
218
219 ValueBinding vb = getApplication().createValueBinding(expr);
220 vb.setValue(getFacesContext(), value);
221
222 }
223
224
225
226
227
228 /***
229 * <p>The attribute name under which saved data will be stored on the
230 * view root component.</p>
231 */
232 private static final String DATA_KEY = "org.apache.shale.DATA";
233
234
235
236 /***
237 * <p>Return the data object stored (typically when the component tree
238 * was previously rendered) under the specified key, if any; otherwise,
239 * return <code>null</code>.</p>
240 *
241 * <p><strong>IMPLEMENTATION NOTE:</strong> Data objects will become
242 * available only after the <em>Restore View</em> phase of the request
243 * processing lifecycle has been completed. A common place to reinitialize
244 * state information, then, would be in the <code>preprocess()</code>
245 * event handler of a {@link ViewController} backing bean.</p>
246 *
247 * @param key Key under which to retrieve the requested data
248 */
249 public Object retrieveData(String key) {
250
251 FacesContext context = getFacesContext();
252 if (context == null) {
253 return null;
254 }
255 UIViewRoot view = context.getViewRoot();
256 if (view == null) {
257 return null;
258 }
259 Map map = (Map) view.getAttributes().get(DATA_KEY);
260 if (map != null) {
261 return map.get(key);
262 } else {
263 return null;
264 }
265
266 }
267
268
269 /***
270 * <p>Save the specified data object (which <strong>MUST</strong> be
271 * <code>Serializable</code>) under the specified key, such that it can
272 * be retrieved (via <code>getData()</code>) on a s subsequent request
273 * immediately after the component tree has been restored.</p>
274 *
275 * <p><strong>IMPLEMENTATION NOTE:</strong> In order to successfully save
276 * data objects, this method must be called before the <em>Render Response</em>
277 * phase of the request processing lifecycle is executed. A common scenario
278 * is to save state information in the <code>prerender()</code> event handler
279 * of a {@link ViewController} backing bean.</p>
280 *
281 * @param key Key under which to store the requested data
282 * @param data Data object to be stored
283 */
284 public void saveData(String key, Object data) {
285
286 Map map = (Map)
287 getFacesContext().getViewRoot().getAttributes().get(DATA_KEY);
288 if (map == null) {
289 map = new HashMap();
290 getFacesContext().getViewRoot().getAttributes().put(DATA_KEY, map);
291 }
292 map.put(key, data);
293
294 }
295
296
297
298
299
300 /***
301 * <p>Erase submitted values on all <code>EditableValueHolder</code>
302 * components in the current view. This method should be called if
303 * you have input components bound to data values, submit the form,
304 * and then arbitrarily change the data that the binding points at
305 * without going through the <em>Update Model Values</em> phase of
306 * the request processing lifecycle.</p>
307 */
308 protected void erase() {
309
310 UIComponent view = getFacesContext().getViewRoot();
311 if (view != null) {
312 erase(view);
313 }
314
315 }
316
317
318 /***
319 * <p>Private helper method for <code>erase()</code> that recursively
320 * descends the component tree and performs the required processing.</p>
321 *
322 * @param component The component to be erased
323 */
324 private void erase(UIComponent component) {
325
326
327 if (component instanceof EditableValueHolder) {
328 ((EditableValueHolder) component).setSubmittedValue(null);
329 }
330
331 Iterator kids = component.getFacetsAndChildren();
332 while (kids.hasNext()) {
333 erase((UIComponent) kids.next());
334 }
335
336 }
337
338
339
340
341
342 /***
343 * <p>Return the first (or only) value for the specified request parameter.
344 * If no such request parameter exists for the current requset, return
345 * <code>null</code> instead.</p>
346 *
347 * @param name Name of the request parameter to look for
348 */
349 public String getRequestParameter(String name) {
350
351 return (String) getExternalContext().getRequestParameterMap().get(name);
352
353 }
354
355
356 /***
357 * <p>Return an array of all the values for the specified request parameter,
358 * if there are any. If no such request parameter exists for the current
359 * request, return <code>null</code> instead.</p>
360 *
361 * @param name Name of the request parameter to look for
362 */
363 public String[] getRequestParameterValues(String name) {
364
365 return (String[])
366 getExternalContext().getRequestParameterValuesMap().get(name);
367
368 }
369
370
371
372
373
374 /***
375 * <p>Log the specified message to the server's log file.</p>
376 *
377 * @param message Message to be logged
378 */
379 protected void log(String message) {
380
381 FacesContext context = getFacesContext();
382 ExternalContext econtext = null;
383 if (context != null) {
384 econtext = context.getExternalContext();
385 }
386 if (econtext != null) {
387 econtext.log(message);
388 } else {
389 System.out.println(message);
390 }
391
392 }
393
394
395 /***
396 * <p>Log the specified message and exception to the server's log file.</p>
397 *
398 * @param message Message to be logged
399 * @param throwable Exception to be logged
400 */
401 protected void log(String message, Throwable throwable) {
402
403 FacesContext context = getFacesContext();
404 ExternalContext econtext = null;
405 if (context != null) {
406 econtext = context.getExternalContext();
407 }
408 if (econtext != null) {
409 econtext.log(message, throwable);
410 } else {
411 System.out.println(message);
412 throwable.printStackTrace(System.out);
413 }
414
415 }
416
417
418
419
420
421 /***
422 * <p>Enqueue a global <code>FacesMessage</code> (not associated with any
423 * particular component) containing the specified summary text and a
424 * message severity level of <code>FacesMessage.SEVERITY_INFO</code>.</p>
425 *
426 * @param summary Summary text for this message
427 */
428 protected void info(String summary) {
429
430 getFacesContext().addMessage(null,
431 new FacesMessage(FacesMessage.SEVERITY_INFO, summary, null));
432
433 }
434
435
436 /***
437 * <p>Enqueue a <code>FacesMessage</code> (associated with the
438 * specified component) containing the specified summary text and a
439 * message severity level of <code>FacesMessage.SEVERITY_INFO</code>.</p>
440 *
441 * @param component Component with which this message is associated
442 * @param summary Summary text for this message
443 */
444 protected void info(UIComponent component, String summary) {
445
446 FacesContext context = getFacesContext();
447 context.addMessage(component.getClientId(context),
448 new FacesMessage(FacesMessage.SEVERITY_INFO, summary, null));
449
450 }
451
452
453 /***
454 * <p>Enqueue a global <code>FacesMessage</code> (not associated with any
455 * particular component) containing the specified summary text and a
456 * message severity level of <code>FacesMessage.SEVERITY_WARN</code>.</p>
457 *
458 * @param summary Summary text for this message
459 */
460 protected void warn(String summary) {
461
462 getFacesContext().addMessage(null,
463 new FacesMessage(FacesMessage.SEVERITY_WARN, summary, null));
464
465 }
466
467
468 /***
469 * <p>Enqueue a <code>FacesMessage</code> (associated with the
470 * specified component) containing the specified summary text and a
471 * message severity level of <code>FacesMessage.SEVERITY_WARN</code>.</p>
472 *
473 * @param component Component with which this message is associated
474 * @param summary Summary text for this message
475 */
476 protected void warn(UIComponent component, String summary) {
477
478 FacesContext context = getFacesContext();
479 context.addMessage(component.getClientId(context),
480 new FacesMessage(FacesMessage.SEVERITY_WARN, summary, null));
481
482 }
483
484
485 /***
486 * <p>Enqueue a global <code>FacesMessage</code> (not associated with any
487 * particular component) containing the specified summary text and a
488 * message severity level of <code>FacesMessage.SEVERITY_ERROR</code>.</p>
489 *
490 * @param summary Summary text for this message
491 */
492 protected void error(String summary) {
493
494 getFacesContext().addMessage(null,
495 new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, null));
496
497 }
498
499
500 /***
501 * <p>Enqueue a <code>FacesMessage</code> (associated with the
502 * specified component) containing the specified summary text and a
503 * message severity level of <code>FacesMessage.SEVERITY_ERROR</code>.</p>
504 *
505 * @param component Component with which this message is associated
506 * @param summary Summary text for this message
507 */
508 protected void error(UIComponent component, String summary) {
509
510 FacesContext context = getFacesContext();
511 context.addMessage(component.getClientId(context),
512 new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, null));
513
514 }
515
516
517 /***
518 * <p>Enqueue a global <code>FacesMessage</code> (not associated with any
519 * particular component) containing the specified summary text and a
520 * message severity level of <code>FacesMessage.SEVERITY_FATAL</code>.</p>
521 *
522 * @param summary Summary text for this message
523 */
524 protected void fatal(String summary) {
525
526 getFacesContext().addMessage(null,
527 new FacesMessage(FacesMessage.SEVERITY_FATAL, summary, null));
528
529 }
530
531
532 /***
533 * <p>Enqueue a <code>FacesMessage</code> (associated with the
534 * specified component) containing the specified summary text and a
535 * message severity level of <code>FacesMessage.SEVERITY_FATAL</code>.</p>
536 *
537 * @param component Component with which this message is associated
538 * @param summary Summary text for this message
539 */
540 protected void fatal(UIComponent component, String summary) {
541
542 FacesContext context = getFacesContext();
543 context.addMessage(component.getClientId(context),
544 new FacesMessage(FacesMessage.SEVERITY_FATAL, summary, null));
545
546 }
547
548
549 }