Save This Page
Home » mojarra-1.2_09-b02-FCS-source » javax.faces.application » [javadoc | source]
    1   /*
    2    * $Id: StateManager.java,v 1.41 2007/04/27 22:00:02 ofung Exp $
    3    */
    4   
    5   /*
    6    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    7    * 
    8    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40   
   41   package javax.faces.application;
   42   
   43   import javax.faces.component.NamingContainer;
   44   import javax.faces.component.UIViewRoot;
   45   import javax.faces.context.FacesContext;
   46   import javax.faces.context.ResponseWriter;
   47   import javax.faces.render.RenderKit;
   48   import javax.faces.render.ResponseStateManager;
   49   
   50   import java.io.IOException;
   51   
   52   
   53   /**
   54    * <p><strong>StateManager</strong> directs the process of saving and
   55    * restoring the view between requests.  The {@link StateManager}
   56    * instance for an application is retrieved from the {@link Application}
   57    * instance, and thus cannot know any details of the markup language
   58    * created by the {@link RenderKit} being used to render a view.  The
   59    * {@link StateManager} utilizes a helper object ({@link
   60    * ResponseStateManager}), that is provided by the {@link RenderKit}
   61    * implementation and is therefore aware of the markup language
   62    * details.</p>
   63    */
   64   
   65   public abstract class
   66         StateManager {
   67   
   68       // ------------------------------------------------------ Manifest Constants
   69   
   70   
   71       /**
   72        * <p>The <code>ServletContext</code> init parameter consulted by
   73        * the <code>StateManager</code> to tell where the state should be
   74        * saved.  Valid values are given as the values of the constants:
   75        * {@link #STATE_SAVING_METHOD_CLIENT} or {@link
   76        * #STATE_SAVING_METHOD_SERVER}.</p>
   77        * <p/>
   78        * <p>If this parameter is not specified, the default value is the
   79        * value of the constant {@link #STATE_SAVING_METHOD_CLIENT}. </p>
   80        */
   81       public static final String STATE_SAVING_METHOD_PARAM_NAME =
   82             "javax.faces.STATE_SAVING_METHOD";
   83   
   84   
   85       /**
   86        * <p>Constant value for the initialization parameter named by
   87        * the <code>STATE_SAVING_METHOD_PARAM_NAME</code> that indicates
   88        * state saving should take place on the client.</p>
   89        */
   90       public static final String STATE_SAVING_METHOD_CLIENT = "client";
   91   
   92   
   93       /**
   94        * <p>Constant value for the initialization parameter named by
   95        * the <code>STATE_SAVING_METHOD_PARAM_NAME</code> that indicates
   96        * state saving should take place on the server.</p>
   97        */
   98       public static final String STATE_SAVING_METHOD_SERVER = "server";
   99   
  100       // ---------------------------------------------------- State Saving Methods
  101   
  102   
  103       /**
  104        * <p>Return the tree structure and component state information for the
  105        * view contained in the specified {@link FacesContext} instance as an
  106        * object of type <code>StateManager.SerializedView</code>.  If there
  107        * is no state information to be saved, return <code>null</code>
  108        * instead.</p>
  109        * <p/>
  110        * <p>Components may opt out of being included in the serialized view
  111        * by setting their <code>transient</code> property to <code>true</code>.
  112        * This must cause the component itself, as well as all of that component's
  113        * children and facets, to be omitted from the saved  tree structure
  114        * and component state information.</p>
  115        * <p/>
  116        * <p>This method must also enforce the rule that, for components with
  117        * non-null <code>id</code>s, all components that are descendants of the
  118        * same nearest {@link NamingContainer} must have unique identifiers.</p>
  119        *
  120        * @param context {@link FacesContext} for the current request
  121        *
  122        * @throws IllegalStateException if more than one component or
  123        *                               facet within the same {@link NamingContainer} in this view has
  124        *                               the same non-<code>null</code> component id
  125        * @deprecated this has been replaced by {@link #saveView}.  The
  126        *             default implementation returns <code>null</code>.
  127        */
  128       public SerializedView saveSerializedView(FacesContext context) {
  129           return null;
  130       }
  131   
  132       /**
  133        * <p>Return an opaque <code>Object</code> containing sufficient
  134        * information for this same instance to restore the state of the
  135        * current {@link UIViewRoot} on a subsequent request.  The returned
  136        * object must implement <code>java.io.Serializable</code>. If there
  137        * is no state information to be saved, return <code>null</code>
  138        * instead.</p>
  139        * <p/>
  140        * <p>Components may opt out of being included in the serialized view
  141        * by setting their <code>transient</code> property to <code>true</code>.
  142        * This must cause the component itself, as well as all of that component's
  143        * children and facets, to be omitted from the saved  tree structure
  144        * and component state information.</p>
  145        * <p/>
  146        * <p>This method must also enforce the rule that, for components with
  147        * non-null <code>id</code>s, all components that are descendants of the
  148        * same nearest {@link NamingContainer} must have unique identifiers.</p>
  149        * <p/>
  150        * <p>For backwards compatability with existing
  151        * <code>StateManager</code> implementations, the default
  152        * implementation of this method calls {@link #saveSerializedView}
  153        * and creates and returns a two element <code>Object</code> array
  154        * with element zero containing the <code>structure</code> property
  155        * and element one containing the <code>state</code> property of the
  156        * <code>SerializedView</code>.</p>
  157        *
  158        * @param context {@link FacesContext} for the current request
  159        *
  160        * @throws IllegalStateException if more than one component or
  161        *                               facet within the same {@link NamingContainer} in this view has
  162        *                               the same non-<code>null</code> component id
  163        * @since 1.2
  164        */
  165       public Object saveView(FacesContext context) {
  166           SerializedView view = saveSerializedView(context);
  167           Object stateArray[] = {view.getStructure(),
  168                                  view.getState()};
  169           return stateArray;
  170       }
  171   
  172   
  173       /**
  174        * <p>Convenience method, which must be called by
  175        * <code>saveSerializedView()</code>, to construct and return a
  176        * <code>Serializable</code> object that represents the structure
  177        * of the entire component tree (including children and facets)
  178        * of this view.</p>
  179        * <p/>
  180        * <p>Components may opt-out of being included in the tree structure
  181        * by setting their <code>transient</code> property to <code>true</code>.
  182        * This must cause the component itself, as well as all of that component's
  183        * children and facets, to be omitted from the saved  tree structure
  184        * information.</p>
  185        *
  186        * @param context {@link FacesContext} for the current request
  187        *
  188        * @deprecated the distinction between tree structure and component
  189        *             state is now an implementation detail.  The default
  190        *             implementation returns <code>null</code>.
  191        */
  192       protected Object getTreeStructureToSave(FacesContext context) {
  193           return null;
  194       }
  195   
  196   
  197       /**
  198        * <p>Convenience method, which must be called by
  199        * <code>saveSerializedView()</code>, to construct and return a
  200        * <code>Serializable</code> object that represents the state of
  201        * all component properties, attributes, and attached objects, for
  202        * the entire component tree (including children and facets)
  203        * of this view.</p>
  204        * <p/>
  205        * <p>Components may opt-out of being included in the component state
  206        * by setting their <code>transient</code> property to <code>true</code>.
  207        * This must cause the component itself, as well as all of that component's
  208        * children and facets, to be omitted from the saved component state
  209        * information.</p>
  210        *
  211        * @param context {@link FacesContext} for the current request
  212        *
  213        * @deprecated the distinction between tree structure and component
  214        *             state is now an implementation detail.  The default
  215        *             implementation returns <code>null</code>.
  216        */
  217       protected Object getComponentStateToSave(FacesContext context) {
  218           return null;
  219       }
  220   
  221       /**
  222        * <p>Save the state represented in the specified state
  223        * <code>Object</code> instance, in an implementation dependent
  224        * manner.</p>
  225        * <p/>
  226        * <p>This method will typically simply delegate the actual
  227        * writing to the <code>writeState()</code> method of the
  228        * {@link ResponseStateManager} instance provided by the
  229        * {@link RenderKit} being used to render this view.  This
  230        * method assumes that the caller has positioned the
  231        * {@link ResponseWriter} at the correct position for the
  232        * saved state to be written.</p>
  233        * <p/>
  234        * <p>For backwards compatability with existing
  235        * <code>StateManager</code> implementations, the default
  236        * implementation of this method checks if the argument is an
  237        * instance of <code>Object []</code> of length greater than or
  238        * equal to two.  If so, it creates a <code>SerializedView</code>
  239        * instance with the tree structure coming from element zero and
  240        * the component state coming from element one and calls through to
  241        * {@link
  242        * #writeState(javax.faces.context.FacesContext,javax.faces.application.StateManager.SerializedView)}.
  243        * If not, does nothing.</p>
  244        *
  245        * @param context {@link FacesContext} for the current request
  246        * @param state   the Serializable state to be written,
  247        *                as returned by {@link #saveSerializedView}
  248        *
  249        * @since 1.2
  250        */
  251       public void writeState(FacesContext context, Object state)
  252             throws IOException {
  253           if (null != state && state.getClass().isArray() &&
  254               state.getClass().getComponentType().equals(Object.class)) {
  255               Object stateArray[] = (Object[]) state;
  256               if (2 == stateArray.length) {
  257                   SerializedView view = new SerializedView(stateArray[0],
  258                                                            stateArray[1]);
  259                   writeState(context, view);
  260               }
  261           }
  262       }
  263   
  264       /**
  265        * <p>Save the state represented in the specified
  266        * <code>SerializedView</code> isntance, in an implementation
  267        * dependent manner.</p>
  268        * <p/>
  269        * <p>This method must consult the context initialization parameter
  270        * named by the symbolic constant
  271        * <code>StateManager.STATE_SAVING_METHOD_PARAMETER_NAME</code>
  272        * to determine whether state should be saved on the client or the
  273        * server.  If not present, client side state saving is assumed.</p>
  274        * <p/>
  275        * <p>If the init parameter indicates that client side state
  276        * saving should be used, this method must delegate the actual
  277        * writing to the <code>writeState()</code> method of the
  278        * {@link ResponseStateManager} instance provided by the
  279        * {@link RenderKit} being used to render this view.  This
  280        * method assumes that the caller has positioned the
  281        * {@link ResponseWriter} at the correct position for the
  282        * saved state to be written.</p>
  283        *
  284        * @param context {@link FacesContext} for the current request
  285        * @param state   the serialized state to be written
  286        *
  287        * @deprecated This method has been replaced by {@link
  288        *             #writeState(javax.faces.context.FacesContext,java.lang.Object)}.
  289        *             The default implementation of this method does nothing.
  290        */
  291       public void writeState(FacesContext context,
  292                              SerializedView state) throws IOException {
  293       }
  294   
  295       // ------------------------------------------------- State Restoring Methods
  296   
  297   
  298       /**
  299        * <p>Restore the tree structure and the component state of the view
  300        * for the specified <code>viewId</code>, in an implementation dependent
  301        * manner, and return the restored {@link UIViewRoot}.  If there is no
  302        * saved state information available for this <code>viewId</code>,
  303        * return <code>null</code> instead.</p>
  304        * <p/>
  305        * <p>This method must consult the context initialization parameter
  306        * named by the symbolic constant
  307        * <code>StateManager.STATE_SAVING_METHOD_PARAMETER_NAME</code>
  308        * to determine whether state should be saved on the client or the
  309        * server.  If not present, client side state saving is assumed.</p>
  310        * <p/>
  311        * <p>If the init parameter indicates that client side state
  312        * saving should be used, this method must call the
  313        * <code>getTreeStructureToRestore()</code> and (if the previous method
  314        * call returned a non-null value) <code>getComponentStateToRestore()</code>
  315        * methods of the {@link ResponseStateManager} instance provided by the
  316        * {@link RenderKit} responsible for this view.</p>
  317        *
  318        * @param context     {@link FacesContext} for the current request
  319        * @param viewId      View identifier of the view to be restored
  320        * @param renderKitId the renderKitId used to render this response.
  321        *                    Must not be <code>null</code>.
  322        *
  323        * @throws IllegalArgumentException if <code>renderKitId</code>
  324        *                                  is <code>null</code>.
  325        */
  326       public abstract UIViewRoot restoreView(FacesContext context, String viewId,
  327                                              String renderKitId);
  328   
  329   
  330       /**
  331        * <p>Convenience method, which must be called by
  332        * <code>restoreView()</code>, to construct and return a {@link UIViewRoot}
  333        * instance (populated with children and facets) representing the
  334        * tree structure of the component tree being restored.  If no saved
  335        * state information is available, return <code>null</code> instead.</p>
  336        *
  337        * @param context     {@link FacesContext} for the current request
  338        * @param viewId      View identifier of the view to be restored
  339        * @param renderKitId the renderKitId used to render this response.
  340        *                    Must not be <code>null</code>.
  341        *
  342        * @throws IllegalArgumentException if <code>renderKitId</code>
  343        *                                  is <code>null</code>.
  344        * @deprecated the distinction between tree structure and component
  345        *             state is now an implementation detail.  The default
  346        *             implementation returns <code>null</code>.
  347        */
  348       protected UIViewRoot restoreTreeStructure(FacesContext context,
  349                                                 String viewId,
  350                                                 String renderKitId) {
  351           return null;
  352       }
  353   
  354   
  355       /**
  356        * <p>Convenience method, which must be called by
  357        * <code>restoreView()</code>, to restore the attributes, properties,
  358        * and attached objects of all components in the restored component tree.
  359        * </p>
  360        *
  361        * @param context     {@link FacesContext} for the current request
  362        * @param viewRoot    {@link UIViewRoot} returned by a previous call
  363        *                    to <code>restoreTreeStructure()</code>
  364        * @param renderKitId the renderKitId used to render this response.
  365        *                    Must not be <code>null</code>.
  366        *
  367        * @throws IllegalArgumentException if <code>renderKitId</code>
  368        *                                  is <code>null</code>.
  369        * @deprecated the distinction between tree structure and component
  370        *             state is now an implementation detail.  The default
  371        *             implementation does nothing.
  372        */
  373       protected void restoreComponentState(FacesContext context,
  374                                            UIViewRoot viewRoot,
  375                                            String renderKitId) {
  376       }
  377   
  378   
  379       private Boolean savingStateInClient = null;
  380   
  381       /**
  382        * @return <code>true</code> if and only if the value of the
  383        *         <code>ServletContext</code> init parameter named by the value of
  384        *         the constant {@link #STATE_SAVING_METHOD_PARAM_NAME} is equal to
  385        *         the value of the constant {@link #STATE_SAVING_METHOD_CLIENT}.
  386        *         <code>false</code> otherwise.
  387        *
  388        * @throws NullPointerException if <code>context</code> is
  389        *                              <code>null</code>.
  390        */
  391   
  392       public boolean isSavingStateInClient(FacesContext context) {
  393           if (null != savingStateInClient) {
  394               return savingStateInClient.booleanValue();
  395           }
  396           savingStateInClient = Boolean.FALSE;
  397   
  398           String saveStateParam = context.getExternalContext().
  399                 getInitParameter(STATE_SAVING_METHOD_PARAM_NAME);
  400           if (saveStateParam != null &&
  401               saveStateParam.equalsIgnoreCase(STATE_SAVING_METHOD_CLIENT)) {
  402               savingStateInClient = Boolean.TRUE;
  403           }
  404           return savingStateInClient.booleanValue();
  405       }
  406   
  407       /**
  408        * <p>Convenience struct for encapsulating tree structure and
  409        * component state.  This is necessary to allow the API to be
  410        * flexible enough to work in JSP and non-JSP environments.</p>
  411        *
  412        * @deprecated This class was not marked <code>Serializable</code>
  413        *             in the 1.0 version of the spec.  It was also not a static inner
  414        *             class, so it can't be made to be <code>Serializable</code>.
  415        *             Therefore, it is being deprecated in version 1.2 of the spec.
  416        *             The replacement is to use an implementation dependent
  417        *             <code>Object</code>.
  418        */
  419   
  420       public class SerializedView extends Object {
  421           private Object structure = null;
  422           private Object state = null;
  423   
  424           public SerializedView(Object newStructure, Object newState) {
  425               structure = newStructure;
  426               state = newState;
  427           }
  428   
  429           public Object getStructure() {
  430               return structure;
  431           }
  432   
  433           public Object getState() {
  434               return state;
  435           }
  436       }
  437   
  438   }

Save This Page
Home » mojarra-1.2_09-b02-FCS-source » javax.faces.application » [javadoc | source]