Author: craigmcc Date: Thu May 25 13:40:00 2006 New Revision: 409460 URL: http://svn.apache.org/viewvc?rev=409460&view=rev Log: Add convenience methods to save and restore arbitrary (but Serializable) data objects under an attribute of the view root component. This is very useful for passing information from a rendered version of a view to the following request that will process a postback, without having to store it in session scope or explicitly modify the view to include something like <h:inputHidden/>.
If you use ViewController, you would typically call saveData("key", value) in the prerender() method, and call retrieveData("key") in the preprocess() method. Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/view/AbstractFacesBean.java Modified: struts/shale/trunk/core-library/src/java/org/apache/shale/view/AbstractFacesBean.java URL: http://svn.apache.org/viewvc/struts/shale/trunk/core-library/src/java/org/apache/shale/view/AbstractFacesBean.java?rev=409460&r1=409459&r2=409460&view=diff ============================================================================== --- struts/shale/trunk/core-library/src/java/org/apache/shale/view/AbstractFacesBean.java (original) +++ struts/shale/trunk/core-library/src/java/org/apache/shale/view/AbstractFacesBean.java Thu May 25 13:40:00 2006 @@ -16,12 +16,14 @@ package org.apache.shale.view; +import java.util.HashMap; import java.util.Map; import javax.faces.FactoryFinder; import javax.faces.application.Application; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; +import javax.faces.component.UIViewRoot; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; @@ -213,6 +215,78 @@ ValueBinding vb = getApplication().createValueBinding(expr); vb.setValue(getFacesContext(), value); + + } + + + // ----------------------------------------------- Save/Restore Data Methods + + + /** + * <p>The attribute name under which saved data will be stored on the + * view root component.</p> + */ + private static final String DATA_KEY = "org.apache.shale.DATA"; + + + + /** + * <p>Return the data object stored (typically when the component tree + * was previously rendered) under the specified key, if any; otherwise, + * return <code>null</code>.</p> + * + * <p><strong>IMPLEMENTATION NOTE:</strong> Data objects will become + * available only after the <em>Restore View</em> phase of the request + * processing lifecycle has been completed. A common place to reinitialize + * state information, then, would be in the <code>preprocess()</code> + * event handler of a [EMAIL PROTECTED] ViewController} backing bean.</p> + * + * @param key Key under which to retrieve the requested data + */ + public Object retrieveData(String key) { + + FacesContext context = getFacesContext(); + if (context == null) { + return null; + } + UIViewRoot view = context.getViewRoot(); + if (view == null) { + return null; + } + Map map = (Map) view.getAttributes().get(DATA_KEY); + if (map != null) { + return map.get(key); + } else { + return null; + } + + } + + + /** + * <p>Save the specified data object (which <strong>MUST</strong> be + * <code>Serializable</code>) under the specified key, such that it can + * be retrieved (via <code>getData()</code>) on a s subsequent request + * immediately after the component tree has been restored.</p> + * + * <p><strong>IMPLEMENTATION NOTE:</strong> In order to successfully save + * data objects, this method must be called before the <em>Render Response</em> + * phase of the request processing lifecycle is executed. A common scenario + * is to save state information in the <code>prerender()</code> event handler + * of a [EMAIL PROTECTED] ViewController} backing bean.</p> + * + * @param key Key under which to store the requested data + * @param data Data object to be stored + */ + public void saveData(String key, Object data) { + + Map map = (Map) + getFacesContext().getViewRoot().getAttributes().get(DATA_KEY); + if (map == null) { + map = new HashMap(); + getFacesContext().getViewRoot().getAttributes().put(DATA_KEY, map); + } + map.put(key, data); }