javax.faces.render.ResponseStateManager Maven / Gradle / Ivy
/*
* $Id: ResponseStateManager.java,v 1.30 2007/04/27 22:00:10 ofung Exp $
*/
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.faces.render;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.application.StateManager;
import javax.faces.application.StateManager.SerializedView;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* ResponseStateManager is the helper class to
* {@link javax.faces.application.StateManager} that knows the specific
* rendering technology being used to generate the response. It is a
* singleton abstract class, vended by the {@link RenderKit}. This
* class knows the mechanics of saving state, whether it be in hidden
* fields, session, or some combination of the two.
*/
public abstract class ResponseStateManager {
private static Logger log = Logger.getLogger("javax.faces.render");
/**
* The name of the request parameter used by the default
* implementation of {@link
* javax.faces.application.ViewHandler#calculateRenderKitId} to
* derive a RenderKit ID.
*/
public static final String RENDER_KIT_ID_PARAM =
"javax.faces.RenderKitId";
/**
* Implementations must use this value as the name and id of the client
* parameter in which to save the state between requests.
*
* @since 1.2
*/
public static final String VIEW_STATE_PARAM = "javax.faces.ViewState";
/*
* Take the argument state
and write it into the
* output using the current {@link ResponseWriter}, which must be
* correctly positioned already.
*
* If the state is to be written out to hidden fields, the
* implementation must take care to make all necessary character
* replacements to make the Strings suitable for inclusion as an
* HTTP request paramater.
*
* If the state saving method for this application is {@link
* javax.faces.application.StateManager#STATE_SAVING_METHOD_CLIENT},
* the implementation may encrypt the state to be saved to the
* client. We recommend that the state be unreadable by the client,
* and also be tamper evident. The reference implementation follows
* these recommendations.
*
* Write out the render kit identifier associated with this
* ResponseStateManager
implementation with the name
* as the value of the String
constant
* ResponseStateManager.RENDER_KIT_ID_PARAM
. The
* render kit identifier must not be written if:
*
* - it is the default render kit identifier as returned by
* {@link Application#getDefaultRenderKitId()} or
* - the render kit identfier is the value of
*
RenderKitFactory.HTML_BASIC_RENDER_KIT
and
* {@link Application.getDefaultRenderKitId()} returns null
.
*
*
*
* For backwards compatability with existing
* ResponseStateManager
implementations, the default
* implementation of this method checks if the argument is an
* instance of SerializedView
. If so, it calls through
* to {@link
* #writeState(javax.faces.context.FacesContext,javax.faces.application.StateManager.SerializedView}.
* If not, it expects the state to be a two element Object array. It creates
* an instance of SerializedView
and
* stores the state as the treeStructure, and passes it to {@link
* #writeState(javax.faces.context.FacesContext,javax.faces.application.StateManager.SerializedView}.
*
*
* @since 1.2
*
* @param context The {@link FacesContext} instance for the current request
* @param state The serialized state information previously saved
* @throws IOException if the state argument is not an array of length 2.
*
*/
public void writeState(FacesContext context,
Object state) throws IOException {
SerializedView view;
if (state instanceof SerializedView) {
view = (SerializedView) state;
}
else {
if (state instanceof Object[]) {
Object[] stateArray = (Object[])state;
if (2 == stateArray.length) {
StateManager stateManager =
context.getApplication().getStateManager();
view = stateManager.new SerializedView(stateArray[0],
stateArray[1]);
} else {
//PENDING - I18N
if (log.isLoggable(Level.SEVERE)) {
log.log(Level.SEVERE, "State is not an expected array of length 2.");
}
throw new IOException("State is not an expected array of length 2.");
}
} else {
//PENDING - I18N
if (log.isLoggable(Level.SEVERE)) {
log.log(Level.SEVERE, "State is not an expected array of length 2.");
}
throw new IOException("State is not an expected array of length 2.");
}
}
writeState(context, view);
}
/**
* Take the argument state
and write it into
* the output using the current {@link ResponseWriter}, which
* must be correctly positioned already.
*
* If the {@link
* javax.faces.application.StateManager.SerializedView} is to be
* written out to hidden fields, the implementation must take care
* to make all necessary character replacements to make the Strings
* suitable for inclusion as an HTTP request paramater.
*
* If the state saving method for this application is {@link
* javax.faces.application.StateManager#STATE_SAVING_METHOD_CLIENT},
* the implementation may encrypt the state to be saved to the
* client. We recommend that the state be unreadable by the client,
* and also be tamper evident. The reference implementation follows
* these recommendations.
*
* @deprecated This method has been replaced by {@link
* #writeState(javax.faces.context.FacesContext,java.lang.Object)}.
* The default implementation of this method does nothing.
*
* @param context The {@link FacesContext} instance for the current request
* @param state The serialized state information previously saved
*
*/
public void writeState(FacesContext context,
SerializedView state) throws IOException {
}
/**
* The implementation must inspect the current request and return
* an Object representing the tree structure and component state
* passed in to a previous invocation of {@link
* #writeState(javax.faces.context.FacesContext,java.lang.Object)}.
*
* For backwards compatability with existing
* ResponseStateManager
implementations, the default
* implementation of this method calls {@link
* #getTreeStructureToRestore} and {@link
* #getComponentStateToRestore} and creates and returns a two
* element Object
array with element zero containing
* the structure
property and element one containing
* the state
property of the
* SerializedView
.
*
* @since 1.2
*
* @param context The {@link FacesContext} instance for the current request
* @param viewId View identifier of the view to be restored
*
* @return the tree structure and component state Object passed in
* to writeState
. If this is an initial request, this
* method returns null
.
*/
public Object getState(FacesContext context, String viewId) {
Object stateArray[] = { getTreeStructureToRestore(context, viewId),
getComponentStateToRestore(context) };
return stateArray;
}
/**
* The implementation must inspect the current request and return
* the tree structure Object passed to it on a previous invocation of
* writeState()
.
*
* @deprecated This method has been replaced by {@link #getState}.
* The default implementation returns null
.
*
* @param context The {@link FacesContext} instance for the current request
* @param viewId View identifier of the view to be restored
*
*/
public Object getTreeStructureToRestore(FacesContext context,
String viewId) {
return null;
}
/**
* The implementation must inspect the current request and return
* the component state Object passed to it on a previous invocation
* of writeState()
.
*
* @deprecated This method has been replaced by {@link #getState}.
* The default implementation returns null
.
*
* @param context The {@link FacesContext} instance for the current request
*
*/
public Object getComponentStateToRestore(FacesContext context) {
return null;
}
/**
* Return true if the current request is a postback. This method
* is leveraged from the Restore View Phase to determine if
* {@link javax.faces.application.ViewHandler#restoreView} or {@link
* javax.faces.application.ViewHandler#createView} should be called.
* The default implementation must return true
if this
* ResponseStateManager
instance wrote out state on a
* previous request to which this request is a postback,
* false
otherwise.
*
* The implementation if this method for the Standard HTML
* RenderKit must consult the {@link
* javax.faces.context.ExternalContext}'s
* requestParameterMap
and return true
if
* and only if there is a key equal to the value of the symbolic
* constant {@link #VIEW_STATE_PARAM}.
*
* For backwards compatability with implementations of
* ResponseStateManager
prior to JSF 1.2, a default
* implementation is provided that consults the {@link
* javax.faces.context.ExternalContext}'s requestParameterMap
and return
* true
if its size is greater than 0.
*
* @since 1.2
*/
public boolean isPostback(FacesContext context) {
return (!context.getExternalContext().getRequestParameterMap().isEmpty());
}
}