You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gc...@apache.org on 2010/03/18 23:22:01 UTC
svn commit: r925024 - in /myfaces/trinidad/branches/1.2.12.2-branch:
trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/
trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/
trinidad-impl/src/main/java/org/apache/my...
Author: gcrawford
Date: Thu Mar 18 22:22:01 2010
New Revision: 925024
URL: http://svn.apache.org/viewvc?rev=925024&view=rev
Log:
TRINIDAD-1747 zip page state to reduce live memory
Added:
myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ObjectInputStreamResolveClass.java
Modified:
myfaces/trinidad/branches/1.2.12.2-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java
myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
Modified: myfaces/trinidad/branches/1.2.12.2-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.2-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts?rev=925024&r1=925023&r2=925024&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.2-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/branches/1.2.12.2-branch/trinidad-api/src/main/xrts/org/apache/myfaces/trinidad/resource/LoggerBundle.xrts Thu Mar 18 22:22:01 2010
@@ -453,4 +453,11 @@
<!-- COMPARETO_TYPE_MISMATCH -->
<resource key="COMPARETO_TYPE_MISMATCH">The type for "{0}" prevents it from being compared to "{1}".</resource>
+<!-- ZIP_STATE_FAILED -->
+<resource key="ZIP_STATE_FAILED">Failed to zip the page state.</resource>
+
+<!-- UNZIP_STATE_FAILED -->
+<resource key="UNZIP_STATE_FAILED">Failed to unzip the page state.</resource>
+
+
</resources>
Modified: myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java?rev=925024&r1=925023&r2=925024&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java (original)
+++ myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java Thu Mar 18 22:22:01 2010
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -18,14 +18,24 @@
*/
package org.apache.myfaces.trinidadinternal.application;
+import com.sun.facelets.FaceletViewHandler;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.Serializable;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.zip.DataFormatException;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
import javax.faces.FactoryFinder;
import javax.faces.application.StateManager;
@@ -38,23 +48,20 @@ import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.ResponseStateManager;
+import org.apache.myfaces.trinidad.bean.util.StateUtils;
import org.apache.myfaces.trinidad.component.UIXComponentBase;
import org.apache.myfaces.trinidad.context.RequestContext;
+import org.apache.myfaces.trinidad.context.Window;
import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidad.util.ExternalContextUtils;
+import org.apache.myfaces.trinidad.util.TransientHolder;
+import org.apache.myfaces.trinidadinternal.context.RequestContextImpl;
+import org.apache.myfaces.trinidadinternal.context.TrinidadPhaseListener;
import org.apache.myfaces.trinidadinternal.util.LRUCache;
+import org.apache.myfaces.trinidadinternal.util.ObjectInputStreamResolveClass;
import org.apache.myfaces.trinidadinternal.util.SubKeyMap;
import org.apache.myfaces.trinidadinternal.util.TokenCache;
-import com.sun.facelets.FaceletViewHandler;
-
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectOutputStream;
-
-import org.apache.myfaces.trinidad.bean.util.StateUtils;
-import org.apache.myfaces.trinidad.context.Window;
-import org.apache.myfaces.trinidadinternal.context.RequestContextImpl;
-import org.apache.myfaces.trinidadinternal.context.TrinidadPhaseListener;
/**
* StateManager that handles a hybrid client/server strategy: a
@@ -114,6 +121,15 @@ public class StateManagerImpl extends St
"org.apache.myfaces.trinidad.CLIENT_STATE_MAX_TOKENS";
/**
+ * Servlet context initialization parameter used by
+ * StateManagerImpl to decide whether to zip state.
+ * Valid values are true and false
+ */
+ static public final String COMPRESS_VIEW_STATE_PARAM_NAME =
+ "org.apache.myfaces.trinidadinternal.COMPRESS_VIEW_STATE";
+
+
+ /**
* Value indicating that only a simple token will be stored
* on the client.
*/
@@ -130,7 +146,7 @@ public class StateManagerImpl extends St
{
_delegate = delegate;
}
-
+
@Override
protected StateManager getWrapped()
{
@@ -142,13 +158,13 @@ public class StateManagerImpl extends St
public Object saveView(FacesContext context)
{
assert(context != null);
-
+
if(isSavingStateInClient(context))
{
SerializedView view = _saveSerializedView(context);
return new Object[]{view.getStructure(), view.getState()};
}
-
+
return super.saveView(context);
}
@@ -156,12 +172,12 @@ public class StateManagerImpl extends St
public SerializedView saveSerializedView(FacesContext context)
{
assert(context != null);
-
+
if(isSavingStateInClient(context))
{
return _saveSerializedView(context);
}
-
+
return _delegate.saveSerializedView(context);
}
@@ -177,7 +193,7 @@ public class StateManagerImpl extends St
Object state = component.processSaveState(context);
return new PageState(context, structure, state, null);
}
-
+
/**
* Take an object created by saveComponentTree()
* and instantiate it as a UIComponent.
@@ -253,7 +269,7 @@ public class StateManagerImpl extends St
root.processRestoreState(context, state);
return root;
- }
+ }
@SuppressWarnings({"unchecked", "deprecation"})
private SerializedView _saveSerializedView(FacesContext context)
@@ -314,10 +330,10 @@ public class StateManagerImpl extends St
Map<String, Object> sessionMap = extContext.getSessionMap();
RequestContext trinContext = RequestContext.getCurrentInstance();
-
+
// get view cache key with "." separator suffix to separate the SubKeyMap keys
String subkey = _getViewCacheKey(extContext, trinContext, _SUBKEY_SEPARATOR);
-
+
Map<String, PageState> stateMap = new SubKeyMap<PageState>(sessionMap, subkey);
// Sadly, we can't save just a SerializedView, because we should
@@ -345,7 +361,7 @@ public class StateManagerImpl extends St
sessionMap.put(activePageStateKey, pageState);
}
-
+
String requestToken = _getRequestTokenForResponse(context);
// If we have a cached token that we want to reuse,
// and that token hasn't disappeared from the cache already
@@ -378,7 +394,7 @@ public class StateManagerImpl extends St
{
// use null viewRoot since this state is shared across users:
PageState applicationState = new PageState(context, structure, state, null);
-
+
// If we need to, stash the state off in our cache
if (!dontSave)
{
@@ -399,7 +415,7 @@ public class StateManagerImpl extends St
// Create a "tokenView" which abuses SerializedView to store
// our token only
view = new SerializedView(token, null);
-
+
// And store the token for this request
extContext.getRequestMap().put(_REQUEST_STATE_TOKEN_KEY, token);
}
@@ -425,9 +441,9 @@ public class StateManagerImpl extends St
{
context.getExternalContext().getRequestMap().put(
_PINNED_STATE_TOKEN_KEY, stateToken);
-
+
}
-
+
/**
* @return the state token for the current request
*/
@@ -436,24 +452,24 @@ public class StateManagerImpl extends St
return (String) context.getExternalContext().getRequestMap().get(
_REQUEST_STATE_TOKEN_KEY);
}
-
-
+
+
/**
* Mark the the incoming request token should be used for the response
*/
@SuppressWarnings("unchecked")
static public void reuseRequestTokenForResponse(ExternalContext ec)
{
- ec.getRequestMap().put(_REUSE_REQUEST_TOKEN_FOR_RESPONSE_KEY, Boolean.TRUE);
+ ec.getRequestMap().put(_REUSE_REQUEST_TOKEN_FOR_RESPONSE_KEY, Boolean.TRUE);
}
-
+
/**
* Clears the flag indicating that the old request token should be used for the response.
*/
@SuppressWarnings("unchecked")
static public void clearReuseRequestTokenForResponse(ExternalContext ec)
{
- ec.getRequestMap().remove(_REUSE_REQUEST_TOKEN_FOR_RESPONSE_KEY);
+ ec.getRequestMap().remove(_REUSE_REQUEST_TOKEN_FOR_RESPONSE_KEY);
}
/**
@@ -489,8 +505,8 @@ public class StateManagerImpl extends St
return (String) token;
}
-
-
+
+
@Override @SuppressWarnings("deprecation")
public void writeState(FacesContext context,
SerializedView state) throws IOException
@@ -504,8 +520,8 @@ public class StateManagerImpl extends St
String renderKitId)
{
final ExternalContext extContext = context.getExternalContext();
-
- // If we're being asked to execute a "return" event from, say, a dialog, always
+
+ // If we're being asked to execute a "return" event from, say, a dialog, always
// restore the "launch view", which was set over in the TrinidadFilter.
UIViewRoot launchView = (UIViewRoot)
extContext.getRequestMap().remove(RequestContextImpl.LAUNCH_VIEW);
@@ -514,7 +530,7 @@ public class StateManagerImpl extends St
TrinidadPhaseListener.markPostback(context);
return launchView;
}
-
+
if (!isSavingStateInClient(context))
return _delegate.restoreView(context, viewId, renderKitId);
@@ -559,10 +575,10 @@ public class StateManagerImpl extends St
if (viewState != null)
perSessionCache.put(viewId, viewState);
}
-
+
// If the view was found in the application cache then we
// know it would be unsafe to use its locale for this session.
- // Same conclusion, however, even if found in the per-session
+ // Same conclusion, however, even if found in the per-session
// cache, since the latter is just a mirror of the former.
recalculateLocale = true;
}
@@ -573,7 +589,7 @@ public class StateManagerImpl extends St
String subkey = _getViewCacheKey(extContext,
RequestContext.getCurrentInstance(),
_SUBKEY_SEPARATOR);
-
+
Map<String, PageState> stateMap = new SubKeyMap<PageState>(
extContext.getSessionMap(),
subkey);
@@ -649,7 +665,7 @@ public class StateManagerImpl extends St
if (state != null)
root.processRestoreState(context, state);
-
+
if (recalculateLocale)
{
// Ensure that locale gets re-calculated when next fetched.
@@ -716,7 +732,7 @@ public class StateManagerImpl extends St
private TokenCache _getViewCache(FacesContext context)
{
ExternalContext extContext = context.getExternalContext();
-
+
return TokenCache.getTokenCacheFromSession(context,
_getViewCacheKey(extContext,
RequestContext.getCurrentInstance(),
@@ -725,7 +741,7 @@ public class StateManagerImpl extends St
_getCacheSize(extContext));
}
-
+
/**
* Returns a key suitable for finding the per-window active page state key
@@ -739,7 +755,7 @@ public class StateManagerImpl extends St
{
return _getPerWindowCacheKey(extContext, trinContext, _ACTIVE_PAGE_STATE_SESSION_KEY, null);
}
-
+
/**
* Returns a key suitable for finding the per-window cache key
* @param extContext
@@ -754,7 +770,7 @@ public class StateManagerImpl extends St
{
return _getPerWindowCacheKey(extContext, trinContext, _VIEW_CACHE_KEY, suffix);
}
-
+
/**
* Returns a key of the form <prefix>.<windowid><suffix> if a window and a suffix are available
* <prefix>.<window> if just a window is available
@@ -772,18 +788,18 @@ public class StateManagerImpl extends St
Character suffix)
{
Window currWindow = trinContext.getWindowManager().getCurrentWindow(eContext);
-
+
// if we have a current window or a suffix, we need a StringBuilder to calculate the cache key
if ((currWindow != null) || (suffix != null))
{
// get the window id and the extra size neeeded to store it and its separator
String windowId;
int windowPartSize;
-
+
if (currWindow != null)
{
windowId = currWindow.getId();
-
+
// add 1 for separator
windowPartSize = windowId.length() + 1;
}
@@ -792,28 +808,28 @@ public class StateManagerImpl extends St
windowId = null;
windowPartSize = 0;
}
-
+
int builderSize = prefix.length() + windowPartSize;
-
+
// add extra space for the suffix Character
if (suffix != null)
builderSize += 1;
-
+
// add the constant part to the StringBuilder
StringBuilder keyBuilder = new StringBuilder(builderSize);
keyBuilder.append(prefix);
-
+
// add the windowId and its separator
if (currWindow != null)
{
keyBuilder.append('.');
keyBuilder.append(windowId);
}
-
+
// add the suffix if any
if (suffix != null)
keyBuilder.append(suffix);
-
+
return keyBuilder.toString();
}
else
@@ -880,7 +896,7 @@ public class StateManagerImpl extends St
return cache;
}
}
-
+
@SuppressWarnings("unchecked")
static private Map<String, PageState> _getPerSessionApplicationViewCache(FacesContext context)
{
@@ -943,7 +959,7 @@ public class StateManagerImpl extends St
}
if (Boolean.TRUE.equals(_useApplicationViewCache))
{
- _LOG.severe("USE_APPLICATION_VIEW_CACHE_UNSUPPORTED");
+ _LOG.severe("USE_APPLICATION_VIEW_CACHE_UNSUPPORTED");
}
return _useApplicationViewCache.booleanValue();
}
@@ -1016,18 +1032,18 @@ public class StateManagerImpl extends St
// Nope, guess it's a facet
// 2006-08-02: -= Simon Lessard
// Not 1.5 structure and inefficient loop
- // values() is more efficient as you don't have
+ // values() is more efficient as you don't have
// to do a second lookup for the value.
Map<String, UIComponent> facets = parent.getFacets();
- for(Iterator<UIComponent> facetIter = facets.values().iterator();
+ for(Iterator<UIComponent> facetIter = facets.values().iterator();
facetIter.hasNext();)
{
if(facetIter.next() == kid)
{
facetIter.remove();
// FIXME: -= Simon Lessard
- // Is that continue need to labeled to go all the way up to
- // the first while? Currently it won't cause any problem, but
+ // Is that continue need to labeled to go all the way up to
+ // the first while? Currently it won't cause any problem, but
// it's a performance loss.
continue;
}
@@ -1083,11 +1099,11 @@ public class StateManagerImpl extends St
{
if (viewRoot == null)
throw new NullPointerException();
-
+
_viewRoot = viewRoot;
_viewRootState = viewRoot.saveState(context);
}
-
+
public UIViewRoot getViewRoot()
{
return _viewRoot;
@@ -1097,7 +1113,7 @@ public class StateManagerImpl extends St
{
return _viewRootState;
}
-
+
private final UIViewRoot _viewRoot;
private final Object _viewRootState;
}
@@ -1106,8 +1122,8 @@ public class StateManagerImpl extends St
{
private static final long serialVersionUID = 1L;
- private final Object _structure, _state;
-
+ private Object _structure, _state;
+
// use transient since UIViewRoots are not Serializable.
private transient ViewRootState _cachedState;
@@ -1115,22 +1131,33 @@ public class StateManagerImpl extends St
{
_structure = structure;
_state = state;
-
- // if component tree serialization checking is on (in order to validate
- // fail over support, attempt to Serialize all of the component state
- // immediately
- if (StateUtils.checkComponentTreeStateSerialization(fc))
+
+ boolean zipState = _zipState(fc);
+
+ if (zipState || StateUtils.checkComponentTreeStateSerialization(fc))
{
- try
+
+ if (zipState)
{
- new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(state);
+ // zip the page state. This will also catch any serialization problems.
+ _zipToBytes(state, structure);
}
- catch (IOException e)
- {
- throw new RuntimeException(_LOG.getMessage("COMPONENT_TREE_SERIALIZATION_FAILED"), e);
+ else
+ {
+ // if component tree serialization checking is on (in order to validate
+ // fail over support, attempt to Serialize all of the component state
+ // immediately
+ try
+ {
+ new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(state);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(_LOG.getMessage("COMPONENT_TREE_SERIALIZATION_FAILED"), e);
+ }
}
}
-
+
// we need this state, as we are going to recreate the UIViewRoot later. see
// the popRoot() method:
_cachedState = (root != null)
@@ -1140,11 +1167,21 @@ public class StateManagerImpl extends St
public Object getStructure()
{
+ if (_zipState(FacesContext.getCurrentInstance()))
+ {
+ return _unzipBytes((byte[])_structure);
+ }
+
return _structure;
}
public Object getState()
{
+ if (_zipState(FacesContext.getCurrentInstance()))
+ {
+ return _unzipBytes((byte[])_state);
+ }
+
return _state;
}
@@ -1155,7 +1192,7 @@ public class StateManagerImpl extends St
_cachedState = null;
}
}
-
+
@SuppressWarnings("unchecked")
public UIViewRoot popRoot(FacesContext fc)
{
@@ -1176,7 +1213,7 @@ public class StateManagerImpl extends St
_cachedState = null;
}
}
-
+
if (root != null)
{
// If an error happens during updateModel, JSF 1.1 does not
@@ -1185,11 +1222,11 @@ public class StateManagerImpl extends St
// so to clear the events, we create a new UIViewRoot.
// must get the UIViewRoot from the application so that
// we pick up any custom ViewRoot defined in faces-config.xml:
- UIViewRoot newRoot = (UIViewRoot)
+ UIViewRoot newRoot = (UIViewRoot)
fc.getApplication().createComponent(UIViewRoot.COMPONENT_TYPE);
-
+
//This code handles automatic namespacing in a JSR-301 environment
- if(ExternalContextUtils.isPortlet(fc.getExternalContext()))
+ if(ExternalContextUtils.isPortlet(fc.getExternalContext()))
{
//IMPORTANT: To avoid introducing a runtime dependency on the bridge,
//this method should only be executed when we have a portlet
@@ -1200,7 +1237,7 @@ public class StateManagerImpl extends St
newRoot = PortletUtils.getPortletViewRoot(newRoot);
}
-
+
// must call restoreState so that we setup attributes, listeners,
// uniqueIds, etc ...
newRoot.restoreState(fc, viewRootState);
@@ -1216,9 +1253,170 @@ public class StateManagerImpl extends St
newRoot.getChildren().addAll(temp);
return newRoot;
}
-
+
return null;
- }
+ }
+
+ private boolean _zipState(FacesContext fc)
+ {
+ // default is false
+ Object zipStateObject =
+ fc.getExternalContext().getInitParameter(COMPRESS_VIEW_STATE_PARAM_NAME);
+
+ if (zipStateObject == null)
+ return false;
+
+ return zipStateObject.toString().equalsIgnoreCase("true");
+ }
+
+ private Object _unzipBytes(byte[] zippedBytes)
+ {
+ Inflater decompressor = null;
+ ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+ Map<String,Object> sessionMap = externalContext.getSessionMap();
+
+ try
+ {
+ //Get inflater from session cope
+ TransientHolder<Inflater> th =
+ (TransientHolder<Inflater>)sessionMap.remove("PAGE_STATE_INFLATER");
+
+ if (th != null)
+ {
+ decompressor = th.getValue();
+ }
+
+ if(decompressor == null)
+ {
+ decompressor = new Inflater();
+ }
+
+ decompressor.setInput(zippedBytes);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(zippedBytes.length);
+ byte[] buf = new byte[zippedBytes.length*5];
+
+ while (!decompressor.finished())
+ {
+ try
+ {
+ int count = decompressor.inflate(buf);
+ bos.write(buf, 0, count);
+ }
+ catch (DataFormatException e)
+ {
+ throw new RuntimeException(_LOG.getMessage("UNZIP_STATE_FAILED"), e);
+ }
+ }
+
+ ByteArrayInputStream baos = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStreamResolveClass(baos);
+ Object unzippedState = ois.readObject();
+ ois.close();
+ return unzippedState;
+ }
+ catch(ClassNotFoundException cnfe)
+ {
+ throw new RuntimeException(_LOG.getMessage("UNZIP_STATE_FAILED"), cnfe);
+ }
+ catch(IOException ioe)
+ {
+ throw new RuntimeException(_LOG.getMessage("UNZIP_STATE_FAILED"), ioe);
+ }
+ finally
+ {
+ //Reset and put back
+ if(decompressor != null)
+ {
+ decompressor.reset();
+ TransientHolder<Inflater> th = TransientHolder.newTransientHolder(decompressor);
+ sessionMap.put("PAGE_STATE_INFLATER", th);
+ }
+ }
+ }
+
+ private void _zipToBytes(Object state, Object structure)
+ {
+ Deflater compresser = null;
+ ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+ Map<String,Object> sessionMap = externalContext.getSessionMap();
+
+ try
+ {
+ //Get deflater from session cope
+ TransientHolder<Deflater> th =
+ (TransientHolder<Deflater>)sessionMap.remove("PAGE_STATE_DEFLATER");
+
+ if (th != null)
+ {
+ compresser = th.getValue();
+ }
+
+ if(compresser == null)
+ {
+ compresser = new Deflater(Deflater.BEST_SPEED);
+ }
+
+ //Serialize state
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ oos.writeObject(state);
+ oos.flush();
+ oos.close();
+
+ byte[] ret = baos.toByteArray();
+ compresser.setInput(ret);
+ compresser.finish();
+
+ baos.reset();
+ byte[] buf = new byte[ret.length/5];
+
+ while (!compresser.finished())
+ {
+ int count = compresser.deflate(buf);
+ baos.write(buf, 0, count);
+ }
+
+ _state = baos.toByteArray();
+
+ //Serialize structure
+ baos.reset();
+ oos = new ObjectOutputStream(baos);
+ compresser.reset();
+
+ oos.writeObject(structure);
+ oos.flush();
+ oos.close();
+
+ ret = baos.toByteArray();
+ compresser.setInput(ret);
+ compresser.finish();
+
+ baos.reset();
+
+ while (!compresser.finished())
+ {
+ int count = compresser.deflate(buf);
+ baos.write(buf, 0, count);
+ }
+
+ _structure = baos.toByteArray();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(_LOG.getMessage("ZIP_STATE_FAILED"), e);
+ }
+ finally
+ {
+ //Reset and put back
+ if(compresser != null)
+ {
+ compresser.reset();
+ TransientHolder<Deflater> th = TransientHolder.newTransientHolder(compresser);
+ sessionMap.put("PAGE_STATE_DEFLATER", th);
+ }
+ }
+ }
}
private final StateManager _delegate;
@@ -1227,11 +1425,11 @@ public class StateManagerImpl extends St
private Boolean _structureGeneratedByTemplate;
private static final Character _SUBKEY_SEPARATOR = new Character('.');
-
+
private static final int _DEFAULT_CACHE_SIZE = 15;
private static final Object _APPLICATION_VIEW_CACHE_LOCK = new Object();
-
+
// base key used to identify the view cache. The window name, if any, is appended to this
private static final String _VIEW_CACHE_KEY =
"org.apache.myfaces.trinidadinternal.application.VIEW_CACHE";
Modified: myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java?rev=925024&r1=925023&r2=925024&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java (original)
+++ myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java Thu Mar 18 22:22:01 2010
@@ -46,6 +46,7 @@ import org.apache.myfaces.trinidad.loggi
import org.apache.myfaces.trinidad.util.Base64InputStream;
import org.apache.myfaces.trinidad.util.Base64OutputStream;
import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+import org.apache.myfaces.trinidadinternal.util.ObjectInputStreamResolveClass;
/**
* ResponseStateManager implementation for the Core RenderKit.
@@ -184,21 +185,7 @@ public class CoreResponseStateManager ex
try
{
ObjectInputStream ois;
- ois = new ObjectInputStream( new GZIPInputStream( b64_in,
- _BUFFER_SIZE ))
- {
- protected Class<?> resolveClass(ObjectStreamClass desc)
- throws IOException,
- ClassNotFoundException
- {
- // TRINIDAD-1062 It has been noticed that in OC4J and Weblogic that the
- // classes being resolved are having problems by not finding
- // them using the context class loader. Therefore, we are adding
- // this work-around until the problem with these application
- // servers can be better understood
- return ClassLoaderUtils.loadClass(desc.getName());
- }
- };
+ ois = new ObjectInputStreamResolveClass( new GZIPInputStream( b64_in, _BUFFER_SIZE ));
Object structure = ois.readObject();
Object state = ois.readObject();
Added: myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ObjectInputStreamResolveClass.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ObjectInputStreamResolveClass.java?rev=925024&view=auto
==============================================================================
--- myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ObjectInputStreamResolveClass.java (added)
+++ myfaces/trinidad/branches/1.2.12.2-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ObjectInputStreamResolveClass.java Thu Mar 18 22:22:01 2010
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.trinidadinternal.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+
+import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+
+public class ObjectInputStreamResolveClass extends ObjectInputStream
+{
+ public ObjectInputStreamResolveClass() throws IOException, SecurityException
+ {
+ super();
+ }
+
+ public ObjectInputStreamResolveClass(InputStream in) throws IOException
+ {
+ super(in);
+ }
+
+ protected Class<?> resolveClass(ObjectStreamClass desc)
+ throws IOException,
+ ClassNotFoundException
+ {
+ // TRINIDAD-1062 It has been noticed that in OC4J and Weblogic that the
+ // classes being resolved are having problems by not finding
+ // them using the context class loader. Therefore, we are adding
+ // this work-around until the problem with these application
+ // servers can be better understood
+ return ClassLoaderUtils.loadClass(desc.getName());
+ }
+}