You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by bs...@apache.org on 2010/10/28 02:40:24 UTC
svn commit: r1028150 [1/2] - in /myfaces/trinidad/branches/trinidad-1.2.x:
trinidad-api/src/main/java/org/apache/myfaces/trinidad/bean/util/
trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/
trinidad-impl/src/main/java/org/apache/myfaces/tri...
Author: bsullivan
Date: Thu Oct 28 00:40:23 2010
New Revision: 1028150
URL: http://svn.apache.org/viewvc?rev=1028150&view=rev
Log:
[Trinidad-1858] Fix fail-over bugs where session state is mutated without dirtying the Session objects
Backport to 1.2.x
Modified:
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/bean/util/StateUtils.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/CheckSerializationConfigurator.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PageFlowScopeMap.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/SubKeyMap.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/TokenCache.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/webapp/TrinidadFilterImpl.java
myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
Modified: myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/bean/util/StateUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/bean/util/StateUtils.java?rev=1028150&r1=1028149&r2=1028150&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/bean/util/StateUtils.java (original)
+++ myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/bean/util/StateUtils.java Thu Oct 28 00:40:23 2010
@@ -57,6 +57,7 @@ public final class StateUtils
boolean checkComponentTreeStateSerialization = false;
boolean checkSessionSerialization = false;
boolean checkApplicationSerialization = false;
+ boolean checkMangedBeanMutation = false;
String checkSerializationProperty;
@@ -90,6 +91,7 @@ public final class StateUtils
checkComponentTreeStateSerialization = true;
checkSessionSerialization = true;
checkApplicationSerialization = true;
+ checkMangedBeanMutation = true;
}
else
{
@@ -98,6 +100,7 @@ public final class StateUtils
checkComponentTreeStateSerialization = serializationFlags.contains("TREE");
checkSessionSerialization = serializationFlags.contains("SESSION");
checkApplicationSerialization = serializationFlags.contains("APPLICATION");
+ checkMangedBeanMutation = serializationFlags.contains("BEANS");
}
}
}
@@ -107,6 +110,7 @@ public final class StateUtils
_CHECK_COMPONENT_TREE_STATE_SERIALIZATION = checkComponentTreeStateSerialization;
_CHECK_SESSION_SERIALIZATION = checkSessionSerialization;
_CHECK_APPLICATION_SERIALIZATION = checkApplicationSerialization;
+ _CHECK_MANAGED_BEAN_MUTATATION = checkMangedBeanMutation;
}
private static final boolean _CHECK_COMPONENT_TREE_STATE_SERIALIZATION;
@@ -114,6 +118,7 @@ public final class StateUtils
private static final boolean _CHECK_PROPERTY_STATE_SERIALIZATION;
private static final boolean _CHECK_SESSION_SERIALIZATION;
private static final boolean _CHECK_APPLICATION_SERIALIZATION;
+ private static final boolean _CHECK_MANAGED_BEAN_MUTATATION;
/**
* Returns <code>true</code> if properties should be checked for
@@ -200,6 +205,7 @@ public final class StateUtils
* @see #checkComponentStateSerialization
* @see #checkComponentTreeStateSerialization
* @see #checkApplicationSerialization
+ * @see #checkManagedBeanMutation
*/
public static boolean checkSessionSerialization(ExternalContext extContext)
{
@@ -222,6 +228,7 @@ public final class StateUtils
* @see #checkComponentStateSerialization
* @see #checkComponentTreeStateSerialization
* @see #checkSessionSerialization
+ * @see #checkManagedBeanMutation
*/
public static boolean checkApplicationSerialization(ExternalContext extContext)
{
@@ -229,6 +236,22 @@ public final class StateUtils
}
/**
+ * Returns <code>true</code> if the attributes of the session and application Maps should be
+ * checked for cases where the attribute was mutated but not dirtied for failover. If
+ * <code>checkSessionSerialization</code> returns <code>true</code>, the contents of the
+ * Session should be checked. If <code>checkApplicationSerialization</code> returns
+ * <code>true</code>, the Serializable content of the Application should be checked.
+ * @return true if the contents of scopes should be checked for mutation without dirtying.
+ * @see #checkApplicationSerialization
+ * @see #checkSessionSerialization
+ */
+ public static boolean checkManagedBeanMutation(ExternalContext extContext)
+ {
+ return _CHECK_MANAGED_BEAN_MUTATATION;
+ }
+
+
+ /**
* Persists a property key.
*/
static public Object saveKey(PropertyKey key)
@@ -591,6 +614,3 @@ public final class StateUtils
}
-
-
-
Modified: myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java?rev=1028150&r1=1028149&r2=1028150&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java (original)
+++ myfaces/trinidad/branches/trinidad-1.2.x/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java Thu Oct 28 00:40:23 2010
@@ -1720,7 +1720,7 @@ public final class CollectionUtils
e);
}
}
- else
+ else if (value != null)
{
if (_requireSerializable)
{
Modified: myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java?rev=1028150&r1=1028149&r2=1028150&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java (original)
+++ myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java Thu Oct 28 00:40:23 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,12 +18,15 @@
*/
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;
@@ -60,7 +63,6 @@ import org.apache.myfaces.trinidadintern
import org.apache.myfaces.trinidadinternal.util.SubKeyMap;
import org.apache.myfaces.trinidadinternal.util.TokenCache;
-import com.sun.facelets.FaceletViewHandler;
/**
* StateManager that handles a hybrid client/server strategy: a
@@ -101,6 +103,7 @@ public class StateManagerImpl extends St
static public final String CACHE_VIEW_ROOT_INIT_PARAM =
"org.apache.myfaces.trinidad.CACHE_VIEW_ROOT";
+
/**
* Servlet context initialization parameter used by
* StateManagerImpl to decide what sort of state should be saved
@@ -119,12 +122,13 @@ 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";
+ * 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.trinidad.COMPRESS_VIEW_STATE";
+
/**
* Value indicating that only a simple token will be stored
@@ -143,7 +147,7 @@ public class StateManagerImpl extends St
{
_delegate = delegate;
}
-
+
@Override
protected StateManager getWrapped()
{
@@ -155,13 +159,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);
}
@@ -169,12 +173,12 @@ public class StateManagerImpl extends St
public SerializedView saveSerializedView(FacesContext context)
{
assert(context != null);
-
+
if(isSavingStateInClient(context))
{
return _saveSerializedView(context);
}
-
+
return _delegate.saveSerializedView(context);
}
@@ -190,7 +194,7 @@ public class StateManagerImpl extends St
Object state = component.processSaveState(context);
return new PageState(context, new Object[]{structure, state}, null);
}
-
+
/**
* Take an object created by saveComponentTree()
* and instantiate it as a UIComponent.
@@ -268,7 +272,7 @@ public class StateManagerImpl extends St
root.processRestoreState(context, state);
return root;
- }
+ }
@SuppressWarnings({"unchecked", "deprecation"})
private SerializedView _saveSerializedView(FacesContext context)
@@ -319,19 +323,20 @@ public class StateManagerImpl extends St
String token;
ExternalContext extContext = context.getExternalContext();
-
if (applicationViewCache == null)
{
assert(!dontSave);
- TokenCache cache = _getViewCache(context);
+
+ RequestContext trinContext = RequestContext.getCurrentInstance();
+
+ TokenCache cache = _getViewCache(trinContext, extContext);
assert(cache != null);
- Map<String, Object> sessionMap = extContext.getSessionMap();
- RequestContext trinContext = RequestContext.getCurrentInstance();
-
+ Map<String, Object> sessionMap = extContext.getSessionMap();
+
// 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
@@ -343,9 +348,9 @@ public class StateManagerImpl extends St
// Save the view root into the page state as a transient
// if this feature has not been disabled
_useViewRootCache(context) ? root : null);
-
+
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
// (unlikely, but not impossible), use the stateMap directly
@@ -383,15 +388,15 @@ public class StateManagerImpl extends St
// See Trinidad-1779
String activePageStateKey = _getActivePageTokenKey(extContext, trinContext);
String activeToken = (String)sessionMap.get(activePageStateKey);
-
+
// we only need to clear out the state if we're actually changing pages and thus tokens.
- // Since we have already updated the state for
+ // Since we have already updated the state for
if (!token.equals(activeToken))
{
if (activeToken != null)
{
PageState activePageState = stateMap.get(activeToken);
-
+
if (activePageState != null)
activePageState.clearViewRootState();
}
@@ -405,7 +410,7 @@ public class StateManagerImpl extends St
{
// use null viewRoot since this state is shared across users:
PageState applicationState = new PageState(context, new Object[]{structure, state}, null);
-
+
// If we need to, stash the state off in our cache
if (!dontSave)
{
@@ -426,7 +431,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);
}
@@ -452,9 +457,9 @@ public class StateManagerImpl extends St
{
context.getExternalContext().getRequestMap().put(
_PINNED_STATE_TOKEN_KEY, stateToken);
-
+
}
-
+
/**
* @return the state token for the current request
*/
@@ -463,24 +468,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);
}
/**
@@ -516,8 +521,8 @@ public class StateManagerImpl extends St
return (String) token;
}
-
-
+
+
@Override @SuppressWarnings("deprecation")
public void writeState(FacesContext context,
SerializedView state) throws IOException
@@ -531,8 +536,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);
@@ -541,7 +546,7 @@ public class StateManagerImpl extends St
TrinidadPhaseListener.markPostback(context);
return launchView;
}
-
+
if (!isSavingStateInClient(context))
return _delegate.restoreView(context, viewId, renderKitId);
@@ -586,21 +591,21 @@ 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;
}
}
else
{
+ RequestContext trinContext = RequestContext.getCurrentInstance();
+
// get view cache key with "." separator suffix to separate the SubKeyMap keys
- String subkey = _getViewCacheKey(extContext,
- RequestContext.getCurrentInstance(),
- _SUBKEY_SEPARATOR);
-
+ String subkey = _getViewCacheKey(extContext, trinContext, _SUBKEY_SEPARATOR);
+
Map<String, PageState> stateMap = new SubKeyMap<PageState>(
extContext.getSessionMap(),
subkey);
@@ -616,8 +621,7 @@ public class StateManagerImpl extends St
// token cache here, not just inside the assert. If we don't,
// then we don't actually access the token, so it doesn't
// get bumped up to the front in the LRU Cache!
- boolean isAvailable =
- _getViewCache(context).isAvailable((String) token);
+ boolean isAvailable = _getViewCache(trinContext, extContext).isAvailable((String) token);
assert ((viewState != null) == isAvailable);
}
@@ -677,7 +681,7 @@ public class StateManagerImpl extends St
if (state != null)
root.processRestoreState(context, state);
-
+
if (recalculateLocale)
{
// Ensure that locale gets re-calculated when next fetched.
@@ -708,12 +712,12 @@ public class StateManagerImpl extends St
* The given parameter (<code>perViewStateSaving</code>) indicates
* if we need to enable client- OR server-side state-saving
* for the current VIEW.
- *
+ *
* <p>
* <b>This is an internal method, that is ONLY called by the
* Trinidad Document</b>
* </p>
- *
+ *
* @param perViewStateSaving <code>default</code>, <code>server</code> or <code>client</code> for stateSaving
*/
public void setPerViewStateSaving(String perViewStateSaving)
@@ -760,21 +764,19 @@ public class StateManagerImpl extends St
throw new UnsupportedOperationException();
}
-
- private TokenCache _getViewCache(FacesContext context)
+ /**
+ * Returns the TokenCache for the current window
+ * @param trinContext
+ * @param extContext
+ * @return
+ */
+ private TokenCache _getViewCache(RequestContext trinContext, ExternalContext extContext)
{
- ExternalContext extContext = context.getExternalContext();
+ String cacheKey = _getViewCacheKey(extContext, trinContext, null);
- return TokenCache.getTokenCacheFromSession(context,
- _getViewCacheKey(extContext,
- RequestContext.getCurrentInstance(),
- null),
- true,
- _getCacheSize(extContext));
+ return TokenCache.getTokenCacheFromSession(extContext,cacheKey, true,_getCacheSize(extContext));
}
-
-
/**
* Returns a key suitable for finding the per-window active page state key
* @param extContext
@@ -785,9 +787,9 @@ public class StateManagerImpl extends St
ExternalContext extContext,
RequestContext trinContext)
{
- return _getPerWindowCacheKey(extContext, trinContext, _ACTIVE_PAGE_STATE_SESSION_KEY, null);
+ return _getPerWindowCacheKey(extContext, trinContext, _ACTIVE_PAGE_TOKEN_SESSION_KEY, null);
}
-
+
/**
* Returns a key suitable for finding the per-window cache key
* @param extContext
@@ -802,7 +804,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
@@ -820,18 +822,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;
}
@@ -840,28 +842,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
@@ -907,7 +909,7 @@ public class StateManagerImpl extends St
ExternalContext external = context.getExternalContext();
Object stateSavingMethod =
- external.getInitParameterMap().get(StateManager.STATE_SAVING_METHOD_PARAM_NAME);
+ external.getInitParameterMap().get(StateManager.STATE_SAVING_METHOD_PARAM_NAME);
// on "SERVER" state-saving we return TRUE, since we want send down a token string.
if ((stateSavingMethod == null) ||
@@ -926,7 +928,7 @@ public class StateManagerImpl extends St
return false;
}
- // if the user has used the <document> 'stateSaving' attribute to specify
+ // if the user has used the <document> 'stateSaving' attribute to specify
// client, we force the state mananger (see above) to render the entire
// state on the client. The indicator is stashed on the FacesContext and
// is therefore NOT visible during "restoreView" phase. So if we reach this point
@@ -989,7 +991,7 @@ public class StateManagerImpl extends St
return cache;
}
}
-
+
@SuppressWarnings("unchecked")
static private Map<String, PageState> _getPerSessionApplicationViewCache(FacesContext context)
{
@@ -1052,7 +1054,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();
}
@@ -1125,18 +1127,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;
}
@@ -1192,11 +1194,11 @@ public class StateManagerImpl extends St
{
if (viewRoot == null)
throw new NullPointerException();
-
+
_viewRoot = viewRoot;
_viewRootState = viewRoot.saveState(context);
}
-
+
public UIViewRoot getViewRoot()
{
return _viewRoot;
@@ -1206,7 +1208,7 @@ public class StateManagerImpl extends St
{
return _viewRootState;
}
-
+
private final UIViewRoot _viewRoot;
private final Object _viewRootState;
}
@@ -1216,7 +1218,7 @@ public class StateManagerImpl extends St
private static final long serialVersionUID = 1L;
private Object _viewState;
-
+
// use transient since UIViewRoots are not Serializable.
private transient ViewRootState _cachedState;
@@ -1236,19 +1238,20 @@ public class StateManagerImpl extends St
}
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(viewState);
- }
- catch (IOException e)
- {
- throw new RuntimeException(_LOG.getMessage("COMPONENT_TREE_SERIALIZATION_FAILED"), e);
+ // 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(viewState);
+ }
+ 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)
@@ -1273,7 +1276,7 @@ public class StateManagerImpl extends St
_cachedState = null;
}
}
-
+
@SuppressWarnings("unchecked")
public UIViewRoot popRoot(FacesContext fc)
{
@@ -1294,7 +1297,7 @@ public class StateManagerImpl extends St
_cachedState = null;
}
}
-
+
if (root != null)
{
// If an error happens during updateModel, JSF 1.1 does not
@@ -1303,11 +1306,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
@@ -1326,7 +1329,7 @@ public class StateManagerImpl extends St
}
}
-
+
// must call restoreState so that we setup attributes, listeners,
// uniqueIds, etc ...
newRoot.restoreState(fc, viewRootState);
@@ -1342,9 +1345,10 @@ public class StateManagerImpl extends St
newRoot.getChildren().addAll(temp);
return newRoot;
}
-
+
return null;
}
+
private boolean _zipState(FacesContext fc)
{
// default is false
@@ -1379,22 +1383,22 @@ public class StateManagerImpl extends St
decompressor = new Inflater();
}
- decompressor.setInput(zippedBytes);
+ 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)
- {
+ 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);
@@ -1454,7 +1458,7 @@ public class StateManagerImpl extends St
byte[] ret = baos.toByteArray();
compresser.setInput(ret);
- compresser.finish();
+ compresser.finish();
baos.reset();
byte[] buf = new byte[ret.length/5];
@@ -1485,7 +1489,7 @@ public class StateManagerImpl extends St
}
/**
- * Static ENUM to capture the values of the <document>'s
+ * Static ENUM to capture the values of the <document>'s
* 'stateSaving' attribute
*/
static private enum StateSaving
@@ -1508,11 +1512,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";
@@ -1521,7 +1525,7 @@ public class StateManagerImpl extends St
"org.apache.myfaces.trinidadinternal.application.APPLICATION_VIEW_CACHE";
// key to stash the per_page_state_saving during rendering
- private static final String _PER_PAGE_STATE_SAVING =
+ private static final String _PER_PAGE_STATE_SAVING =
"org.apache.myfaces.trinidadimpl.PER_PAGE_STATE_SAVING";
private static final String _CACHED_SERIALIZED_VIEW =
@@ -1536,8 +1540,8 @@ public class StateManagerImpl extends St
private static final String _REUSE_REQUEST_TOKEN_FOR_RESPONSE_KEY =
"org.apache.myfaces.trinidadinternal.application.REUSE_REQUEST_TOKEN_FOR_RESPONSE";
- // key for saving the PageState for the last accessed view in this Session
- private static final String _ACTIVE_PAGE_STATE_SESSION_KEY =
+ // key for saving the token to the PageState for the last accessed view in this Session
+ private static final String _ACTIVE_PAGE_TOKEN_SESSION_KEY =
"org.apache.myfaces.trinidadinternal.application.StateManagerImp.ACTIVE_PAGE_STATE";
private static final String _APPLICATION_CACHE_TOKEN = "_a_";
Modified: myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/CheckSerializationConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/CheckSerializationConfigurator.java?rev=1028150&r1=1028149&r2=1028150&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/CheckSerializationConfigurator.java (original)
+++ myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/CheckSerializationConfigurator.java Thu Oct 28 00:40:23 2010
@@ -18,18 +18,57 @@
*/
package org.apache.myfaces.trinidadinternal.config;
+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.Serializable;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.faces.context.ExternalContext;
+import org.apache.myfaces.trinidad.context.ExternalContextDecorator;
+
+import javax.servlet.FilterConfig;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+import javax.servlet.http.HttpSessionContext;
+
import org.apache.myfaces.trinidad.bean.util.StateUtils;
import org.apache.myfaces.trinidad.config.Configurator;
-import org.apache.myfaces.trinidad.context.ExternalContextDecorator;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
import org.apache.myfaces.trinidad.util.CollectionUtils;
+import org.apache.myfaces.trinidad.util.CollectionUtils.MapMutationHooks;
+import org.apache.myfaces.trinidad.util.TransientHolder;
+
+import org.apache.myfaces.trinidadinternal.context.external.ServletApplicationMap;
/**
- * Configurator that uses a wrapped ExternalContext to return a Session Map that validates that
- * only Serializable Objects are placed in the Map.
+ * Configurator that uses both wrapped ExternalContext (for Portlet cases) and wrapped
+ * ServletContext and HttpSession (for HttpServlet cases) to validate that
+ * only Serializable Objects are placed in the Sesssion Map and that mutations to the
+ * Session and ApplicationMap content dirty the entries.
* @version $Revision$ $Date$
*/
public final class CheckSerializationConfigurator extends Configurator
@@ -37,89 +76,1171 @@ public final class CheckSerializationCon
/**
* Override to return our ExternalContext wrapped if session serialization checking is enabled
- * @param externalContext
+ * @param extContext
* @return
*/
@Override
- public ExternalContext getExternalContext(ExternalContext externalContext)
+ public ExternalContext getExternalContext(ExternalContext extContext)
{
- boolean checkSession = StateUtils.checkSessionSerialization(externalContext);
- boolean checkApplication = StateUtils.checkApplicationSerialization(externalContext);
-
- if (checkSession || checkApplication)
+ // retrieve our wrapped ExternalContext, creating it if necessary. We wrap the external
+ // context to trap calls to retrieve the Session and Application Maps in the portal case.
+ // For the HttpServlet case, we rely on
+ ExternalContext checkingContext =
+ SerializationCheckingWrapper.getSerializationWrapper(extContext, true);
+
+ if (checkingContext != null)
+ {
+ return checkingContext;
+ }
+ else
+ {
+ return extContext;
+ }
+ }
+
+ /**
+ * Check if any of the non-dirtied checked managed beans have been mutated in this request
+ * @param extContext
+ */
+ @Override
+ public void endRequest(ExternalContext extContext)
+ {
+ // get the wrapper without creating it if it doesn't already exist
+ SerializationCheckingWrapper checkingWrapper =
+ SerializationCheckingWrapper.getSerializationWrapper(extContext, false);
+
+
+ if (checkingWrapper != null)
+ {
+ checkingWrapper.checkForMutations();
+ }
+ }
+
+ /**
+ * Returns the FilterConfig to use for initializing the filters so that we can wrap it
+ * if necessary
+ * @param filterConfig
+ * @return
+ */
+ public static FilterConfig getFilterConfig(FilterConfig filterConfig)
+ {
+ // skankily don't pass the ExternalContext since we don't have one when the filters are
+ // initialized. This only really works because checkApplicvationSerialization doesn't
+ // need the ExternalContext
+ if (StateUtils.checkApplicationSerialization(null))
+ {
+ return new FilterConfigWrapper(filterConfig);
+ }
+ else
{
- return new SessionSerializationChecker(externalContext, checkSession, checkApplication);
+ return filterConfig;
+ }
+ }
+
+ /**
+ * Returns the HttpServletRequest to use for this request, so that we can wrap it if
+ * necessary.
+ * @param extContext
+ * @param request
+ * @return
+ */
+ public static HttpServletRequest getHttpServletRequest(
+ ExternalContext extContext,
+ HttpServletRequest request)
+ {
+ SerializationChecker checker = SerializationChecker.getSerializationChecker(extContext, true);
+
+ if (checker != null)
+ {
+ return checker.getWrappedRequest(request);
}
else
{
- return externalContext;
+ return request;
}
}
+
+ /**
+ * Unregisters the checking of the specified session attribute
+ * @param external ExternalContext
+ * @param key Name of session attribute to unregister
+ */
+ public static void unregisterSessionAttribute(ExternalContext external, String key)
+ {
+ SerializationChecker checker = SerializationChecker.getSerializationChecker(external, false);
+
+ if (checker != null)
+ {
+ checker.unregisterSessionAttribute(external, key);
+ }
+ }
+
+ /**
+ * Unregisters the checking of the specified application attribute
+ * @param external ExternalContext
+ * @param key Name of session attribute to unregister
+ */
+ public static void unregisterApplicationAttribute(ExternalContext external, String key)
+ {
+ SerializationChecker checker = SerializationChecker.getSerializationChecker(external, false);
+
+ if (checker != null)
+ {
+ checker.unregisterApplicationAttribute(external, key);
+ }
+ }
+
+ /**
+ * Returns the list of in-flight MutatedBeanCheckers for the specified Map and its associated
+ * lock object
+ * @param checkedMap Map checked by the MutatedBeanCheckers
+ * @param mapWriteLock Lock object to synchronize on when mutatating the amp
+ * @return
+ */
+ private static List<MutatedBeanChecker> _getMutatedBeanList(
+ Map<String, Object> checkedMap,
+ Object mapWriteLock)
+ {
+ Object list = checkedMap.get(_CHECKED_MAPS_KEY);
+
+ if (list == null)
+ {
+ // make sure that the list is only created once per map
+ synchronized(mapWriteLock)
+ {
+ // check again in case we value was written by the previou lock holder
+ list = checkedMap.get(_CHECKED_MAPS_KEY);
+
+ if (list == null)
+ {
+ // mutations to the list itself need to be thread-safe
+ List<MutatedBeanChecker> beanList = new CopyOnWriteArrayList<MutatedBeanChecker>();
+
+ // use a TransientHolder since we don't care if this gets failed over
+ checkedMap.put(_CHECKED_MAPS_KEY, TransientHolder.newTransientHolder(beanList));
+
+ return beanList;
+ }
+ }
+ }
+
+ return ((TransientHolder<List<MutatedBeanChecker>>)list).getValue();
+ }
+
+ /**
+ * Remove the modified key from all of the in-flight bean checking requests
+ * @param beanCheckers
+ * @param key
+ */
+ private static void _notifyBeanCheckersOfChange(
+ List<MutatedBeanChecker> beanCheckers,
+ Object key)
+ {
+ for (MutatedBeanChecker beanChecker : beanCheckers)
+ {
+ beanChecker._unmutatedKeyValues.remove(key);
+ }
+ }
+
+ /**
+ * Wraps the FilterConfig so that we can wrap the ServletContext that it returns so that
+ * we can trap calls the setting and removing ServletContext attributes. Phew!
+ */
+ private static class FilterConfigWrapper implements FilterConfig
+ {
+ FilterConfigWrapper(FilterConfig filterConfig)
+ {
+ _delegate = filterConfig;
+
+ // create ServletContext wrapper to catch sets and removes from the ServletContext
+ _wrappedContext = new ContextWrapper(filterConfig.getServletContext(), null);
+ }
+
+ public String getFilterName()
+ {
+ return _delegate.getFilterName();
+ }
+
+ public ServletContext getServletContext()
+ {
+ return _wrappedContext;
+ }
+
+ public String getInitParameter(String paramName)
+ {
+ return _delegate.getInitParameter(paramName);
+ }
+
+ public Enumeration getInitParameterNames()
+ {
+ return _delegate.getInitParameterNames();
+ }
+
+ private final FilterConfig _delegate;
+ private final ServletContext _wrappedContext;
+ }
+
+
/**
- * ExternalContextDecorator returning our wrapped SessionMap
+ * ExternalContextWrapper that returns wrapped versions of the Session and ApplicationMaps that
+ * we can track changes to. This is needed for the Portlet case. For the HttpServel case,
+ * it is redundant with the ServletContext and Session wrapping but shouldn't do any harm.
*/
- private static class SessionSerializationChecker extends ExternalContextDecorator
+ private static class SerializationCheckingWrapper extends ExternalContextDecorator
{
- public SessionSerializationChecker(
+ /**
+ * Retrieves the current SerializationCheckingWrapper for this request
+ * @param extContext
+ * @param create If <code>true</code>, create the SerializationCheckingWrapper for this
+ * request if it doesn't already exist.
+ * @return
+ */
+ public static SerializationCheckingWrapper getSerializationWrapper(
ExternalContext extContext,
- boolean checkSession,
- boolean checkApplication)
+ boolean create)
+ {
+ // get the SerializationCheckingWrapper for this request
+ Map<String, Object> requestMap = extContext.getRequestMap();
+
+ Object wrapper = requestMap.get(_SERIALIZATION_WRAPPER_KEY);
+
+ if (wrapper != null)
+ {
+ return (SerializationCheckingWrapper)wrapper;
+ }
+ else if (create)
+ {
+ // create the wrapper for this request and store it on the request so that we don't
+ // recreate it
+ SerializationChecker checker = SerializationChecker.getSerializationChecker(extContext,
+ create);
+
+ if (checker != null)
+ {
+ SerializationCheckingWrapper checkingWrapper = new SerializationCheckingWrapper(extContext,
+ checker);
+
+ requestMap.put(_SERIALIZATION_WRAPPER_KEY, checkingWrapper);
+
+ return checkingWrapper;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Create a SerializationCheckingWrapper
+ * @param extContext ExternalContext to wrap
+ * @param checker SerializationChecker to call back on mutations
+ */
+ private SerializationCheckingWrapper(
+ ExternalContext extContext,
+ SerializationChecker checker)
{
_extContext = extContext;
+ _checker = checker;
+ }
+
+ /**
+ * Check for mutations to beans trancked by the SerializationCheckingWrapper
+ */
+ public void checkForMutations()
+ {
+ _checker.checkForMutations();
+ }
+
+ @Override
+ public ExternalContext getExternalContext()
+ {
+ return _extContext;
+ }
+
+ /**
+ * Override to delegate to the SerializationChecker
+ * @return
+ */
+ @Override
+ public Map<String, Object> getSessionMap()
+ {
+ return _checker.getSessionMap();
+ }
+
+ /**
+ * Override to delegate to the SerializationChecker
+ * @return
+ */
+ @Override
+ public Map<String, Object> getApplicationMap()
+ {
+ return _checker.getApplicationMap();
+ }
+
+ private static final String _SERIALIZATION_WRAPPER_KEY =
+ CheckSerializationConfigurator.class.getName() + "#WRAPPER";
+
+ private final ExternalContext _extContext;
+ private final SerializationChecker _checker;
+ }
+
+ /**
+ * Checks a Map for mutations to the contents of its Serializable attributes that weren't
+ * dirtied in the current request.
+ * The mutations are checked by snapshotting the serialized bytes of the current Serializable
+ * values of the Map at the beginning of the request. We then catch all puts and removes to
+ * the Map across any request and remove those entries, since they have been correctly dirtied.
+ * At the end of the request. <code>checkForMutations</code> is called and we iterate over
+ * the remaining entries and compared their serialized bytes against the serialized bytes
+ * of the current values. If the bytes are different, we assume that some part of the
+ * attribute's object subtree has been changed without appropriately dirtying it and we
+ * log an errror.
+ * @see #checkForMutations
+ */
+ private static class MutatedBeanChecker implements MapMutationHooks<String, Object>
+ {
+ /**
+ * Creates a MutatedBeanChecker to check for undirtied mutations to the Serialized state
+ * of a Map in the current request.
+ * @param checkedMap Map containing attributes to check for mutations
+ * @param mapName Name of map used when logging
+ * @param mapLock Lock to use when mutating the map
+ * @param requireSerialization <code>true</code> if all of the attributes are required to be
+ * Serializable (Sesssion Map attributes are. Application Map
+ * aren't)
+ */
+ public MutatedBeanChecker(
+ Map<String, Object> checkedMap,
+ String mapName,
+ Object mapLock,
+ boolean requireSerialization)
+ {
+ _checkedMap = checkedMap;
+ _mapName = mapName;
+ _mapLock = mapLock;
+
+ // snapshot the initial serialized bytes of the mutable values in the Map so that we
+ // can compare them at the end of the request to see if they have changed
+ _unmutatedKeyValues = new ConcurrentHashMap<String, Object>(checkedMap.size() * 2);
+ _unmutatedKeyValues.putAll(checkedMap);
+
+ // register this request with the list of checkers for this map.
+ // I think there is a possible race condition between the keys being added to the map and
+ // our registering ourselves as listening for puts and removes made by other requests.
+ // This makes me sad
+ _getMutatedBeanList().add(this);
+
+ // loop through the map's valid keys getting the serialized bytes
+ for (String key : _unmutatedKeyValues.keySet())
+ {
+ Object value = checkedMap.get(key);
+
+ // get the serialized bytes for this key. If the key's vale isn't serializable or is
+ // immutable, this will be an empty array and we won't need to check it
+ byte[] serializedBytes = _getSerializedValue(key, value, requireSerialization);
+
+ if (serializedBytes.length > 0)
+ {
+ // save the bytes for comparing at the end of the request
+ _unmutatedKeyValues.put(key, serializedBytes);
+ }
+ else
+ {
+ // either not serializable or immutable, so we don't need to worry about checking it
+ _unmutatedKeyValues.remove(key);
+ }
+ }
+ }
+
+ /**
+ * Unregisters the checking of the specified attribute
+ * @param key Name of session attribute to unregister
+ */
+ public void unregisterAttribute(String key)
+ {
+ CheckSerializationConfigurator._notifyBeanCheckersOfChange(_getMutatedBeanList(), key);
+ }
+
+ /** Implement to catch writes to the Map, since that means that the Map has been dirtied */
+ @Override
+ public void writeNotify(Map<String, Object> map, String key, Object value)
+ {
+ unregisterAttribute(key);
+ }
+
+ /** Implement to catch remove from the Map, since that means the attribute won't
+ * be failed over
+ */
+ @Override
+ public void removeNotify(Map<String, Object> map, Object key)
+ {
+ unregisterAttribute((String)key);
+ }
+
+ /** Implement to catch clear of Map, since that means the attributes won't
+ * be failed over
+ */
+ @Override
+ public void clearNotify(Map<String, Object> map)
+ {
+ // clear all of the keys across all of the beans
+ for (String key : map.keySet())
+ {
+ unregisterAttribute(key);
+ }
+ }
+
+ /**
+ * Clear all of the values we were checking. This is called if the Session is invalidated,
+ * for example.
+ */
+ public void clearCheckedValues()
+ {
+ for (MutatedBeanChecker beanChecker : _getMutatedBeanList())
+ {
+ beanChecker._unmutatedKeyValues.clear();
+ }
+ }
+
+ /**
+ * Check for any undirtied mutations of this map, logging severe messages if there are
+ */
+ public void checkForMutations()
+ {
+ // loop through the unmodified items in the Map and verify that the curent
+ // Serialized values haven't changed
+ for (Map.Entry<String, Object> checkedEntry : _unmutatedKeyValues.entrySet())
+ {
+ String key = checkedEntry.getKey();
+
+ Object currValue = _checkedMap.get(key);
+ byte[] currentBytes = _getSerializedValue(key, currValue, false);
+ byte[] oldBytes = (byte[])checkedEntry.getValue();
+
+ // check if the bytes are different
+ if (!Arrays.equals(oldBytes, currentBytes))
+ {
+ // deserialize the original object so we can dump it out (hopefully it has a
+ // good toString()) We also do this so we can
+ Object oldValue = _deserializeObject(oldBytes);
+
+ // deserialize the new bytes so that we are comparing two deserialized objects
+ Object newValue = _deserializeObject(currentBytes);
+
+ // This doesn't do anything, but is a handy comparison of debugging when things go awry
+ oldValue.equals(newValue);
+
+ // build up the message
+ String message = _LOG.getMessage("SERIALIZABLE_ATTRIBUTE_MUTATED",
+ new Object[]{_mapName, key, oldValue, newValue});
+
+ // Log message because user might not notice exception since we are at the end of the
+ // request
+ _LOG.severe(message);
+ }
+ }
+
+ // we no longer need to track changes to the map
+ _getMutatedBeanList().remove(this);
+ }
+
+
+ /**
+ * Given the serialized bytes of an Object, return the Object itself
+ * @param serializedBytes
+ * @return
+ */
+ private Object _deserializeObject(byte[] serializedBytes)
+ {
+ Object deserializedObject;
+
+ try
+ {
+ // copy the bytes before passing to the ByteArrayInputStream, since it mutates
+ // the array
+ byte[] copyBytes = Arrays.copyOf(serializedBytes, serializedBytes.length);
+
+ ByteArrayInputStream baos = new ByteArrayInputStream(copyBytes);
+ ObjectInputStream ois = new ObjectInputStream(baos);
+ deserializedObject = ois.readObject();
+ ois.close();
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new IllegalArgumentException(e);
+ }
+
+ return deserializedObject;
+ }
+
+ /**
+ * Returns the List of MutatedBeanCheckers across all in flight requests listening for changes
+ * to this Map
+ * @return
+ */
+ private List<MutatedBeanChecker> _getMutatedBeanList()
+ {
+ return CheckSerializationConfigurator._getMutatedBeanList(_checkedMap, _mapLock);
+ }
+
+ /**
+ * Returns the serialized value of the object as a byte[] or an empty array if the object is
+ * immutable and therefore doesn't need to be checked
+ * @param key Key in map to get the serialized value of
+ * @param value Value in map to serialize
+ * @param requireSerialization <code>true</code> if this value is required to be serializable
+ * @return The serialized bytes for the Object if serializable and mutable
+ * @throws IllegalStateException if the Object is not serializable or serialization fails
+ */
+ private byte[] _getSerializedValue(String key, Object value, boolean requireSerialization)
+ {
+ if (value == null)
+ return _EMPTY_BYTE_ARRAY;
+
+ Class valueClass = value.getClass();
+
+ // check against the lsit of classes to ignore for performance reasons
+ if (_INGNORE_CLASS_NAMES.contains(valueClass.getName()))
+ return _EMPTY_BYTE_ARRAY;
+
+ if (!(value instanceof Serializable))
+ {
+ if (requireSerialization)
+ {
+ String message = _LOG.getMessage("ATTRIBUTE_NOT_SERIALIZABLE",
+ new Object[]{_mapName, key, valueClass});
+
+ // throw new IllegalStateException(message);
+ }
+
+ return _EMPTY_BYTE_ARRAY;
+ }
- Map<String, Object> sessionMap = extContext.getSessionMap();
- if (checkSession)
+ // verify that the contents of the value are in fact Serializable
+ try
{
- // skank using type erasure to finess the fact that Collections.checkedMap() expects and
- // will return a Map<String, Serializable> when in fact, we should be returning a
- // Map<String, Onject>. Using checkedMap also has the disadvantage that a ClassCastException
- // is thrown when we would really prefer to throw a more-explanatory message
- //Map erasedMap = sessionMap;
- //_sessionMap = (Map)Collections.checkedMap(erasedMap, String.class, Serializable.class);
- _sessionMap = CollectionUtils.getCheckedSerializationMap(sessionMap);
+ ByteArrayOutputStream outputByteStream = new ByteArrayOutputStream();
+
+ new ObjectOutputStream(outputByteStream).writeObject(value);
+
+ return outputByteStream.toByteArray();
+ }
+ catch (IOException e)
+ {
+ if (requireSerialization)
+ {
+ String message = _LOG.getMessage("ATTRIBUTE_SERIALIZATION_FAILED",
+ new Object[]{_mapName, key, value});
+
+ throw new IllegalArgumentException(message, e);
+ }
+
+ return _EMPTY_BYTE_ARRAY;
+ }
+ }
+
+ private static final byte[] _EMPTY_BYTE_ARRAY = new byte[0];
+
+ private static final Set<String> _INGNORE_CLASS_NAMES;
+
+ static
+ {
+ // initialize Set of class names to ignore for Serialization tracking because they
+ // are immutable or not serialiable
+ String[] classNames = new String[]
+ {
+ "java.lang.Boolean", // immutable
+ "java.lang.Character", // immutable
+ "java.lang.Double", // immutable
+ "java.lang.Float", // immutable
+ "java.lang.Integer", // immutable
+ "java.lang.Long", // immutable
+ "java.lang.Short", // immutable
+ "java.lang.String", // immutable
+ "java.math.BigDecimal", // immutable
+ "java.math.BigInteger", // immutable
+ "org.apache.myfaces.trinidad.util.TransientHolder" // Not serializable
+ };
+
+
+ _INGNORE_CLASS_NAMES = new HashSet<String>();
+ _INGNORE_CLASS_NAMES.addAll(Arrays.asList(classNames));
+ }
+
+ private static final TrinidadLogger _LOG =
+ TrinidadLogger.createTrinidadLogger(MutatedBeanChecker.class);
+
+ private final Map<String, Object> _unmutatedKeyValues;
+ private final Map<String, Object> _checkedMap;
+ private final String _mapName;
+ private final Object _mapLock;
+ }
+
+ /**
+ * Wraps the ServletContext so that we can catch modifications to the attributes
+ */
+ private static final class ContextWrapper implements ServletContext
+ {
+ ContextWrapper(
+ ServletContext servletContext,
+ Map<String, Object> applicationMap)
+ {
+ _delegate = servletContext;
+
+ // if we already have an Application Map, use it, otherwise create a wrapper around
+ // the ServletContext
+ if (applicationMap != null)
+ {
+ _applicationMap = applicationMap;
}
else
{
- _sessionMap = sessionMap;
+ _applicationMap = new ServletApplicationMap(servletContext);
}
-
+ }
+
+ public String getContextPath()
+ {
+ return _delegate.getContextPath();
+ }
+
+ public ServletContext getContext(String string)
+ {
+ return _delegate.getContext(string);
+ }
+
+ public int getMajorVersion()
+ {
+ return _delegate.getMajorVersion();
+ }
+
+ public int getMinorVersion()
+ {
+ return _delegate.getMinorVersion();
+ }
+
+ public String getMimeType(String string)
+ {
+ return _delegate.getMimeType(string);
+ }
+
+ public Set getResourcePaths(String string)
+ {
+ return _delegate.getResourcePaths(string);
+ }
+
+ public URL getResource(String string) throws MalformedURLException
+ {
+ return _delegate.getResource(string);
+ }
+
+ public InputStream getResourceAsStream(String string)
+ {
+ return _delegate.getResourceAsStream(string);
+ }
+
+ public RequestDispatcher getRequestDispatcher(String string)
+ {
+ return _delegate.getRequestDispatcher(string);
+ }
+
+ public RequestDispatcher getNamedDispatcher(String string)
+ {
+ return _delegate.getNamedDispatcher(string);
+ }
+
+ public Servlet getServlet(String string) throws ServletException
+ {
+ return _delegate.getServlet(string);
+ }
+
+ public Enumeration getServlets()
+ {
+ return _delegate.getServlets();
+ }
+
+ public Enumeration getServletNames()
+ {
+ return _delegate.getServletNames();
+ }
+
+ public void log(String string)
+ {
+ _delegate.log(string);
+ }
+
+ public void log(Exception exception, String string)
+ {
+ _delegate.log(exception, string);
+ }
+
+ public void log(String string, Throwable throwable)
+ {
+ _delegate.log(string, throwable);
+ }
+
+ public String getRealPath(String string)
+ {
+ return _delegate.getRealPath(string);
+ }
+
+ public String getServerInfo()
+ {
+ return _delegate.getServerInfo();
+ }
+
+ public String getInitParameter(String string)
+ {
+ return _delegate.getInitParameter(string);
+ }
+
+ public Enumeration getInitParameterNames()
+ {
+ return _delegate.getInitParameterNames();
+ }
+
+ public Object getAttribute(String key)
+ {
+ return _delegate.getAttribute(key);
+ }
+
+ public Enumeration getAttributeNames()
+ {
+ return _delegate.getAttributeNames();
+ }
+
+ /**
+ * Override to remove the attribute from the list of attributes to fail over
+ * @param key
+ * @param value
+ */
+ public void setAttribute(String key, Object value)
+ {
+ _delegate.setAttribute(key, value);
+
+ _notifyBeanCheckersOfChange(_getMutatedBeanList(), key);
+ }
+
+ /**
+ * Override to remove the attribute from the list of attributes to fail over
+ * @param key
+ */
+ public void removeAttribute(String key)
+ {
+ _delegate.removeAttribute(key);
+
+ _notifyBeanCheckersOfChange(_getMutatedBeanList(), key);
+ }
+
+ public String getServletContextName()
+ {
+ return _delegate.getServletContextName();
+ }
+
+ private List<MutatedBeanChecker> _getMutatedBeanList()
+ {
+ return CheckSerializationConfigurator._getMutatedBeanList(_applicationMap, _delegate);
+ }
+
+ private final ServletContext _delegate;
+ private final Map<String, Object> _applicationMap;
+ }
+
+ /**
+ * Performs any configured serialization checking of the Session or Application Maps including
+ * whether the contents are Serializable and whether the contents have changed.
+ */
+ private static class SerializationChecker
+ {
+ /**
+ * Get the current SerializaionChecker for this request, potentially creating one
+ * @param extContext ExternalContext to use to create the SerializationChecker
+ * @param create If <code>true</code> a SerializationChecker will be created and registered
+ * for this request if one does not alreadfy exist.
+ * @return
+ */
+ public static SerializationChecker getSerializationChecker(
+ ExternalContext extContext,
+ boolean create)
+ {
+ Map<String, Object> requestMap = extContext.getRequestMap();
+
+ Object checker = requestMap.get(_SERIALIZATION_CHECKER_KEY);
+
+ if (checker != null)
+ {
+ return (SerializationChecker)checker;
+ }
+ else if (create)
+ {
+ boolean checkSession = StateUtils.checkSessionSerialization(extContext);
+ boolean checkApplication = StateUtils.checkApplicationSerialization(extContext);
+ boolean checkManagedBeanMutation = StateUtils.checkManagedBeanMutation(extContext);
+
+ // check the possible conditions under which we would need to create a SerializationChecker
+ if (checkSession || checkApplication || checkManagedBeanMutation)
+ {
+ SerializationChecker serializationChecker = new SerializationChecker(
+ extContext,
+ checkSession,
+ checkApplication,
+ checkManagedBeanMutation);
+ requestMap.put(_SERIALIZATION_CHECKER_KEY, serializationChecker);
+
+ return serializationChecker;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Creates a SerializationChecker for this request
+ * @param extContext ExternalContext to use to initialize the SerializationChecker
+ * @param checkSession If true check serializability of session attributes
+ * @param checkApplication if true, check serializability of application attributes
+ * @param checkManagedBeanMutation if true, check for mutations to attributes in the session
+ * if checkSession is true and the application if
+ * checkApplication is true.
+ */
+ private SerializationChecker(
+ ExternalContext extContext,
+ boolean checkSession,
+ boolean checkApplication,
+ boolean checkManagedBeanMutation)
+ {
+ Map<String, Object> sessionMap = extContext.getSessionMap();
Map<String, Object> applicationMap = extContext.getApplicationMap();
- if (checkApplication)
+ if (checkManagedBeanMutation)
{
- // skank using type erasure to finess the fact that Collections.checkedMap() expects and
- // will return a Map<String, Serializable> when in fact, we should be returning a
- // Map<String, Onject>. Using checkedMap also has the disadvantage that a ClassCastException
- // is thrown when we would really prefer to throw a more-explanatory message
- //Map erasedMap = applicationMap;
- //_applicationMap = (Map)Collections.checkedMap(erasedMap, String.class, Serializable.class);
- _applicationMap = CollectionUtils.getCheckedSerializationMap(applicationMap);
+ // note that the mutated bean checekd implicitly checks for attribute serialization as well.
+ _sessionBeanChecker = new MutatedBeanChecker(sessionMap,
+ "Session",
+ extContext.getSession(true),
+ true);
+ sessionMap = CollectionUtils.newMutationHookedMap(sessionMap, _sessionBeanChecker);
+
+ // only check the application for mutations if the application checking is enabled
+ if (checkApplication)
+ {
+ _applicationBeanChecker = new MutatedBeanChecker(applicationMap,
+ "Application",
+ extContext.getContext(),
+ false);
+ applicationMap = CollectionUtils.newMutationHookedMap(applicationMap,
+ _applicationBeanChecker);
+ }
+ else
+ {
+ _applicationBeanChecker = null;
+ }
}
else
{
- _applicationMap = applicationMap;
+ _sessionBeanChecker = null;
+ _applicationBeanChecker = null;
+
+ if (checkSession)
+ {
+ sessionMap = CollectionUtils.getCheckedSerializationMap(sessionMap, true);
+ }
+
+ if (checkApplication)
+ {
+ applicationMap = CollectionUtils.getCheckedSerializationMap(applicationMap, false);
+ }
}
- }
+
+ _sessionMap = sessionMap;
+ _applicationMap = applicationMap;
+ }
- protected ExternalContext getExternalContext()
+ /**
+ * Unregisters the checking of the specified session attribute
+ * @param external ExternalContext
+ * @param key Name of session attribute to unregister
+ */
+ public void unregisterSessionAttribute(ExternalContext external, String key)
{
- return _extContext;
+ SerializationChecker checker = SerializationChecker.getSerializationChecker(external, false);
+
+ if (checker != null)
+ {
+ if (_sessionBeanChecker != null)
+ {
+ _sessionBeanChecker.unregisterAttribute(key);
+ }
+ }
}
+ /**
+ * Unregisters the checking of the specified session attribute
+ * @param external ExternalContext
+ * @param key Name of session attribute to unregister
+ */
+ public void unregisterApplicationAttribute(ExternalContext external, String key)
+ {
+ SerializationChecker checker = SerializationChecker.getSerializationChecker(external, false);
+
+ if (checker != null)
+ {
+ if (_applicationBeanChecker != null)
+ {
+ _applicationBeanChecker.unregisterAttribute(key);
+ }
+ }
+ }
+
+ /**
+ * Return a wrapped HttpServletRequest if necessary to implement the checking features
+ * @param request
+ * @return
+ */
+ public HttpServletRequest getWrappedRequest(HttpServletRequest request)
+ {
+ if (_sessionBeanChecker != null)
+ {
+ return new SessionBeanTracker(request, _sessionBeanChecker, _sessionMap, _applicationMap);
+ }
+ else
+ {
+ return request;
+ }
+ }
+
+ /**
+ * Returns the potentially wrapped Session Map
+ * @return
+ */
public Map<String, Object> getSessionMap()
{
return _sessionMap;
}
+ /**
+ * Returns the potentially wrapped Application Map
+ * @return
+ */
public Map<String, Object> getApplicationMap()
{
return _applicationMap;
}
+
+ /**
+ * Check the session and application for mutations if configured to do so
+ */
+ public void checkForMutations()
+ {
+ if (_sessionBeanChecker != null)
+ _sessionBeanChecker.checkForMutations();
+
+ if (_applicationBeanChecker != null)
+ _applicationBeanChecker.checkForMutations();
+ }
- private final ExternalContext _extContext;
- private final Map _sessionMap;
- private final Map _applicationMap;
+ /**
+ * Wraps the HttpServletRequest so that we can return a wrapped Session so that we can catch
+ * changes to the Session attributes and/or return a wrapped ServletContext so that we can
+ * catch changes to the SevletContext attributes.
+ */
+ private static class SessionBeanTracker extends HttpServletRequestWrapper
+ {
+ public SessionBeanTracker(
+ HttpServletRequest request,
+ MutatedBeanChecker sessionBeanChecker,
+ Map<String, Object> sessionMap,
+ Map<String, Object> applicationMap)
+ {
+ super(request);
+
+ _wrappedSession = new SessionWrapper(request.getSession(),
+ sessionBeanChecker,
+ sessionMap,
+ applicationMap);
+ }
+
+ @Override
+ public HttpSession getSession()
+ {
+ return _wrappedSession;
+ }
+
+ @Override
+ public HttpSession getSession(boolean p1)
+ {
+ return _wrappedSession;
+ }
+
+ /**
+ * Wraps the HttpSession sso that we can catch
+ * changes to the Session attributes and/or return a wrapped ServletContext so that we can
+ * catch changes to the SevletContext attributes.
+ */
+ private static final class SessionWrapper implements HttpSession
+ {
+ SessionWrapper(
+ HttpSession session,
+ MutatedBeanChecker sessionChecker,
+ Map<String, Object> sessionMap,
+ Map<String, Object> applicationMap)
+ {
+ _delegate = session;
+ _sessionChecker = sessionChecker;
+ _sessionMap = sessionMap;
+ // determine whether we need to return a wrapped ServletContext as well
+ if (applicationMap != null)
+ {
+ _wrappedContext = new ContextWrapper(session.getServletContext(), applicationMap);
+ }
+ else
+ {
+ _wrappedContext = null;
+ }
+ }
+
+ public long getCreationTime()
+ {
+ return _delegate.getCreationTime();
+ }
+
+ public String getId()
+ {
+ return _delegate.getId();
+ }
+
+ public long getLastAccessedTime()
+ {
+ return _delegate.getLastAccessedTime();
+ }
+
+ public ServletContext getServletContext()
+ {
+ if (_wrappedContext != null)
+ {
+ return _wrappedContext;
+ }
+ else
+ {
+ return _delegate.getServletContext();
+ }
+ }
+
+ public void setMaxInactiveInterval(int maxInterval)
+ {
+ _delegate.setMaxInactiveInterval(maxInterval);
+ }
+
+ public int getMaxInactiveInterval()
+ {
+ return _delegate.getMaxInactiveInterval();
+ }
+
+ public HttpSessionContext getSessionContext()
+ {
+ return _delegate.getSessionContext();
+ }
+
+ public Object getAttribute(String attrName)
+ {
+ return _delegate.getAttribute(attrName);
+ }
+
+ public Object getValue(String attrName)
+ {
+ return _delegate.getValue(attrName);
+ }
+
+ public Enumeration getAttributeNames()
+ {
+ return _delegate.getAttributeNames();
+ }
+
+ public String[] getValueNames()
+ {
+ return _delegate.getValueNames();
+ }
+
+ /**
+ * Implement to delegate and inform the sessionChecker that the attribute is dirty
+ * @param key
+ * @param value
+ */
+ public void setAttribute(String key, Object value)
+ {
+ _delegate.setAttribute(key, value);
+ _sessionChecker.writeNotify(_sessionMap, key, value);
+ }
+
+ /**
+ * Implement to delegate and inform the sessionChecker that the attribute is dirty
+ * @param key
+ * @param value
+ */
+ public void putValue(String key, Object value)
+ {
+ _delegate.putValue(key, value);
+ _sessionChecker.writeNotify(_sessionMap, key, value);
+ }
+
+ /**
+ * Implement to delegate and inform the sessionChecker that the attribute is dirty
+ * @param key
+ */
+ public void removeAttribute(String key)
+ {
+ _delegate.removeAttribute(key);
+ _sessionChecker.removeNotify(_sessionMap, key);
+ }
+
+ /**
+ * Implement to delegate and inform the sessionChecker that the attribute is dirty
+ * @param key
+ */
+ public void removeValue(String key)
+ {
+ _delegate.removeValue(key);
+ _sessionChecker.removeNotify(_sessionMap, key);
+ }
+
+ /**
+ * Implement to delegate and inform the sessionChecker that all atrributes are dirty since
+ * the session has been blown away
+ */
+ public void invalidate()
+ {
+ _delegate.invalidate();
+ _sessionChecker.clearCheckedValues();
+ }
+
+ public boolean isNew()
+ {
+ return _delegate.isNew();
+ }
+
+ private final HttpSession _delegate;
+ private final MutatedBeanChecker _sessionChecker;
+ private final Map<String, Object> _sessionMap;
+ private final ServletContext _wrappedContext;
+ }
+
+ private final HttpSession _wrappedSession;
+ }
+
+ private final MutatedBeanChecker _sessionBeanChecker;
+ private final MutatedBeanChecker _applicationBeanChecker;
+
+ private final Map<String, Object> _sessionMap;
+ private final Map<String, Object> _applicationMap;
}
+
+ private static final String _CHECKED_MAPS_KEY = MutatedBeanChecker.class.getName() +"#MAPS";
+
+ private static final String _SERIALIZATION_CHECKER_KEY =
+ CheckSerializationConfigurator.class.getName() + "#CHECKER";
}
Modified: myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java?rev=1028150&r1=1028149&r2=1028150&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java (original)
+++ myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/GlobalConfiguratorImpl.java Thu Oct 28 00:40:23 2010
@@ -19,22 +19,16 @@
package org.apache.myfaces.trinidadinternal.config;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import java.util.concurrent.atomic.AtomicReference;
import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-
import javax.servlet.ServletRequest;
-
import javax.servlet.ServletRequestWrapper;
-
import javax.servlet.http.HttpServletRequest;
import org.apache.myfaces.trinidad.config.Configurator;
@@ -45,6 +39,9 @@ import org.apache.myfaces.trinidad.loggi
import org.apache.myfaces.trinidad.skin.SkinFactory;
import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
import org.apache.myfaces.trinidad.util.ComponentReference;
+import org.apache.myfaces.trinidad.util.ExternalContextUtils;
+import org.apache.myfaces.trinidad.util.RequestStateMap;
+import org.apache.myfaces.trinidad.util.RequestType;
import org.apache.myfaces.trinidadinternal.context.RequestContextFactoryImpl;
import org.apache.myfaces.trinidadinternal.context.external.ServletCookieMap;
import org.apache.myfaces.trinidadinternal.context.external.ServletRequestHeaderMap;
@@ -54,9 +51,6 @@ import org.apache.myfaces.trinidadintern
import org.apache.myfaces.trinidadinternal.context.external.ServletRequestParameterValuesMap;
import org.apache.myfaces.trinidadinternal.skin.SkinFactoryImpl;
import org.apache.myfaces.trinidadinternal.skin.SkinUtils;
-import org.apache.myfaces.trinidad.util.ExternalContextUtils;
-import org.apache.myfaces.trinidad.util.RequestStateMap;
-import org.apache.myfaces.trinidad.util.RequestType;
/**
* This is the implementation of the Trinidad's Global configurator. It provides the entry point for
@@ -414,7 +408,7 @@ public final class GlobalConfiguratorImp
}
finally
{
- //Do cleanup of anything which may have use the thread local manager durring
+ //Do cleanup of anything which may have use the thread local manager during
//init.
_releaseManagedThreadLocals();
}
Modified: myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PageFlowScopeMap.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PageFlowScopeMap.java?rev=1028150&r1=1028149&r2=1028150&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PageFlowScopeMap.java (original)
+++ myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/PageFlowScopeMap.java Thu Oct 28 00:40:23 2010
@@ -368,7 +368,7 @@ class PageFlowScopeMap implements Map<St
static private TokenCache _getRootTokenCache(FacesContext context,
int lifetime)
{
- return TokenCache.getTokenCacheFromSession(context,
+ return TokenCache.getTokenCacheFromSession(context.getExternalContext(),
_PAGE_FLOW_SCOPE_CACHE,
true,
lifetime);
@@ -416,6 +416,7 @@ class PageFlowScopeMap implements Map<St
// =-=AEW Make transient for efficiency
private PageFlowScopeMap _parent;
private TokenCache _children;
+ private static final long serialVersionUID = 1L;
}
// DELETE AFTER DIALOG SERVICE IS CLEANED UP
@@ -425,7 +426,8 @@ class PageFlowScopeMap implements Map<St
private String _token;
private HashMap<String, Object> _map;
- static private final String _PAGE_FLOW_SCOPE_CACHE =
+ private static final String _PAGE_FLOW_SCOPE_CACHE =
"org.apache.myfaces.trinidadinternal.application.PageFlowScope";
- static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(PageFlowScopeMap.class);
+ private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(PageFlowScopeMap.class);
+ private static final long serialVersionUID = 1L;
}
Modified: myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/SubKeyMap.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/SubKeyMap.java?rev=1028150&r1=1028149&r2=1028150&view=diff
==============================================================================
--- myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/SubKeyMap.java (original)
+++ myfaces/trinidad/branches/trinidad-1.2.x/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/SubKeyMap.java Thu Oct 28 00:40:23 2010
@@ -104,7 +104,7 @@ final public class SubKeyMap<V> extends
public Set<Map.Entry<String, V>> entrySet()
{
if (_entrySet == null)
- _entrySet = new Entries<V>();
+ _entrySet = new Entries();
return _entrySet;
}
@@ -131,7 +131,7 @@ final public class SubKeyMap<V> extends
//
// Set implementation for SubkeyMap.entrySet()
//
- private class Entries<V> extends AbstractSet<Map.Entry<String, V>>
+ private class Entries extends AbstractSet<Map.Entry<String, V>>
{
public Entries()
{
@@ -145,7 +145,7 @@ final public class SubKeyMap<V> extends
// exceptions. Consequently, gather the keys in a list
// and iterator over that.
List<String> keyList = _gatherKeys();
- return new EntryIterator<V>(keyList.iterator());
+ return new EntryIterator(keyList.iterator());
}
@Override
@@ -193,7 +193,7 @@ final public class SubKeyMap<V> extends
}
}
- private class EntryIterator<V> implements Iterator<Map.Entry<String, V>>
+ private class EntryIterator implements Iterator<Map.Entry<String, V>>
{
public EntryIterator(Iterator<String> iterator)
{
@@ -209,7 +209,7 @@ final public class SubKeyMap<V> extends
{
String baseKey = _iterator.next();
_currentKey = baseKey;
- return new Entry<V>(baseKey);
+ return new Entry(baseKey);
}
public void remove()
@@ -226,7 +226,7 @@ final public class SubKeyMap<V> extends
private String _currentKey;
}
- private class Entry<V> implements Map.Entry<String, V>
+ private class Entry implements Map.Entry<String, V>
{
public Entry(String baseKey)
{