View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package javax.faces.application;
20  
21  /**
22   * Responsible for storing sufficient information about a component tree so that an identical tree
23   * can later be recreated.
24   * <p>
25   * It is up to the concrete implementation to decide whether to use information from the "view template"
26   * that was used to first create the view, or whether to store sufficient information to enable the
27   * view to be restored without any reference to the original template. However as JSF components have
28   * mutable fields that can be set by code, and affected by user input, at least some state does need
29   * to be kept in order to recreate a previously-existing component tree.
30   * <p>
31   * There are two different options defined by the specification: "client" and "server" state.
32   * <p>
33   * When "client" state is configured, all state information required to create the tree is embedded within
34   * the data rendered to the client. Note that because data received from a remote client must always be
35   * treated as "tainted", care must be taken when using such data. Some StateManager implementations may
36   * use encryption to ensure that clients cannot modify the data, and that the data received on postback
37   * is therefore trustworthy.
38   * <p>
39   * When "server" state is configured, the data is saved somewhere "on the back end", and (at most) a
40   * token is embedded in the data rendered to the user.
41   * <p>
42   * This class is usually invoked by a concrete implementation of ViewHandler.
43   * <p>
44   * Note that class ViewHandler isolates JSF components from the details of the request format. This class
45   * isolates JSF components from the details of the response format. Because request and response are usually
46   * tightly coupled, the StateManager and ViewHandler implementations are also usually fairly tightly coupled
47   * (ie the ViewHandler/StateManager implementations come as pairs).
48   * <p>
49   * See the javadoc for this class in the
50   * <a href="http://java.sun.com/j2ee/javaserverfaces/1.1_01/docs/api/index.html">JSF Specification</a>
51   * for more details.
52   *
53   * @author Manfred Geiler (latest modification by $Author: skitching $)
54   * @version $Revision: 705327 $ $Date: 2008-10-16 14:06:57 -0500 (Thu, 16 Oct 2008) $
55   */
56  public abstract class StateManager
57  {
58      public static final String STATE_SAVING_METHOD_PARAM_NAME = "javax.faces.STATE_SAVING_METHOD";
59      public static final String STATE_SAVING_METHOD_CLIENT = "client";
60      public static final String STATE_SAVING_METHOD_SERVER = "server";
61      private Boolean _savingStateInClient = null;
62  
63      /**
64       * Invokes getTreeStructureToSave and getComponentStateToSave, then return an object that wraps the two
65       * resulting objects. This object can then be passed to method writeState.
66       */
67      public abstract StateManager.SerializedView saveSerializedView(javax.faces.context.FacesContext context);
68  
69      /**
70       * Return data that is sufficient to recreate the component tree that is the viewroot of the specified
71       * context, but without restoring the state in the components.
72       * <p>
73       * Using this data, a tree of components which has the same "shape" as the original component
74       * tree can be recreated. However the component instances themselves will have only their default
75       * values, ie their member fields will not have been set to the original values.
76       */
77      protected abstract Object getTreeStructureToSave(javax.faces.context.FacesContext context);
78  
79      /**
80       * Return data that can be applied to a component tree created using the "getTreeStructureToSave"
81       * method.
82       */
83      protected abstract Object getComponentStateToSave(javax.faces.context.FacesContext context);
84  
85      /**
86       * Associate the provided state object with the current response being generated.
87       * <p>
88       * When client-side state is enabled, it is expected that method writes the data contained in the
89       * state parameter to the response somehow.
90       * <p>
91       * When server-side state is enabled, at most a "token" is expected to be written.
92       */
93      public abstract void writeState(javax.faces.context.FacesContext context,
94                                      StateManager.SerializedView state)
95              throws java.io.IOException;
96  
97      public abstract javax.faces.component.UIViewRoot restoreView(javax.faces.context.FacesContext context,
98                                                                   String viewId,
99                                                                   String renderKitId);
100 
101     protected abstract javax.faces.component.UIViewRoot restoreTreeStructure(javax.faces.context.FacesContext context,
102                                                                              String viewId,
103                                                                              String renderKitId);
104 
105     protected abstract void restoreComponentState(javax.faces.context.FacesContext context,
106                                                   javax.faces.component.UIViewRoot viewRoot,
107                                                   String renderKitId);
108 
109     public boolean isSavingStateInClient(javax.faces.context.FacesContext context)
110     {
111         if(context == null) throw new NullPointerException("context");
112         if (_savingStateInClient != null) return _savingStateInClient.booleanValue();
113         String stateSavingMethod = context.getExternalContext().getInitParameter(STATE_SAVING_METHOD_PARAM_NAME);
114         if (stateSavingMethod == null)
115         {
116             _savingStateInClient = Boolean.FALSE; //Specs 10.1.3: default server saving
117             context.getExternalContext().log("No state saving method defined, assuming default server state saving");
118         }
119         else if (stateSavingMethod.equals(STATE_SAVING_METHOD_CLIENT))
120         {
121             _savingStateInClient = Boolean.TRUE;
122         }
123         else if (stateSavingMethod.equals(STATE_SAVING_METHOD_SERVER))
124         {
125             _savingStateInClient = Boolean.FALSE;
126         }
127         else
128         {
129             _savingStateInClient = Boolean.FALSE; //Specs 10.1.3: default server saving
130             context.getExternalContext().log("Illegal state saving method '" + stateSavingMethod + "', default server state saving will be used");
131         }
132         return _savingStateInClient.booleanValue();
133     }
134 
135 
136     public class SerializedView
137     {
138         private Object _structure;
139         private Object _state;
140 
141         public SerializedView(Object structure, Object state)
142         {
143             _structure = structure;
144             _state = state;
145         }
146 
147         public Object getStructure()
148         {
149             return _structure;
150         }
151 
152         public Object getState()
153         {
154             return _state;
155         }
156     }
157 }