All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.renderkit.ResponseStateManagerImpl Maven / Gradle / Ivy

Go to download

This is the master POM file for Sun's Implementation of the JSF 1.2 Specification.

The newest version!
/*
 * $Id: ResponseStateManagerImpl.java,v 1.49.4.6 2009/09/02 23:38:39 rlubke 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 com.sun.faces.renderkit;

import com.sun.faces.RIConstants;
import com.sun.faces.config.WebConfiguration;
import com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter;
import com.sun.faces.config.WebConfiguration.WebContextInitParameter;
import com.sun.faces.config.WebConfiguration.WebEnvironmentEntry;

import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.EnableViewStateIdRendering;
import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.AutoCompleteOffOnViewState;

import com.sun.faces.io.Base64InputStream;
import com.sun.faces.io.Base64OutputStreamWriter;
import com.sun.faces.spi.SerializationProvider;
import com.sun.faces.spi.SerializationProviderFactory;
import com.sun.faces.util.Util;
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.RequestStateManager;

import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.faces.FacesException;
import javax.faces.application.StateManager;
import javax.faces.application.StateManager.SerializedView;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.ResponseStateManager;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;


/**
 * 

A ResonseStateManager implementation * for the default HTML render kit. */ public class ResponseStateManagerImpl extends ResponseStateManager { // Log instance for this class private static final Logger LOGGER = FacesLogger.RENDERKIT.getLogger(); private static final char[] STATE_FIELD_START = ("".toCharArray(); private static final char[] STATE_FIELD_AUTOCOMPLETE_END = "\" autocomplete=\"off\" />".toCharArray(); private char[] stateFieldStart; private char[] stateFieldEnd; private SerializationProvider serialProvider; private WebConfiguration webConfig; private Boolean compressState; private ByteArrayGuard guard; private int csBuffSize; public ResponseStateManagerImpl() { init(); } /** @see {@link ResponseStateManager#getComponentStateToRestore(javax.faces.context.FacesContext)} */ @Override @SuppressWarnings("deprecation") public Object getComponentStateToRestore(FacesContext context) { return RequestStateManager.get(context, RequestStateManager.FACES_VIEW_STATE); } /** @see {@link ResponseStateManager#isPostback(javax.faces.context.FacesContext)} */ @Override public boolean isPostback(FacesContext context) { return context.getExternalContext().getRequestParameterMap(). containsKey(ResponseStateManager.VIEW_STATE_PARAM); } /** @see {@link ResponseStateManager#getTreeStructureToRestore(javax.faces.context.FacesContext,String)} */ @Override @SuppressWarnings("deprecation") public Object getTreeStructureToRestore(FacesContext context, String treeId) { Object s = RequestStateManager.get(context, RequestStateManager.FACES_VIEW_STRUCTURE); if (s != null) { return s; } StateManager stateManager = Util.getStateManager(context); String viewString = getStateParam(context); if (viewString == null) { return null; } if (stateManager.isSavingStateInClient(context)) { ObjectInputStream ois = null; try { // 1. Base64 Decode InputStream bis = new Base64InputStream(viewString); // 2. If state was encrypted, decrypt it. if (guard != null) { byte[] bytes = viewString.getBytes(RIConstants.CHAR_ENCODING); int numRead = bis.read(bytes, 0, bytes.length); byte[] decodedBytes = new byte[numRead]; bis.reset(); bis.read(decodedBytes, 0, decodedBytes.length); bytes = guard.decrypt(context, decodedBytes); if (bytes == null) return null; bis = new ByteArrayInputStream(bytes); } // 3. If state was compressed, expand it. if (compressState) { bis = new GZIPInputStream(bis); } ois = serialProvider.createObjectInputStream(bis); long stateTime = 0; if (webConfig.isSet(WebContextInitParameter.ClientStateTimeout)) { try { stateTime = ois.readLong(); } catch (IOException ioe) { // we've caught an exception trying to read the time // marker. This most likely means a view that has been // around before upgrading to the release that included // this feature. So, no marker, return null now to // cause a ViewExpiredException if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Client state timeout is enabled, but unable to find the " + "time marker in the serialized state. Assuming state " + "to be old and returning null."); } return null; } } Object structure = ois.readObject(); Object state = ois.readObject(); if (stateTime != 0 && hasStateExpired(stateTime)) { // return null if state has expired. This should cause // a ViewExpiredException to be thrown return null; } storeStateInRequest(context, state); storeStructureInRequest(context, structure); return structure; } catch (java.io.OptionalDataException ode) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, ode.getMessage(), ode); } throw new FacesException(ode); } catch (java.lang.ClassNotFoundException cnfe) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, cnfe.getMessage(), cnfe); } throw new FacesException(cnfe); } catch (java.io.IOException iox) { if (LOGGER.isLoggable(Level.SEVERE)) { LOGGER.log(Level.SEVERE, iox.getMessage(), iox); } throw new FacesException(iox); } finally { if (ois != null) { try { ois.close(); } catch (IOException ioe) { // ignore } } } } else { return viewString; } } /** @see {@link ResponseStateManager#writeState(javax.faces.context.FacesContext,javax.faces.application.StateManager.SerializedView)} */ @Override @SuppressWarnings("deprecation") public void writeState(FacesContext context, SerializedView view) throws IOException { StateManager stateManager = Util.getStateManager(context); ResponseWriter writer = context.getResponseWriter(); writer.write(stateFieldStart); if (stateManager.isSavingStateInClient(context)) { ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; try { baos = new ByteArrayOutputStream(); OutputStream base; // 1. compress the state if (compressState) { base = new GZIPOutputStream(baos, 1024); } else { base = baos; } oos = serialProvider .createObjectOutputStream(new BufferedOutputStream(base)); if (webConfig.isSet(WebContextInitParameter.ClientStateTimeout)) { oos.writeLong(System.currentTimeMillis()); } //noinspection NonSerializableObjectPassedToObjectStream oos.writeObject(view.getStructure()); //noinspection NonSerializableObjectPassedToObjectStream oos.writeObject(view.getState()); oos.flush(); oos.close(); // get bytes for encrypting byte[] bytes =baos.toByteArray(); // 2. encrypt the state if (guard != null) { // this will MAC bytes = guard.encrypt(context, bytes); } // 3. Base 64 encode the state Base64OutputStreamWriter bos = new Base64OutputStreamWriter(bytes.length, writer); bos.write(bytes, 0, bytes.length); bos.finish(); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Client State: total number of characters" + " written: " + bos.getTotalCharsWritten()); } } finally { if (oos != null) { try { oos.close(); } catch (IOException ioe) { // ignore } } } } else { writer.write(view.getStructure().toString()); } writer.write(stateFieldEnd); writeRenderKitIdField(context, writer); } /** *

If the {@link WebContextInitParameter#ClientStateTimeout} init parameter * is set, calculate the elapsed time between the time the client state was * written and the time this method was invoked during restore. If the client * state has expired, return true. If the client state hasn't expired, * or the init parameter wasn't set, return false. * @param stateTime the time in milliseconds that the state was written * to the client * @return false if the client state hasn't timed out, otherwise * return true */ private boolean hasStateExpired(long stateTime) { if (webConfig.isSet(WebContextInitParameter.ClientStateTimeout)) { long elapsed = (System.currentTimeMillis() - stateTime) / 60000; int timeout = Integer.parseInt( webConfig.getOptionValue( WebContextInitParameter.ClientStateTimeout)); return (elapsed > timeout); } else { return false; } } /** *

Store the state for this request into a temporary attribute * within the same request.

* * @param context the FacesContext of the current request * @param state the view state */ private static void storeStateInRequest(FacesContext context, Object state) { // store the state object temporarily in request scope // until it is processed by getComponentStateToRestore // which resets it. RequestStateManager.set(context, RequestStateManager.FACES_VIEW_STATE, state); } private static void storeStructureInRequest(FacesContext context, Object structure) { RequestStateManager.set(context, RequestStateManager.FACES_VIEW_STRUCTURE, structure); } /** *

Write a hidden field if the default render kit ID is not * RenderKitFactory.HTML_BASIC_RENDER_KIT.

* * @param context the FacesContext for the current request * @param writer the target writer * * @throws IOException if an error occurs */ private static void writeRenderKitIdField(FacesContext context, ResponseWriter writer) throws IOException { String result = context.getApplication().getDefaultRenderKitId(); if (result != null && !RenderKitFactory.HTML_BASIC_RENDER_KIT.equals(result)) { writer.startElement("input", context.getViewRoot()); writer.writeAttribute("type", "hidden", "type"); writer.writeAttribute("name", ResponseStateManager.RENDER_KIT_ID_PARAM, "name"); writer.writeAttribute("value", result, "value"); writer.endElement("input"); } } /** *

Get our view state from this request

* * @param context the FacesContext for the current request * * @return the view state from this request */ private static String getStateParam(FacesContext context) { String pValue = context.getExternalContext().getRequestParameterMap(). get(ResponseStateManager.VIEW_STATE_PARAM); if (pValue != null && pValue.length() == 0) { pValue = null; } return pValue; } /** *

Perform the necessary intialization to make this * class work.

*/ private void init() { webConfig = WebConfiguration.getInstance(); assert(webConfig != null); // BugDB 2966897 make ClientStateSavingPassword on by default unless // it is explicitly disabled. boolean clientStateSavingPasswordDisabled = webConfig.isOptionEnabled(BooleanWebContextInitParameter.DisableClientStateEncryption); if (!clientStateSavingPasswordDisabled) { guard = new ByteArrayGuard(); } compressState = webConfig.isOptionEnabled( BooleanWebContextInitParameter.CompressViewState); String size = webConfig.getOptionValue( WebContextInitParameter.ClientStateWriteBufferSize); String defaultSize = WebContextInitParameter.ClientStateWriteBufferSize.getDefaultValue(); try { csBuffSize = Integer.parseInt(size); if (csBuffSize % 2 != 0) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "jsf.renderkit.resstatemgr.clientbuf_div_two", new Object[] { WebContextInitParameter.ClientStateWriteBufferSize.getQualifiedName(), size, defaultSize}); } csBuffSize = Integer.parseInt(defaultSize); } else { csBuffSize /= 2; if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Using client state buffer size of " + csBuffSize); } } } catch (NumberFormatException nfe) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, "jsf.renderkit.resstatemgr.clientbuf_not_integer", new Object[] { WebContextInitParameter.ClientStateWriteBufferSize.getQualifiedName(), size, defaultSize}); } csBuffSize = Integer.parseInt(defaultSize); } stateFieldStart = (webConfig.isOptionEnabled(EnableViewStateIdRendering) ? STATE_FIELD_START : STATE_FIELD_START_NO_ID); stateFieldEnd = (webConfig.isOptionEnabled(AutoCompleteOffOnViewState) ? STATE_FIELD_AUTOCOMPLETE_END : STATE_FIELD_END); if (serialProvider == null) { serialProvider = SerializationProviderFactory .createInstance(FacesContext.getCurrentInstance().getExternalContext()); } } } // end of class ResponseStateManagerImpl




© 2015 - 2024 Weber Informatics LLC | Privacy Policy