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 }