/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2010 Oracle and/or its affiliates. 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.java.net/public/CDDL+GPL_1_1.html
* or packager/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 packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [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.systest.render;
import javax.faces.application.StateManager;
import javax.faces.application.StateManager.SerializedView;
import javax.faces.context.FacesContext;
import javax.faces.render.ResponseStateManager;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import com.sun.faces.util.Util;
/**
* <B>RenderKitImpl</B> is a class ...
*/
public class CustomResponseStateManagerImpl extends ResponseStateManager {
//
// Protected Constants
//
private static final String FACES_VIEW_STATE =
"com.sun.faces.FACES_VIEW_STATE";
private static final String COMPRESS_STATE_PARAM =
"com.sun.faces.COMPRESS_STATE";
//
// Class Variables
//
//
// Instance Variables
//
private Boolean compressStateSet = null;
//
// Ivars used during actual client lifetime
//
// Relationship Instance Variables
//
// Constructors and Initializers
//
public CustomResponseStateManagerImpl() {
super();
}
//
// Class methods
//
//
// General Methods
//
//
// Methods From ResponseStateManager
//
public Object getState(FacesContext context, String viewId) {
Object stateArray[] = { getTreeStructure(context, viewId),
getComponentState(context) };
return stateArray;
}
public boolean isPostback(FacesContext context) {
boolean result = context.getExternalContext().getRequestParameterMap().
containsKey(javax.faces.render.ResponseStateManager.VIEW_STATE_PARAM);
return result;
}
private Object getComponentState(FacesContext context) {
// requestMap is a local variable so we don't need to synchronize
Map requestMap = context.getExternalContext().getRequestMap();
Object state = requestMap.get(FACES_VIEW_STATE);
// null out the temporary attribute, since we don't need it anymore.
requestMap.remove(FACES_VIEW_STATE);
return state;
}
private Object getTreeStructure(FacesContext context,
String treeId) {
StateManager stateManager = Util.getStateManager(context);
Map requestParamMap = context.getExternalContext()
.getRequestParameterMap();
String viewString = (String) requestParamMap.get(
javax.faces.render.ResponseStateManager.VIEW_STATE_PARAM);
Object structure = null;
if (viewString == null) {
return null;
}
if (stateManager.isSavingStateInClient(context)) {
Object state = null;
ByteArrayInputStream bis = null;
GZIPInputStream gis = null;
ObjectInputStream ois = null;
boolean compress = isCompressStateSet(context);
try {
byte[] bytes = Base64.decode(viewString.getBytes());
bis = new ByteArrayInputStream(bytes);
if (isCompressStateSet(context)) {
gis = new GZIPInputStream(bis);
ois = new ObjectInputStream(gis);
} else {
ois = new ObjectInputStream(bis);
}
structure = ois.readObject();
state = ois.readObject();
Map requestMap = context.getExternalContext().getRequestMap();
// store the state object temporarily in request scope
// until it is processed by getComponentStateToRestore
// which resets it.
requestMap.put(FACES_VIEW_STATE, state);
bis.close();
if ( compress) {
gis.close();
}
ois.close();
} catch (java.io.OptionalDataException ode) {
} catch (java.lang.ClassNotFoundException cnfe) {
} catch (java.io.IOException iox) {
}
}
else {
structure = viewString;
}
return structure;
}
public void writeState(FacesContext context,
Object state) throws IOException {
SerializedView view = null;
if (state instanceof SerializedView) {
view = (SerializedView) state;
}
else {
Object[] stateArray = (Object[])state;
StateManager stateManager =
context.getApplication().getStateManager();
view = stateManager.new SerializedView(stateArray[0], null);
}
writeSerializedState(context, view);
}
private void writeSerializedState(FacesContext context, SerializedView view)
throws IOException {
String hiddenField = null;
StateManager stateManager = Util.getStateManager(context);
if (stateManager.isSavingStateInClient(context)) {
GZIPOutputStream zos = null;
ObjectOutputStream oos = null;
boolean compress = isCompressStateSet(context);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
if (compress) {
zos = new GZIPOutputStream(bos);
oos = new ObjectOutputStream(zos);
} else {
oos = new ObjectOutputStream(bos);
}
oos.writeObject(view.getStructure());
oos.writeObject(view.getState());
oos.close();
if (compress) {
zos.close();
}
byte[] securedata = bos.toByteArray();
bos.close();
hiddenField = " <input type=\"hidden\" name=\""
+ javax.faces.render.ResponseStateManager.VIEW_STATE_PARAM + "\"" + " value=\"" +
(new String(Base64.encode(securedata), "ISO-8859-1"))
+ "\" />\n ";
}
else {
hiddenField = " <input type=\"hidden\" name=\""
+ javax.faces.render.ResponseStateManager.VIEW_STATE_PARAM + "\"" + " value=\"" +
view.getStructure() +
"\" />\n ";
}
context.getResponseWriter().write(hiddenField);
// write this out regardless of state saving mode
// Only write it out if there is a default specified, and
// this render kit identifier is not the default.
String result = context.getApplication().getDefaultRenderKitId();
if ((null != result && !result.equals("CUSTOM")) || result == null) {
hiddenField = " <input type=\"hidden\" name=\""
+ ResponseStateManager.RENDER_KIT_ID_PARAM + "\"" + " value=\"CUSTOM\"" +
"\" />\n ";
context.getResponseWriter().write(hiddenField);
}
}
private boolean isCompressStateSet(FacesContext context) {
if (null != compressStateSet) {
return compressStateSet.booleanValue();
}
compressStateSet = Boolean.TRUE;
String compressStateParam = context.getExternalContext().
getInitParameter(COMPRESS_STATE_PARAM);
if (compressStateParam != null){
compressStateSet = Boolean.valueOf(compressStateParam);
}
return compressStateSet.booleanValue();
}
} // end of class CustomResponseStateManagerImpl