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  import javax.faces.context.FacesContext;
22  
23  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
24  
25  import java.io.IOException;
26  
27  
28  /**
29   * Responsible for storing sufficient information about a component tree so that an identical tree
30   * can later be recreated.
31   * <p>
32   * It is up to the concrete implementation to decide whether to use information from the "view template"
33   * that was used to first create the view, or whether to store sufficient information to enable the
34   * view to be restored without any reference to the original template. However as JSF components have
35   * mutable fields that can be set by code, and affected by user input, at least some state does need
36   * to be kept in order to recreate a previously-existing component tree.
37   * <p>
38   * There are two different options defined by the specification: "client" and "server" state.
39   * <p>
40   * When "client" state is configured, all state information required to create the tree is embedded within
41   * the data rendered to the client. Note that because data received from a remote client must always be
42   * treated as "tainted", care must be taken when using such data. Some StateManager implementations may
43   * use encryption to ensure that clients cannot modify the data, and that the data received on postback
44   * is therefore trustworthy.
45   * <p>
46   * When "server" state is configured, the data is saved somewhere "on the back end", and (at most) a
47   * token is embedded in the data rendered to the user.
48   * <p>
49   * This class is usually invoked by a concrete implementation of ViewHandler.
50   * <p>
51   * Note that class ViewHandler isolates JSF components from the details of the request format. This class
52   * isolates JSF components from the details of the response format. Because request and response are usually
53   * tightly coupled, the StateManager and ViewHandler implementations are also usually fairly tightly coupled
54   * (ie the ViewHandler/StateManager implementations come as pairs).
55   * <p>
56   * See also the <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
57   *
58   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
59   * @author Stan Silvert
60   * @version $Revision: 833810 $ $Date: 2009-11-07 21:40:01 -0500 (Sat, 07 Nov 2009) $
61   */
62  public abstract class StateManager
63  {
64      /**
65       * Define the state method to be used. There are two different options defined by the 
66       * specification: "client" and "server" state.
67       * <p>
68       * When "client" state is configured, all state information required to create the tree is embedded within
69       * the data rendered to the client. Note that because data received from a remote client must always be
70       * treated as "tainted", care must be taken when using such data. Some StateManager implementations may
71       * use encryption to ensure that clients cannot modify the data, and that the data received on postback
72       * is therefore trustworthy.
73       * </p>
74       * <p>
75       * When "server" state is configured, the data is saved somewhere "on the back end", and (at most) a
76       * token is embedded in the data rendered to the user.
77       * </p>
78       */
79      @JSFWebConfigParam(defaultValue="server", expectedValues="server,client", since="1.1")
80      public static final String STATE_SAVING_METHOD_PARAM_NAME = "javax.faces.STATE_SAVING_METHOD";
81      public static final String STATE_SAVING_METHOD_CLIENT = "client";
82      public static final String STATE_SAVING_METHOD_SERVER = "server";
83      private Boolean _savingStateInClient = null;
84      
85      /**
86       * Invokes getTreeStructureToSave and getComponentStateToSave, then return an object that wraps the two
87       * resulting objects. This object can then be passed to method writeState.
88       * <p>
89       * Deprecated; use saveView instead.
90       * 
91       * @deprecated
92       */
93      public StateManager.SerializedView saveSerializedView(javax.faces.context.FacesContext context) {
94          return null;
95      }
96      
97      /**
98       * Returns an object that is sufficient to recreate the component tree that is the viewroot of
99       * the specified context.
100      * <p>
101      * The return value is suitable for passing to method writeState.
102      * 
103      * @since 1.2
104      */
105     public Object saveView(FacesContext context) {
106         StateManager.SerializedView serializedView = saveSerializedView(context);
107         if (serializedView == null) return null;
108         
109         Object[] structureAndState = new Object[2];
110         structureAndState[0] = serializedView.getStructure();
111         structureAndState[1] = serializedView.getState();
112         
113         return structureAndState;
114     }
115     
116     /**
117      * Return data that is sufficient to recreate the component tree that is the viewroot of the specified
118      * context, but without restoring the state in the components.
119      * <p>
120      * Using this data, a tree of components which has the same "shape" as the original component
121      * tree can be recreated. However the component instances themselves will have only their default
122      * values, ie their member fields will not have been set to the original values.
123      * <p>
124      * Deprecated; use saveView instead.
125      * 
126      * @deprecated
127      */
128     protected Object getTreeStructureToSave(javax.faces.context.FacesContext context) {
129         return null;
130     }
131 
132     /**
133      * Return data that can be applied to a component tree created using the "getTreeStructureToSave"
134      * method.
135      * <p>
136      * Deprecated; use saveView instead.
137      * 
138      * @deprecated
139      */
140     protected Object getComponentStateToSave(javax.faces.context.FacesContext context) {
141         return null;
142     }
143 
144     /**
145      * Associate the provided state object with the current response being generated.
146      * <p>
147      * When client-side state is enabled, it is expected that method writes the data contained in the
148      * state parameter to the response somehow.
149      * <p>
150      * When server-side state is enabled, at most a "token" is expected to be written.
151      * <p>
152      * Deprecated; use writeState(FacesContext, Object) instead. This method was abstract
153      * in JSF1.1, but is now an empty non-abstract method so that old classes that implement
154      * this method continue to work, while new classes can just override the new writeState
155      * method rather than this one.
156      * 
157      * @deprecated
158      */
159     public void writeState(javax.faces.context.FacesContext context,
160                                     StateManager.SerializedView state)
161             throws java.io.IOException {
162         // default impl does nothing as per JSF 1.2 javadoc
163     }
164     
165     /**
166      * Associate the provided state object with the current response being generated.
167      * <p>
168      * When client-side state is enabled, it is expected that method writes the data contained in the
169      * state parameter to the response somehow.
170      * <p>
171      * When server-side state is enabled, at most a "token" is expected to be written.
172      * <p>
173      * This method should be overridden by subclasses. It is not abstract because a default
174      * implementation is provided that forwards to the old writeState method; this allows
175      * subclasses of StateManager written using the JSF1.1 API to continue to work.
176      * <p>
177      * @since 1.2
178      */
179     public void writeState(FacesContext context, Object state) throws IOException {
180         if (!(state instanceof Object[])) return;
181         Object[] structureAndState = (Object[])state;
182         if (structureAndState.length < 2) return;
183         
184         writeState(context, new StateManager.SerializedView(structureAndState[0], structureAndState[1]));
185     }
186 
187     public abstract javax.faces.component.UIViewRoot restoreView(javax.faces.context.FacesContext context,
188                                                                  String viewId,
189                                                                  String renderKitId);
190 
191     /**
192      * @deprecated
193      */
194     protected javax.faces.component.UIViewRoot restoreTreeStructure(javax.faces.context.FacesContext context,
195                                                                     String viewId,
196                                                                     String renderKitId) {
197         return null;
198     }
199 
200     /**
201      * @deprecated
202      */
203     protected void restoreComponentState(javax.faces.context.FacesContext context,
204                                          javax.faces.component.UIViewRoot viewRoot,
205                                          String renderKitId) {
206         // default impl does nothing as per JSF 1.2 javadoc
207     }
208 
209     public boolean isSavingStateInClient(javax.faces.context.FacesContext context)
210     {
211         if(context == null) throw new NullPointerException("context");
212         if (_savingStateInClient != null) return _savingStateInClient.booleanValue();
213         String stateSavingMethod = context.getExternalContext().getInitParameter(STATE_SAVING_METHOD_PARAM_NAME);
214         if (stateSavingMethod == null)
215         {
216             _savingStateInClient = Boolean.FALSE; //Specs 10.1.3: default server saving
217             context.getExternalContext().log("No state saving method defined, assuming default server state saving");
218         }
219         else if (stateSavingMethod.equals(STATE_SAVING_METHOD_CLIENT))
220         {
221             _savingStateInClient = Boolean.TRUE;
222         }
223         else if (stateSavingMethod.equals(STATE_SAVING_METHOD_SERVER))
224         {
225             _savingStateInClient = Boolean.FALSE;
226         }
227         else
228         {
229             _savingStateInClient = Boolean.FALSE; //Specs 10.1.3: default server saving
230             context.getExternalContext().log("Illegal state saving method '" + stateSavingMethod + "', default server state saving will be used");
231         }
232         return _savingStateInClient.booleanValue();
233     }
234 
235 
236     /**
237      * @deprecated
238      */
239     public class SerializedView 
240     {
241         private Object _structure;
242         private Object _state;
243 
244         /**
245          * @deprecated
246          */
247         public SerializedView(Object structure, Object state)
248         {
249             _structure = structure;
250             _state = state;
251         }
252 
253         /**
254          * @deprecated
255          */
256         public Object getStructure()
257         {
258             return _structure;
259         }
260 
261         /**
262          * @deprecated
263          */
264         public Object getState()
265         {
266             return _state;
267         }
268     }
269 }