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 }