myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leonardo Uribe <lu4...@gmail.com>
Subject Re: svn commit: r1409414 - in /myfaces/core/trunk/impl: ./ src/main/java/org/apache/myfaces/renderkit/
Date Wed, 14 Nov 2012 22:34:53 GMT
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