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:56:39 GMT
> hat the hashCode could be the same is astronomical.

I thought so the same, but Udo did hit that in production. This really happens!
And I really don't care about storing 20 bytes more because the encryption which is done immediately afterwards will use much more memory.


Again: if the viewId would not needed for uniqueness, then we could also drop it completely.


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:50 PM
> Subject: Re: svn commit: r1409414 - in /myfaces/core/trunk/impl: ./ src/main/java/org/apache/myfaces/renderkit/
> 
> 2012/11/14 Mark Struberg <struberg@yahoo.de>:
>> 
>> 
>> 
>> 
>>  Leo we HAD that already in production (with an IBM JVM). Does that count?
>> 
>>  using the hashCode to speed up caches is perfectly fine. But only for 
> _excluding_ matches, Getting the same hashCode doesn't make sure something 
> is unique.
>> 
>>  Also in the private mail you pointed to an example yourself [1]:
>> 
>> 
>>  [1] pry(main)> "a".hash
>>  => 100 [2] pry(main)> "\0a".hash
>>  => 100 [3] pry(main)> "\0\0a".hash
>>  => 100 [4] pry(main)> "\0\0\0a".hash
>>  => 100 [5] pry(main)> "\0\0\0\0a".hash
>>  => 100 [6] pry(main)> 
> "\0\0\0\0\0a".hash
>>  => 100
>> 
> 
> but you cannot put a \0 in a file name, because it is an invalid character
> for a file name, right? We are looking for REAL file names that can result in
> a viewId. For example:
> 
> /home.xhtml
> /module/page.xhtml
> 
> and so on. In practice, the probability of have two REAL pages that derives a
> viewId and that the hashCode could be the same is astronomical.
> 
>>  It's just not guaranteed.
>> 
>>  LieGrue,
>>  strub
>> 
>> 
>> 
>>  [1] 
> http://martin.kleppmann.com/2012/06/18/java-hashcode-unsafe-for-distributed-systems.html
>> 
>> 
>> 
>>  ----- 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:34 PM
>>>  Subject: Re: svn commit: r1409414 - in /myfaces/core/trunk/impl: ./ 
> src/main/java/org/apache/myfaces/renderkit/
>>> 
>>>  2012/11/14 Leonardo Uribe <lu4242@gmail.com>:
>>>>   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.
>>>> 
>>> 
>>>  It is more, could you please try if the fix proposed by me works in 
> your case?
>>>  could you please show two viewIds that can be written as valid file 
> names that
>>>  has the same hashCode? I'm open to change my mind, but first I need
>>>  concrete arguments to do that.
>>> 
>>>>   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