myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mark Struberg <strub...@yahoo.de>
Subject Re: svn commit: r1409414 - in /myfaces/core/trunk/impl: ./ src/main/java/org/apache/myfaces/renderkit/
Date Wed, 14 Nov 2012 22:37:27 GMT
That is ONE strategy! There are tons of others. Plus half of your 10++ inner classes was waste of code!

If you do it pluggable, then do it for real!

If the viewId is not needed then let's get rid of it COMPLETELY!

It just doesn't make sense to only use the hashCode. Plus the encryption of that stuff takes SOOOOO much more resources that it just makes no sense to spare a few bytes.


LieGrue,
strub



----- Original Message -----
> From: Leonardo Uribe <lu4242@gmail.com>
> To: MyFaces Development <dev@myfaces.apache.org>; Mark Struberg <struberg@yahoo.de>
> Cc: 
> Sent: Wednesday, November 14, 2012 11:24 PM
> Subject: Re: svn commit: r1409414 - in /myfaces/core/trunk/impl: ./ src/main/java/org/apache/myfaces/renderkit/
> 
> Hi
> 
> 2012/11/14 Mark Struberg <struberg@yahoo.de>:
>>  Leo, there was a reason I removed it.
>> 
>> 
>>  Even after discussing this over 10 mails in a private thread you don't 
> get it it seems. I will open a VOTE about principal design fundamentals and we 
> will act according to this.
>> 
>>  Just you be prepated: A HASH IS NOT UNIQUE!
>> 
> 
> But I have told you multiple times, the algorithm does not rely on the
> hash to be unique, relies on the counter.
> 
>>  Also saying in the mails you understand and then doing the same crazy code 
> again is just plain ******
>> 
>>  I gonna revert it now and will write up the VOTE
> 
> The best way to resolve this is putting the arguments on the table and
> vote over that, right? after the vote we can do the necessary changes
> over the code. I have committed the fix that I suppose is correct.
> 
> regards,
> 
> Leonardo
> 
>> 
>>  LieGrue,
>>  strub
>> 
>> 
>> 
>> 
>>  ----- Original Message -----
>>>  From: "lu4242@apache.org" <lu4242@apache.org>
>>>  To: commits@myfaces.apache.org
>>>  Cc:
>>>  Sent: Wednesday, November 14, 2012 10:23 PM
>>>  Subject: svn commit: r1409414 - in /myfaces/core/trunk/impl: ./ 
> src/main/java/org/apache/myfaces/renderkit/
>>> 
>>>  Author: lu4242
>>>  Date: Wed Nov 14 21:23:35 2012
>>>  New Revision: 1409414
>>> 
>>>  URL: http://svn.apache.org/viewvc?rev=1409414&view=rev
>>>  Log:
>>>  MYFACES-3638 revert commit 1408993 to include later solution without
>>>  refactoring.
>>> 
>>>  Added:
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/SessionIdGenerator.java
>>>        - copied unchanged from r1408992,
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/SessionIdGenerator.java
>>>  Removed:
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/CounterKeyFactory.java
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/KeyFactory.java
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/RandomKeyFactory.java
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/SecureRandomKeyFactory.java
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/SerializedViewKey.java
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/SessionViewStorageFactory.java
>>>  Modified:
>>>      myfaces/core/trunk/impl/   (props changed)
>>> 
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java
>>> 
>>>  Propchange: myfaces/core/trunk/impl/
>>> 
> ------------------------------------------------------------------------------
>>>  --- svn:ignore (original)
>>>  +++ svn:ignore Wed Nov 14 21:23:35 2012
>>>  @@ -7,7 +7,8 @@ target
>>>  *.iml
>>>  *.ipr
>>>  *.iws
>>>  -.idea
>>>  .settings
>>>  +
>>>  cobertura.ser
>>>  +
>>>  test-output
>>> 
>>>  Modified:
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java
>>>  URL:
>>> 
> http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java?rev=1409414&r1=1409413&r2=1409414&view=diff
>>> 
> ==============================================================================
>>>  ---
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java
>>>  (original)
>>>  +++
>>> 
> myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java
>>>  Wed Nov 14 21:23:35 2012
>>>  @@ -30,16 +30,21 @@ import java.security.AccessController;
>>>  import java.security.PrivilegedActionException;
>>>  import java.security.PrivilegedExceptionAction;
>>>  import java.util.ArrayList;
>>>  +import java.util.Arrays;
>>>  import java.util.HashMap;
>>>  import java.util.List;
>>>  import java.util.Map;
>>>  +import java.util.Random;
>>>  import java.util.logging.Level;
>>>  import java.util.logging.Logger;
>>>  import java.util.zip.GZIPInputStream;
>>>  import java.util.zip.GZIPOutputStream;
>>>  +import javax.faces.application.ProjectStage;
>>> 
>>>  import javax.faces.context.ExternalContext;
>>>  import javax.faces.context.FacesContext;
>>>  +import org.apache.commons.codec.DecoderException;
>>>  +import org.apache.commons.codec.binary.Hex;
>>> 
>>>  import org.apache.commons.collections.map.AbstractReferenceMap;
>>>  import org.apache.commons.collections.map.ReferenceMap;
>>>  @@ -52,22 +57,22 @@ import org.apache.myfaces.shared.util.We
>>>  class ServerSideStateCacheImpl extends StateCache<Object, Object>
>>>  {
>>>       private static final Logger log =
>>>  Logger.getLogger(ServerSideStateCacheImpl.class.getName());
>>>  -
>>>  -    private static final String SERIALIZED_VIEW_SESSION_ATTR=
>>>  +
>>>  +    private static final String SERIALIZED_VIEW_SESSION_ATTR=
>>>           ServerSideStateCacheImpl.class.getName() +
>>>  ".SERIALIZED_VIEW";
>>>  -
>>>  -    private static final String RESTORED_SERIALIZED_VIEW_REQUEST_ATTR 
> =
>>>  +
>>>  +    private static final String RESTORED_SERIALIZED_VIEW_REQUEST_ATTR 
> =
>>>           ServerSideStateCacheImpl.class.getName() +
>>>  ".RESTORED_SERIALIZED_VIEW";
>>> 
>>>  -    private static final String RESTORED_VIEW_KEY_REQUEST_ATTR =
>>>  +    private static final String RESTORED_VIEW_KEY_REQUEST_ATTR =
>>>           ServerSideStateCacheImpl.class.getName() +
>>>  ".RESTORED_VIEW_KEY";
>>>  -
>>>  +
>>>       /**
>>>        * Defines the amount (default = 20) of the latest views are 
> stored in
>>>  session.
>>>  -     *
>>>  +     *
>>>        * <p>Only applicable if state saving method is 
> "server" (=
>>>  default).
>>>        * </p>
>>>  -     *
>>>  +     *
>>>        */
>>>       
> @JSFWebConfigParam(defaultValue="20",since="1.1",
>>>  classType="java.lang.Integer", group="state",
>>>  tags="performance")
>>>       private static final String NUMBER_OF_VIEWS_IN_SESSION_PARAM =
>>>  "org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION";
>>>  @@ -75,8 +80,8 @@ class ServerSideStateCacheImpl extends S
>>>       /**
>>>        * Indicates the amount of views (default is not active) that 
> should be
>>>  stored in session between sequential
>>>        * POST or POST-REDIRECT-GET if
>>>  org.apache.myfaces.USE_FLASH_SCOPE_PURGE_VIEWS_IN_SESSION is true.
>>>  -     *
>>>  -     * <p>Only applicable if state saving method is 
> "server" (=
>>>  default). For example, if this param has value = 2 and
>>>  +     *
>>>  +     * <p>Only applicable if state saving method is 
> "server" (=
>>>  default). For example, if this param has value = 2 and
>>>        * in your custom webapp there is a form that is clicked 3 times, 
> only 2
>>>  views
>>>        * will be stored and the third one (the one stored the first 
> time) will be
>>>        * removed from session, even if the view can
>>>  @@ -88,14 +93,14 @@ class ServerSideStateCacheImpl extends S
>>>       @JSFWebConfigParam(since="2.0.6",
>>>  classType="java.lang.Integer", group="state",
>>>  tags="performance")
>>>       private static final String 
> NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION_PARAM
>>>               =
>>>  "org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION";
>>>  -
>>>  +
>>>       /**
>>>        * Default value for
>>>  <code>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</code> 
> context
>>>  parameter.
>>>        */
>>>       private static final int DEFAULT_NUMBER_OF_VIEWS_IN_SESSION = 20;
>>> 
>>>       /**
>>>  -     * Indicate if the state should be serialized before save it on 
> the
>>>  session.
>>>  +     * Indicate if the state should be serialized before save it on 
> the
>>>  session.
>>>        * <p>
>>>        * Only applicable if state saving method is "server" (=
>>>  default).
>>>        * If <code>true</code> (default) the state will be 
> serialized
>>>  to a byte stream before it is written to the session.
>>>  @@ -107,7 +112,7 @@ class ServerSideStateCacheImpl extends S
>>> 
>>>       /**
>>>        * Indicates that the serialized state will be compressed before 
> it is
>>>  written to the session. By default true.
>>>  -     *
>>>  +     *
>>>        * Only applicable if state saving method is "server" (= 
> default)
>>>  and if
>>>        * 
> <code>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</code>
>>>  is <code>true</code> (= default).
>>>        * If <code>true</code> (default) the serialized state 
> will be
>>>  compressed before it is written to the session.
>>>  @@ -140,38 +145,38 @@ class ServerSideStateCacheImpl extends S
>>>        * <p>
>>>        * By default no cache is used, so views removed from session 
> became
>>>  phantom references.
>>>        * </p>
>>>  -     * <ul>
>>>  -     * <li> off, no: default, no cache is used</li>
>>>  +     * <ul>
>>>  +     * <li> off, no: default, no cache is used</li>
>>>        * <li> hard-soft: use an 
> ReferenceMap(AbstractReferenceMap.HARD,
>>>  AbstractReferenceMap.SOFT)</li>
>>>        * <li> soft: use an ReferenceMap(AbstractReferenceMap.SOFT,
>>>  AbstractReferenceMap.SOFT, true) </li>
>>>        * <li> soft-weak: use an 
> ReferenceMap(AbstractReferenceMap.SOFT,
>>>  AbstractReferenceMap.WEAK, true) </li>
>>>        * <li> weak: use an ReferenceMap(AbstractReferenceMap.WEAK,
>>>  AbstractReferenceMap.WEAK, true) </li>
>>>        * </ul>
>>>  -     *
>>>  +     *
>>>        */
>>>       @JSFWebConfigParam(defaultValue="off", 
> expectedValues="off,
>>>  no, hard-soft, soft, soft-weak, weak",
>>>                          since="1.2.5", 
> group="state",
>>>  tags="performance")
>>>       private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE =
>>>  "org.apache.myfaces.CACHE_OLD_VIEWS_IN_SESSION_MODE";
>>>  -
>>>  +
>>>       /**
>>>  -     * This option uses an hard-soft ReferenceMap, but it could cause 
> a
>>>  +     * This option uses an hard-soft ReferenceMap, but it could cause 
> a
>>>        * memory leak, because the keys are not removed by any method
>>>        * (MYFACES-1660). So use with caution.
>>>        */
>>>       private static final String 
> CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT =
>>>  "hard-soft";
>>>  -
>>>  +
>>>       private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT =
>>>  "soft";
>>>  -
>>>  +
>>>       private static final String 
> CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK =
>>>  "soft-weak";
>>>  -
>>>  +
>>>       private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK =
>>>  "weak";
>>>  -
>>>  +
>>>       private static final String CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF =
>>>  "off";
>>> 
>>>       /**
>>>        * Allow use flash scope to keep track of the views used in 
> session and the
>>>  previous ones,
>>>        * so server side state saving can delete old views even if
>>>  POST-REDIRECT-GET pattern is used.
>>>  -     *
>>>  +     *
>>>        * <p>
>>>        * Only applicable if state saving method is "server" (=
>>>  default).
>>>        * The default value is false.</p>
>>>  @@ -183,84 +188,90 @@ class ServerSideStateCacheImpl extends S
>>>       private static final String 
> RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_NONE =
>>>  "none";
>>>       private static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM = 
> "secureRandom";
>>>       private static final String 
> RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_RANDOM =
>>>  "random";
>>>  -
>>>  +
>>>       /**
>>>        * Adds a random key to the generated view state session token.
>>>        */
>>>  -    @JSFWebConfigParam(since="2.1.9, 2.0.15",
>>>  expectedValues="secureRandom, random, none",
>>>  +    @JSFWebConfigParam(since="2.1.9, 2.0.15",
>>>  expectedValues="secureRandom, random, none",
>>>               defaultValue="none", group="state")
>>>       private static final String 
> RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_PARAM
>>>               =
>>>  "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN";
>>>  -    private static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_PARAM_DEFAULT =
>>>  +    private static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_PARAM_DEFAULT =
>>>               RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_NONE;
>>> 
>>>       /**
>>>        * Set the default length of the random key added to the view 
> state session
>>>  token.
>>>  -     * By default is 8.
>>>  +     * By default is 8.
>>>        */
>>>       @JSFWebConfigParam(since="2.1.9, 2.0.15",
>>>  defaultValue="8", group="state")
>>>  -    static final String 
> RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM
>>>  +    private static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM
>>>               =
>>> 
> "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH";
>>>  -    static final int
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM_DEFAULT = 8;
>>>  +    private static final int
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM_DEFAULT = 8;
>>> 
>>>       /**
>>>  -     * Sets the random class to initialize the secure random id 
> generator.
>>>  +     * Sets the random class to initialize the secure random id 
> generator.
>>>        * By default it uses java.security.SecureRandom
>>>        */
>>>       @JSFWebConfigParam(since="2.1.9, 2.0.15",
>>>  group="state")
>>>  -    static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_CLASS_PARAM
>>>  +    private static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_CLASS_PARAM
>>>               =
>>> 
> "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_CLASS";
>>>  -
>>>  +
>>>       /**
>>>        * Sets the random provider to initialize the secure random id 
> generator.
>>>        */
>>>       @JSFWebConfigParam(since="2.1.9, 2.0.15",
>>>  group="state")
>>>  -    static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_PROVIDER_PARAM
>>>  +    private static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_PROVIDER_PARAM
>>>               =
>>> 
> "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_PROVIDER";
>>>  -
>>>  +
>>>       /**
>>>  -     * Sets the random algorithm to initialize the secure random id 
> generator.
>>>  +     * Sets the random algorithm to initialize the secure random id 
> generator.
>>>        * By default is SHA1PRNG
>>>        */
>>>       @JSFWebConfigParam(since="2.1.9, 2.0.15",
>>>  defaultValue="SHA1PRNG", group="state")
>>>  -    static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITM_PARAM
>>>  +    private static final String
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITM_PARAM
>>>               =
>>> 
> "org.apache.myfaces.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITM";
>>>  -
>>>  -
>>>  +
>>>  +
>>>       private static final int UNCOMPRESSED_FLAG = 0;
>>>       private static final int COMPRESSED_FLAG = 1;
>>>  -
>>>  +
>>>       private static final Object[] EMPTY_STATES = new Object[]{null, 
> null};
>>> 
>>>  +    //private static final int JSF_SEQUENCE_INDEX = 0;
>>>  +
>>>       private Boolean _useFlashScopePurgeViewsInSession = null;
>>>  -
>>>  +
>>>       private Integer _numberOfSequentialViewsInSession = null;
>>>       private boolean _numberOfSequentialViewsInSessionSet = false;
>>> 
>>>  +    //private final KeyFactory keyFactory;
>>>       private SessionViewStorageFactory sessionViewStorageFactory;
>>> 
>>>       public ServerSideStateCacheImpl()
>>>       {
>>>           FacesContext facesContext = FacesContext.getCurrentInstance();
>>>           String randomMode =
>>> 
> WebConfigParamUtils.getStringInitParameter(facesContext.getExternalContext(),
>>>  -                RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_PARAM,
>>>  +                RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_PARAM,
>>>                   RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_PARAM_DEFAULT);
>>>           if
>>> 
> (RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM.equals(randomMode))
>>>           {
>>>  -            sessionViewStorageFactory = new SessionViewStorageFactory(
>>>  +            //keyFactory = new SecureRandomKeyFactory(facesContext);
>>>  +            sessionViewStorageFactory = new 
> RandomSessionViewStorageFactory(
>>>                       new SecureRandomKeyFactory(facesContext));
>>>           }
>>>           else if
>>>  (RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_RANDOM.equals(randomMode))
>>>           {
>>>  -            sessionViewStorageFactory = new SessionViewStorageFactory(
>>>  +            //keyFactory = new RandomKeyFactory(facesContext);
>>>  +            sessionViewStorageFactory = new 
> RandomSessionViewStorageFactory(
>>>                       new RandomKeyFactory(facesContext));
>>>           }
>>>           else
>>>           {
>>>  -            sessionViewStorageFactory = new 
> SessionViewStorageFactory(new
>>>  CounterKeyFactory());
>>>  +            //keyFactory = new CounterKeyFactory();
>>>  +            sessionViewStorageFactory = new
>>>  CounterSessionViewStorageFactory(new CounterKeyFactory());
>>>           }
>>>       }
>>>  -
>>>  +
>>>       //------------------------------------- METHODS COPIED FROM
>>>  JspStateManagerImpl--------------------------------
>>> 
>>>       protected Object getServerStateId(FacesContext facesContext, 
> Object state)
>>>  @@ -285,16 +296,16 @@ class ServerSideStateCacheImpl extends S
>>>           }
>>> 
>>>           Map<Object,Object> attributeMap = 
> context.getAttributes();
>>>  -
>>>  +
>>>           SerializedViewKey key = null;
>>>           if 
> (getNumberOfSequentialViewsInSession(context.getExternalContext())
>>>  != null &&
>>>               
> getNumberOfSequentialViewsInSession(context.getExternalContext())
>>>>   0)
>>>           {
>>>               key = (SerializedViewKey)
>>>  attributeMap.get(RESTORED_VIEW_KEY_REQUEST_ATTR);
>>>  -
>>>  +
>>>               if (key == null )
>>>               {
>>>  -                if
>>>  (isUseFlashScopePurgeViewsInSession(context.getExternalContext()) 
> &&
>>>  +                if
>>>  (isUseFlashScopePurgeViewsInSession(context.getExternalContext()) 
> &&
>>> 
>>>  Boolean.TRUE.equals(context.getExternalContext().getRequestMap()
>>> 
>>>  .get("oam.Flash.REDIRECT.PREVIOUSREQUEST")))
>>>                   {
>>>  @@ -303,7 +314,7 @@ class ServerSideStateCacheImpl extends S
>>>                   }
>>>               }
>>>           }
>>>  -
>>>  +
>>>           SerializedViewKey nextKey =
>>>  getSessionViewStorageFactory().createSerializedViewKey(
>>>                   context, context.getViewRoot().getViewId(),
>>>  getNextViewSequence(context));
>>>           viewCollection.add(context, serializeView(context, 
> serializedView),
>>>  nextKey, key);
>>>  @@ -339,14 +350,14 @@ class ServerSideStateCacheImpl extends S
>>>                   }
>>>               }
>>>               attributeMap.put(RESTORED_SERIALIZED_VIEW_REQUEST_ATTR,
>>>  serializedView);
>>>  -
>>>  +
>>>               if (getNumberOfSequentialViewsInSession(externalContext) 
> != null
>>>  &&
>>>                   getNumberOfSequentialViewsInSession(externalContext) 
>>  0)
>>>               {
>>>                   SerializedViewKey key = 
> getSessionViewStorageFactory().
>>>                           createSerializedViewKey(context, viewId, 
> sequence);
>>>                   attributeMap.put(RESTORED_VIEW_KEY_REQUEST_ATTR, key);
>>>  -
>>>  +
>>>                   if 
> (isUseFlashScopePurgeViewsInSession(externalContext))
>>>                   {
>>> 
>>>  externalContext.getFlash().put(RESTORED_VIEW_KEY_REQUEST_ATTR, key);
>>>  @@ -418,7 +429,7 @@ class ServerSideStateCacheImpl extends S
>>>                   //Object[] stateArray = (Object[]) serializedView;
>>> 
>>>                   ObjectOutputStream out = new ObjectOutputStream(os);
>>>  -
>>>  +
>>>                   out.writeObject(serializedView);
>>>                   //out.writeObject(stateArray[0]);
>>>                   //out.writeObject(stateArray[1]);
>>>  @@ -513,9 +524,9 @@ class ServerSideStateCacheImpl extends S
>>>                       final ObjectInputStream in = new
>>>  MyFacesObjectInputStream(is);
>>>                       ois = in;
>>>                       Object object = null;
>>>  -                    if (System.getSecurityManager() != null)
>>>  +                    if (System.getSecurityManager() != null)
>>>                       {
>>>  -                        object = AccessController.doPrivileged(new
>>>  PrivilegedExceptionAction<Object>()
>>>  +                        object = AccessController.doPrivileged(new
>>>  PrivilegedExceptionAction<Object>()
>>>                           {
>>>                               public Object run() throws
>>>  PrivilegedActionException, IOException, ClassNotFoundException
>>>                               {
>>>  @@ -540,7 +551,7 @@ class ServerSideStateCacheImpl extends S
>>>                       }
>>>                   }
>>>               }
>>>  -            catch (PrivilegedActionException e)
>>>  +            catch (PrivilegedActionException e)
>>>               {
>>>                   log.log(Level.SEVERE, "Exiting deserializeView - 
> Could not
>>>  deserialize state: " + e.getMessage(), e);
>>>                   return null;
>>>  @@ -577,7 +588,7 @@ class ServerSideStateCacheImpl extends S
>>>               return null;
>>>           }
>>>       }
>>>  -
>>>  +
>>>       protected static class SerializedViewCollection implements 
> Serializable
>>>       {
>>>           private static final long serialVersionUID = 
> -3734849062185115847L;
>>>  @@ -585,8 +596,8 @@ class ServerSideStateCacheImpl extends S
>>>           private final List<SerializedViewKey> _keys
>>>                   = new
>>>  ArrayList<SerializedViewKey>(DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
>>>           private final Map<SerializedViewKey, Object> 
> _serializedViews =
>>>  new HashMap<SerializedViewKey, Object>();
>>>  -
>>>  -        private final Map<SerializedViewKey, SerializedViewKey>
>>>  _precedence =
>>>  +
>>>  +        private final Map<SerializedViewKey, SerializedViewKey>
>>>  _precedence =
>>>               new HashMap<SerializedViewKey, SerializedViewKey>();
>>> 
>>>           // old views will be hold as soft references which will be 
> removed by
>>>  @@ -609,7 +620,7 @@ class ServerSideStateCacheImpl extends S
>>>                   // into the map.
>>>                   state = null;
>>>               }
>>>  -
>>>  +
>>>               Integer maxCount = 
> getNumberOfSequentialViewsInSession(context);
>>>               if (maxCount != null)
>>>               {
>>>  @@ -647,7 +658,7 @@ class ServerSideStateCacheImpl extends S
>>>                     previousKey = _precedence.get(previousKey);
>>>                     count++;
>>>                   } while (previousKey != null && count < 
> maxCount);
>>>  -
>>>  +
>>>                   if (previousKey != null)
>>>                   {
>>>                       SerializedViewKey keyToRemove = 
> (SerializedViewKey)
>>>  previousKey;
>>>  @@ -670,7 +681,7 @@ class ServerSideStateCacheImpl extends S
>>>                           {
>>>                               _serializedViews.remove(keyToRemove);
>>>                           }
>>>  -
>>>  +
>>>                           keyToRemove = _precedence.remove(keyToRemove);
>>>                       }  while(keyToRemove != null);
>>>                   }
>>>  @@ -680,11 +691,11 @@ class ServerSideStateCacheImpl extends S
>>>               while (_keys.size() > views)
>>>               {
>>>                   key = _keys.remove(0);
>>>  -
>>>  +
>>>                   if (maxCount != null && maxCount > 0)
>>>                   {
>>>                       SerializedViewKey keyToRemove = 
> (SerializedViewKey) key;
>>>  -                    // Note in this case the key to delete is the 
> oldest one,
>>>  +                    // Note in this case the key to delete is the 
> oldest one,
>>>                       // so it could be at least one precedence, but to 
> be safe
>>>                       // do it with a loop.
>>>                       do
>>>  @@ -696,7 +707,7 @@ class ServerSideStateCacheImpl extends S
>>>                   if (_serializedViews.containsKey(key) &&
>>> 
>>> 
> !CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF.equals(getCacheOldViewsInSessionMode(context)))
>>>                   {
>>>  -
>>>  +
>>>                       getOldSerializedViewsMap().put(key,
>>>  _serializedViews.remove(key));
>>>                   }
>>>                   else
>>>  @@ -708,10 +719,10 @@ class ServerSideStateCacheImpl extends S
>>> 
>>>           protected Integer 
> getNumberOfSequentialViewsInSession(FacesContext
>>>  context)
>>>           {
>>>  -            return
>>> 
> WebConfigParamUtils.getIntegerInitParameter(context.getExternalContext(),
>>>  +            return
>>> 
> WebConfigParamUtils.getIntegerInitParameter(context.getExternalContext(),
>>>                       NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION_PARAM);
>>>           }
>>>  -
>>>  +
>>>           /**
>>>            * Reads the amount (default = 20) of views to be stored in 
> session.
>>>            * @see #NUMBER_OF_VIEWS_IN_SESSION_PARAM
>>>  @@ -755,7 +766,7 @@ class ServerSideStateCacheImpl extends S
>>>               FacesContext context = FacesContext.getCurrentInstance();
>>>               if (_oldSerializedViews == null && context != 
> null)
>>>               {
>>>  -                String cacheMode = 
> getCacheOldViewsInSessionMode(context);
>>>  +                String cacheMode = 
> getCacheOldViewsInSessionMode(context);
>>>                   if 
> (CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK.equals(cacheMode))
>>>                   {
>>>                       _oldSerializedViews = new
>>>  ReferenceMap(AbstractReferenceMap.WEAK, AbstractReferenceMap.WEAK, 
> true);
>>>  @@ -773,13 +784,13 @@ class ServerSideStateCacheImpl extends S
>>>                       _oldSerializedViews = new
>>>  ReferenceMap(AbstractReferenceMap.HARD, AbstractReferenceMap.SOFT);
>>>                   }
>>>               }
>>>  -
>>>  +
>>>               return _oldSerializedViews;
>>>           }
>>>  -
>>>  +
>>>           /**
>>>            * Reads the value of the
>>> 
> <code>org.apache.myfaces.CACHE_OLD_VIEWS_IN_SESSION_MODE</code>
>>>  context parameter.
>>>  -         *
>>>  +         *
>>>            * @since 1.2.5
>>>            * @param context
>>>            * @return constant indicating caching mode
>>>  @@ -800,7 +811,7 @@ class ServerSideStateCacheImpl extends S
>>>               else if
>>>  (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK))
>>>               {
>>>                   return CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK;
>>>  -            }
>>>  +            }
>>>               else if
>>>  (value.equalsIgnoreCase(CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK))
>>>               {
>>>                   return CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK;
>>>  @@ -814,7 +825,7 @@ class ServerSideStateCacheImpl extends S
>>>                   return CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF;
>>>               }
>>>           }
>>>  -
>>>  +
>>>           public Object get(SerializedViewKey key)
>>>           {
>>>               Object value = _serializedViews.get(key);
>>>  @@ -846,7 +857,172 @@ class ServerSideStateCacheImpl extends S
>>>           }
>>>       }
>>> 
>>>  +    /**
>>>  +     * Base implementation where all keys used to identify the state 
> of a view
>>>  should
>>>  +     * extend.
>>>  +     */
>>>  +    protected abstract static class SerializedViewKey implements 
> Serializable
>>>  +    {
>>>  +    }
>>>  +
>>>  +    /**
>>>  +     * Implementation of SerializedViewKey, where the hashCode of the 
> viewId is
>>>  used
>>>  +     * and the sequenceId is a numeric value.
>>>  +     */
>>>  +    private static class IntIntSerializedViewKey extends 
> SerializedViewKey
>>>  +        implements Serializable
>>>  +    {
>>>  +        private static final long serialVersionUID = 
> -1170697124386063642L;
>>>  +
>>>  +        private final int _viewId;
>>>  +        private final int _sequenceId;
>>>  +
>>>  +        public IntIntSerializedViewKey(int viewId, int sequence)
>>>  +        {
>>>  +            _sequenceId = sequence;
>>>  +            _viewId = viewId;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public boolean equals(Object obj)
>>>  +        {
>>>  +            if (obj == null)
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            if (getClass() != obj.getClass())
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            final IntIntSerializedViewKey other = 
> (IntIntSerializedViewKey)
>>>  obj;
>>>  +            if (this._viewId != other._viewId)
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            if (this._sequenceId != other._sequenceId)
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            return true;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public int hashCode()
>>>  +        {
>>>  +            int hash = 7;
>>>  +            hash = 83 * hash + this._viewId;
>>>  +            hash = 83 * hash + this._sequenceId;
>>>  +            return hash;
>>>  +        }
>>>  +    }
>>>  +
>>>  +    /**
>>>  +     * Implementation of SerializedViewKey, where the hashCode of the 
> viewId is
>>>  used
>>>  +     * and the sequenceId is a string value.
>>>  +     */
>>>  +    private static class IntByteArraySerializedViewKey extends
>>>  SerializedViewKey
>>>  +        implements Serializable
>>>  +    {
>>>  +        private final int _viewId;
>>>  +        private final byte[] _sequenceId;
>>>  +
>>>  +        public IntByteArraySerializedViewKey(int viewId, byte[] 
> sequence)
>>>  +        {
>>>  +            _sequenceId = sequence;
>>>  +            _viewId = viewId;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public boolean equals(Object obj)
>>>  +        {
>>>  +            if (obj == null)
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            if (getClass() != obj.getClass())
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            final IntByteArraySerializedViewKey other =
>>>  (IntByteArraySerializedViewKey) obj;
>>>  +            if (this._viewId != other._viewId)
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            if (!Arrays.equals(this._sequenceId, other._sequenceId))
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            return true;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public int hashCode()
>>>  +        {
>>>  +            int hash = 5;
>>>  +            hash = 37 * hash + this._viewId;
>>>  +            hash = 37 * hash + Arrays.hashCode(this._sequenceId);
>>>  +            return hash;
>>>  +        }
>>>  +    }
>>>  +
>>>  +
>>>  +    /**
>>>  +     * Implementation of SerializedViewKey, where the viewId and the 
> sequenceId
>>>  can be
>>>  +     * anything.
>>>  +     */
>>>  +    private static class ReferenceSerializedViewKey<I,K> extends
>>>  SerializedViewKey
>>>  +        implements Serializable
>>>  +    {
>>>  +        private static final long serialVersionUID = 
> -1170697124386063642L;
>>>  +
>>>  +        private final I _viewId;
>>>  +        private final K _sequenceId;
>>> 
>>>  +        public ReferenceSerializedViewKey()
>>>  +        {
>>>  +            _sequenceId = null;
>>>  +            _viewId = null;
>>>  +        }
>>>  +        public ReferenceSerializedViewKey(I viewId, K sequence)
>>>  +        {
>>>  +            _sequenceId = sequence;
>>>  +            _viewId = viewId;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public boolean equals(Object obj)
>>>  +        {
>>>  +            if (obj == null)
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            if (getClass() != obj.getClass())
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            final ReferenceSerializedViewKey<I, K> other =
>>>  (ReferenceSerializedViewKey<I, K>) obj;
>>>  +            if (this._viewId != other._viewId && (this._viewId 
> == null
>>>  || !this._viewId.equals(other._viewId)))
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            if (this._sequenceId != other._sequenceId &&
>>>  +                (this._sequenceId == null ||
>>>  !this._sequenceId.equals(other._sequenceId)))
>>>  +            {
>>>  +                return false;
>>>  +            }
>>>  +            return true;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public int hashCode()
>>>  +        {
>>>  +            int hash = 7;
>>>  +            hash = 83 * hash + (this._viewId != null ? 
> this._viewId.hashCode()
>>>  : 0);
>>>  +            hash = 83 * hash + (this._sequenceId != null ?
>>>  this._sequenceId.hashCode() : 0);
>>>  +            return hash;
>>>  +        }
>>>  +    }
>>>  +
>>>       //------------------------------------- METHOD FROM StateCache
>>>  ------------------------------------------------
>>> 
>>>       @Override
>>>  @@ -858,12 +1034,12 @@ class ServerSideStateCacheImpl extends S
>>>           }
>>>           //save state in server session
>>>           saveSerializedViewInServletSession(facesContext, 
> serializedView);
>>>  -
>>>  +
>>>           if (log.isLoggable(Level.FINEST))
>>>           {
>>>               log.finest("Exiting saveSerializedView - server-side 
> state
>>>  saving - saved state");
>>>           }
>>>  -
>>>  +
>>>           return encodeSerializedState(facesContext, serializedView);
>>>       }
>>> 
>>>  @@ -886,7 +1062,7 @@ class ServerSideStateCacheImpl extends S
>>>       {
>>>           return
>>>  getKeyFactory(facesContext).encode(getNextViewSequence(facesContext));
>>>       }
>>>  -
>>>  +
>>>       @Override
>>>       public boolean isWriteStateAfterRenderViewRequired(FacesContext
>>>  facesContext)
>>>       {
>>>  @@ -894,7 +1070,7 @@ class ServerSideStateCacheImpl extends S
>>>       }
>>> 
>>>       //------------------------------------- Custom methods
>>>  -----------------------------------------------------
>>>  -
>>>  +
>>>       private boolean isUseFlashScopePurgeViewsInSession(ExternalContext
>>>  externalContext)
>>>       {
>>>           if (_useFlashScopePurgeViewsInSession == null)
>>>  @@ -904,29 +1080,372 @@ class ServerSideStateCacheImpl extends S
>>>           }
>>>           return _useFlashScopePurgeViewsInSession;
>>>       }
>>>  -
>>>  +
>>>       private Integer 
> getNumberOfSequentialViewsInSession(ExternalContext
>>>  externalContext)
>>>       {
>>>           if (!_numberOfSequentialViewsInSessionSet)
>>>           {
>>>               _numberOfSequentialViewsInSession =
>>>  WebConfigParamUtils.getIntegerInitParameter(
>>>  -                    externalContext,
>>>  +                    externalContext,
>>>                       NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION_PARAM);
>>>               _numberOfSequentialViewsInSessionSet = true;
>>>           }
>>>           return _numberOfSequentialViewsInSession;
>>>       }
>>>  -
>>>  +
>>>       protected KeyFactory getKeyFactory(FacesContext facesContext)
>>>       {
>>>           //return keyFactory;
>>>           return sessionViewStorageFactory.getKeyFactory();
>>>       }
>>>  -
>>>  +
>>>       protected SessionViewStorageFactory getSessionViewStorageFactory()
>>>       {
>>>           return sessionViewStorageFactory;
>>>       }
>>>  +
>>> 
>>>  +    protected abstract static class KeyFactory<K, V>
>>>  +    {
>>>  +
>>>  +        /**
>>>  +         * Generates a unique key per session
>>>  +         *
>>>  +         * @param facesContext
>>>  +         * @return
>>>  +         */
>>>  +        public abstract K generateKey(FacesContext facesContext);
>>>  +
>>>  +        /**
>>>  +         * Encode a Key into a value that will be used as view state 
> session
>>>  token
>>>  +         *
>>>  +         * @param key
>>>  +         * @return
>>>  +         */
>>>  +        public abstract V encode(K key);
>>> 
>>>  +        /**
>>>  +         * Decode a view state session token into a key
>>>  +         *
>>>  +         * @param value
>>>  +         * @return
>>>  +         */
>>>  +        public abstract K decode(V value);
>>>  +
>>>  +    }
>>>  +
>>>  +    private static class CounterKeyFactory extends 
> KeyFactory<Integer,
>>>  String>
>>>  +    {
>>>  +        /**
>>>  +         * Take the counter from session scope and increment
>>>  +         *
>>>  +         * @param facesContext
>>>  +         * @return
>>>  +         */
>>>  +        @Override
>>>  +        public Integer generateKey(FacesContext facesContext)
>>>  +        {
>>>  +            ExternalContext externalContext =
>>>  facesContext.getExternalContext();
>>>  +            Object sessionObj = externalContext.getSession(true);
>>>  +            Integer sequence = null;
>>>  +            synchronized(sessionObj) // synchronized to increase 
> sequence if
>>>  multiple requests
>>>  +                                    // are handled at the same time 
> for the
>>>  session
>>>  +            {
>>>  +                Map<String, Object> map =
>>>  externalContext.getSessionMap();
>>>  +                sequence = (Integer) 
> map.get(RendererUtils.SEQUENCE_PARAM);
>>>  +                if(sequence == null || sequence.intValue() ==
>>>  Integer.MAX_VALUE)
>>>  +                {
>>>  +                    sequence = Integer.valueOf(1);
>>>  +                }
>>>  +                else
>>>  +                {
>>>  +                    sequence = Integer.valueOf(sequence.intValue() + 
> 1);
>>>  +                }
>>>  +                map.put(RendererUtils.SEQUENCE_PARAM, sequence);
>>>  +            }
>>>  +            return sequence;
>>>  +        }
>>>  +
>>>  +        public String encode(Integer sequence)
>>>  +        {
>>>  +            return Integer.toString(sequence, Character.MAX_RADIX);
>>>  +        }
>>>  +
>>>  +        public Integer decode(String serverStateId)
>>>  +        {
>>>  +             return Integer.valueOf((String) serverStateId,
>>>  Character.MAX_RADIX);
>>>  +        }
>>>  +    }
>>>  +
>>>  +    /**
>>>  +     * This factory generate a key composed by a counter and a random 
> number.
>>>  The
>>>  +     * counter ensures uniqueness, and the random number prevents 
> guess the
>>>  next
>>>  +     * session token.
>>>  +     */
>>>  +    private static class SecureRandomKeyFactory extends 
> KeyFactory<byte[],
>>>  String>
>>>  +    {
>>>  +        private final SessionIdGenerator sessionIdGenerator;
>>>  +        private final int length;
>>>  +
>>>  +        public SecureRandomKeyFactory(FacesContext facesContext)
>>>  +        {
>>>  +            length =
>>> 
> WebConfigParamUtils.getIntegerInitParameter(facesContext.getExternalContext(),
>>>  +                    
> RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM,
>>>  +
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM_DEFAULT);
>>>  +            sessionIdGenerator = new SessionIdGenerator();
>>>  +            sessionIdGenerator.setSessionIdLength(length);
>>>  +            String secureRandomClass =
>>>  WebConfigParamUtils.getStringInitParameter(
>>>  +                    facesContext.getExternalContext(),
>>>  +
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_CLASS_PARAM);
>>>  +            if (secureRandomClass != null)
>>>  +            {
>>>  +                
> sessionIdGenerator.setSecureRandomClass(secureRandomClass);
>>>  +            }
>>>  +            String secureRandomProvider =
>>>  WebConfigParamUtils.getStringInitParameter(
>>>  +                    facesContext.getExternalContext(),
>>>  +
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_PROVIDER_PARAM);
>>>  +            if (secureRandomProvider != null)
>>>  +            {
>>>  +
>>>  sessionIdGenerator.setSecureRandomProvider(secureRandomProvider);
>>>  +            }
>>>  +            String secureRandomAlgorithm =
>>>  WebConfigParamUtils.getStringInitParameter(
>>>  +                    facesContext.getExternalContext(),
>>>  +
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_ALGORITM_PARAM);
>>>  +            if (secureRandomAlgorithm != null)
>>>  +            {
>>>  +
>>>  sessionIdGenerator.setSecureRandomAlgorithm(secureRandomAlgorithm);
>>>  +            }
>>>  +        }
>>>  +
>>>  +        public Integer generateCounterKey(FacesContext facesContext)
>>>  +        {
>>>  +            ExternalContext externalContext =
>>>  facesContext.getExternalContext();
>>>  +            Object sessionObj = externalContext.getSession(true);
>>>  +            Integer sequence = null;
>>>  +            synchronized(sessionObj) // synchronized to increase 
> sequence if
>>>  multiple requests
>>>  +                                    // are handled at the same time 
> for the
>>>  session
>>>  +            {
>>>  +                Map<String, Object> map =
>>>  externalContext.getSessionMap();
>>>  +                sequence = (Integer) 
> map.get(RendererUtils.SEQUENCE_PARAM);
>>>  +                if(sequence == null || sequence.intValue() ==
>>>  Integer.MAX_VALUE)
>>>  +                {
>>>  +                    sequence = Integer.valueOf(1);
>>>  +                }
>>>  +                else
>>>  +                {
>>>  +                    sequence = Integer.valueOf(sequence.intValue() + 
> 1);
>>>  +                }
>>>  +                map.put(RendererUtils.SEQUENCE_PARAM, sequence);
>>>  +            }
>>>  +            return sequence;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public byte[] generateKey(FacesContext facesContext)
>>>  +        {
>>>  +            byte[] array = new byte[length];
>>>  +            byte[] key = new byte[length+4];
>>>  +
>>>  +            sessionIdGenerator.getRandomBytes(array);
>>>  +            for (int i = 0; i < array.length; i++)
>>>  +            {
>>>  +                key[i] = array[i];
>>>  +            }
>>>  +            int value = generateCounterKey(facesContext);
>>>  +            key[array.length] =  (byte) (value >>> 24);
>>>  +            key[array.length+1] =  (byte) (value >>> 16);
>>>  +            key[array.length+2] =  (byte) (value >>> 8);
>>>  +            key[array.length+3] =  (byte) (value);
>>>  +
>>>  +            return key;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public String encode(byte[] key)
>>>  +        {
>>>  +            return new String(Hex.encodeHex(key));
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public byte[] decode(String value)
>>>  +        {
>>>  +            try
>>>  +            {
>>>  +                return Hex.decodeHex(value.toCharArray());
>>>  +            }
>>>  +            catch (DecoderException ex)
>>>  +            {
>>>  +                // Cannot decode, ignore silently, later it will be 
> handled as
>>>  +                // ViewExpiredException
>>>  +            }
>>>  +            return null;
>>>  +        }
>>>  +    }
>>>  +
>>>  +    private static class RandomKeyFactory extends 
> KeyFactory<byte[],
>>>  String>
>>>  +    {
>>>  +        private final Random random;
>>>  +        private final int length;
>>>  +
>>>  +        public RandomKeyFactory(FacesContext facesContext)
>>>  +        {
>>>  +            length =
>>> 
> WebConfigParamUtils.getIntegerInitParameter(facesContext.getExternalContext(),
>>>  +                    
> RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM,
>>>  +
>>>  RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM_DEFAULT);
>>>  +            random = new 
> Random(((int)System.nanoTime())+this.hashCode());
>>>  +        }
>>>  +
>>>  +        public Integer generateCounterKey(FacesContext facesContext)
>>>  +        {
>>>  +            ExternalContext externalContext =
>>>  facesContext.getExternalContext();
>>>  +            Object sessionObj = externalContext.getSession(true);
>>>  +            Integer sequence = null;
>>>  +            synchronized(sessionObj) // synchronized to increase 
> sequence if
>>>  multiple requests
>>>  +                                    // are handled at the same time 
> for the
>>>  session
>>>  +            {
>>>  +                Map<String, Object> map =
>>>  externalContext.getSessionMap();
>>>  +                sequence = (Integer) 
> map.get(RendererUtils.SEQUENCE_PARAM);
>>>  +                if(sequence == null || sequence.intValue() ==
>>>  Integer.MAX_VALUE)
>>>  +                {
>>>  +                    sequence = Integer.valueOf(1);
>>>  +                }
>>>  +                else
>>>  +                {
>>>  +                    sequence = Integer.valueOf(sequence.intValue() + 
> 1);
>>>  +                }
>>>  +                map.put(RendererUtils.SEQUENCE_PARAM, sequence);
>>>  +            }
>>>  +            return sequence;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public byte[] generateKey(FacesContext facesContext)
>>>  +        {
>>>  +            byte[] array = new byte[length];
>>>  +            byte[] key = new byte[length+4];
>>>  +
>>>  +            //sessionIdGenerator.getRandomBytes(array);
>>>  +            random.nextBytes(array);
>>>  +            for (int i = 0; i < array.length; i++)
>>>  +            {
>>>  +                key[i] = array[i];
>>>  +            }
>>>  +            int value = generateCounterKey(facesContext);
>>>  +            key[array.length] =  (byte) (value >>> 24);
>>>  +            key[array.length+1] =  (byte) (value >>> 16);
>>>  +            key[array.length+2] =  (byte) (value >>> 8);
>>>  +            key[array.length+3] =  (byte) (value);
>>>  +
>>>  +            return key;
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public String encode(byte[] key)
>>>  +        {
>>>  +            return new String(Hex.encodeHex(key));
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public byte[] decode(String value)
>>>  +        {
>>>  +            try
>>>  +            {
>>>  +                return Hex.decodeHex(value.toCharArray());
>>>  +            }
>>>  +            catch (DecoderException ex)
>>>  +            {
>>>  +                // Cannot decode, ignore silently, later it will be 
> handled as
>>>  +                // ViewExpiredException
>>>  +            }
>>>  +            return null;
>>>  +        }
>>>  +    }
>>>  +
>>>  +    /**
>>>  +     *
>>>  +     * @param <T>
>>>  +     * @param <K>
>>>  +     * @param <V>
>>>  +     */
>>>  +    protected abstract static class SessionViewStorageFactory <T 
> extends
>>>  KeyFactory<K,V>, K, V >
>>>  +    {
>>>  +        private KeyFactory<K, V> keyFactory;
>>>  +
>>>  +        public SessionViewStorageFactory(KeyFactory<K, V> 
> keyFactory)
>>>  +        {
>>>  +            this.keyFactory = keyFactory;
>>>  +        }
>>>  +
>>>  +        public KeyFactory<K, V> getKeyFactory()
>>>  +        {
>>>  +            return keyFactory;
>>>  +        }
>>>  +
>>>  +        public abstract SerializedViewCollection
>>>  createSerializedViewCollection(
>>>  +                FacesContext context);
>>>  +
>>>  +        public abstract SerializedViewKey createSerializedViewKey(
>>>  +                FacesContext facesContext, String viewId, K key);
>>>  +
>>>  +    }
>>>  +
>>>  +    private static class CounterSessionViewStorageFactory
>>>  +        extends SessionViewStorageFactory <KeyFactory
>>>  <Integer,String>, Integer, String>
>>>  +    {
>>>  +        public CounterSessionViewStorageFactory(KeyFactory<Integer,
>>>  String> keyFactory)
>>>  +        {
>>>  +            super(keyFactory);
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public SerializedViewCollection 
> createSerializedViewCollection(
>>>  +                FacesContext context)
>>>  +        {
>>>  +            return new SerializedViewCollection();
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public SerializedViewKey createSerializedViewKey(
>>>  +                FacesContext context, String viewId, Integer key)
>>>  +        {
>>>  +            if (context.isProjectStage(ProjectStage.Production))
>>>  +            {
>>>  +                return new IntIntSerializedViewKey(viewId.hashCode(), 
> key);
>>>  +            }
>>>  +            else
>>>  +            {
>>>  +                return new ReferenceSerializedViewKey(viewId, key);
>>>  +            }
>>>  +        }
>>>  +    }
>>>  +
>>>  +    private static class RandomSessionViewStorageFactory
>>>  +        extends SessionViewStorageFactory <KeyFactory 
> <byte[],String>,
>>>  byte[], String>
>>>  +    {
>>>  +        public RandomSessionViewStorageFactory(KeyFactory<byte[], 
> String>
>>>  keyFactory)
>>>  +        {
>>>  +            super(keyFactory);
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public SerializedViewCollection 
> createSerializedViewCollection(
>>>  +                FacesContext context)
>>>  +        {
>>>  +            return new SerializedViewCollection();
>>>  +        }
>>>  +
>>>  +        @Override
>>>  +        public SerializedViewKey createSerializedViewKey(
>>>  +                FacesContext context, String viewId, byte[] key)
>>>  +        {
>>>  +            if (context.isProjectStage(ProjectStage.Production))
>>>  +            {
>>>  +                return new 
> IntByteArraySerializedViewKey(viewId.hashCode(),
>>>  key);
>>>  +            }
>>>  +            else
>>>  +            {
>>>  +                return new ReferenceSerializedViewKey(viewId, key);
>>>  +            }
>>>  +        }
>>>  +    }
>>>  }
>>> 
> 

Mime
View raw message