You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/11/16 07:03:51 UTC

svn commit: r1410208 [1/2] - /myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/

Author: lu4242
Date: Fri Nov 16 06:03:50 2012
New Revision: 1410208

URL: http://svn.apache.org/viewvc?rev=1410208&view=rev
Log:
MYFACES-3645 review/refactor/document ViewState handling (step 2. move from inner class to outer package all classes without do any additional changes)

Added:
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterKeyFactory.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterSessionViewStorageFactory.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntByteArraySerializedViewKey.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntIntSerializedViewKey.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/KeyFactory.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomKeyFactory.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomSessionViewStorageFactory.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/ReferenceSerializedViewKey.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SecureRandomKeyFactory.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewCollection.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewKey.java   (with props)
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SessionViewStorageFactory.java   (with props)
Modified:
    myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/ServerSideStateCacheImpl.java

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterKeyFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterKeyFactory.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterKeyFactory.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterKeyFactory.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.util.Map;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import org.apache.myfaces.shared.renderkit.RendererUtils;
+
+/**
+ *
+ */
+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 to increase sequence if multiple requests
+        // are handled at the same time for the session
+        synchronized (sessionObj) 
+        {
+            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);
+    }
+
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterKeyFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterSessionViewStorageFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterSessionViewStorageFactory.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterSessionViewStorageFactory.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterSessionViewStorageFactory.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import javax.faces.application.ProjectStage;
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @author lu4242
+ */
+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 == null ? 0 : viewId.hashCode(), key);
+        }
+        else
+        {
+            return new ReferenceSerializedViewKey(viewId, key);
+        }
+    }
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/CounterSessionViewStorageFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntByteArraySerializedViewKey.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntByteArraySerializedViewKey.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntByteArraySerializedViewKey.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntByteArraySerializedViewKey.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.io.Serializable;
+import java.util.Arrays;
+
+/**
+ * Implementation of SerializedViewKey, where the hashCode of the viewId is used
+ * and the sequenceId is a string value.
+ */
+class IntByteArraySerializedViewKey extends SerializedViewKey implements Serializable
+{
+    final int _viewId;
+    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;
+    }
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntByteArraySerializedViewKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntIntSerializedViewKey.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntIntSerializedViewKey.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntIntSerializedViewKey.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntIntSerializedViewKey.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.io.Serializable;
+
+/**
+ * Implementation of SerializedViewKey, where the hashCode of the viewId is used
+ * and the sequenceId is a numeric value.
+ */
+class IntIntSerializedViewKey extends SerializedViewKey implements Serializable
+{
+    private static final long serialVersionUID = -1170697124386063642L;
+    final int _viewId;
+    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;
+    }
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/IntIntSerializedViewKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/KeyFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/KeyFactory.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/KeyFactory.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/KeyFactory.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ */
+abstract 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);
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/KeyFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomKeyFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomKeyFactory.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomKeyFactory.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomKeyFactory.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.util.Map;
+import java.util.Random;
+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.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.util.WebConfigParamUtils;
+
+/**
+ *
+ */
+class RandomKeyFactory extends KeyFactory<byte[], String>
+{
+    private final Random random;
+    private final int length;
+
+    public RandomKeyFactory(FacesContext facesContext)
+    {
+        length = WebConfigParamUtils.getIntegerInitParameter(
+            facesContext.getExternalContext(), 
+            ServerSideStateCacheImpl.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM, 
+            ServerSideStateCacheImpl.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) // 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
+            // Cannot decode, ignore silently, later it will be handled as
+            // ViewExpiredException
+        }
+        return null;
+    }
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomKeyFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomSessionViewStorageFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomSessionViewStorageFactory.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomSessionViewStorageFactory.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomSessionViewStorageFactory.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import javax.faces.application.ProjectStage;
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @author lu4242
+ */
+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 == null ? 0 : viewId.hashCode(), key);
+        }
+        else
+        {
+            return new ReferenceSerializedViewKey(viewId, key);
+        }
+    }
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/RandomSessionViewStorageFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/ReferenceSerializedViewKey.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/ReferenceSerializedViewKey.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/ReferenceSerializedViewKey.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/ReferenceSerializedViewKey.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.io.Serializable;
+
+/**
+ * Implementation of SerializedViewKey, where the viewId and the sequenceId can be
+ * anything.
+ */
+class ReferenceSerializedViewKey<I, K> extends SerializedViewKey implements Serializable
+{
+    private static final long serialVersionUID = -1170697124386063642L;
+    final I _viewId;
+    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;
+    }
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/ReferenceSerializedViewKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SecureRandomKeyFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SecureRandomKeyFactory.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SecureRandomKeyFactory.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SecureRandomKeyFactory.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.util.Map;
+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.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.util.WebConfigParamUtils;
+
+/**
+ * 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.
+ */
+class SecureRandomKeyFactory extends KeyFactory<byte[], String>
+{
+    private final SessionIdGenerator sessionIdGenerator;
+    private final int length;
+
+    public SecureRandomKeyFactory(FacesContext facesContext)
+    {
+        length = WebConfigParamUtils.getIntegerInitParameter(
+            facesContext.getExternalContext(), 
+            ServerSideStateCacheImpl.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM, 
+            ServerSideStateCacheImpl.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_LENGTH_PARAM_DEFAULT);
+        sessionIdGenerator = new SessionIdGenerator();
+        sessionIdGenerator.setSessionIdLength(length);
+        String secureRandomClass = WebConfigParamUtils.getStringInitParameter(
+            facesContext.getExternalContext(), 
+            ServerSideStateCacheImpl.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_CLASS_PARAM);
+        if (secureRandomClass != null)
+        {
+            sessionIdGenerator.setSecureRandomClass(secureRandomClass);
+        }
+        String secureRandomProvider = WebConfigParamUtils.getStringInitParameter(
+            facesContext.getExternalContext(), 
+            ServerSideStateCacheImpl.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM_PROVIDER_PARAM);
+        if (secureRandomProvider != null)
+        {
+            sessionIdGenerator.setSecureRandomProvider(secureRandomProvider);
+        }
+        String secureRandomAlgorithm = WebConfigParamUtils.getStringInitParameter(
+            facesContext.getExternalContext(), 
+            ServerSideStateCacheImpl.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) // 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
+            // Cannot decode, ignore silently, later it will be handled as
+            // ViewExpiredException
+        }
+        return null;
+    }
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SecureRandomKeyFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewCollection.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewCollection.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewCollection.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewCollection.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,338 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.faces.context.FacesContext;
+import org.apache.commons.collections.map.AbstractReferenceMap;
+import org.apache.commons.collections.map.LRUMap;
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.myfaces.shared.util.WebConfigParamUtils;
+
+/**
+ *
+ */
+class SerializedViewCollection implements Serializable
+{
+    private static final Logger log = Logger.getLogger(SerializedViewCollection.class.getName());
+
+    private static final Object[] EMPTY_STATES = new Object[]{null, null};
+
+    private static final long serialVersionUID = -3734849062185115847L;
+    private final List<SerializedViewKey> _keys = 
+        new ArrayList<SerializedViewKey>(
+            ServerSideStateCacheImpl.DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
+    private final Map<SerializedViewKey, Object> _serializedViews = 
+        new HashMap<SerializedViewKey, Object>();
+
+    private final Map<SerializedViewKey, SerializedViewKey> _precedence =
+        new HashMap<SerializedViewKey, SerializedViewKey>();
+    private Map<String, SerializedViewKey> _lastWindowKeys = null;
+    // old views will be hold as soft references which will be removed by
+    // the garbage collector if free memory is low
+    private transient Map<Object, Object> _oldSerializedViews = null;
+
+    public synchronized void add(FacesContext context, Object state, 
+        SerializedViewKey key, SerializedViewKey previousRestoredKey)
+    {
+        if (state == null)
+        {
+            state = EMPTY_STATES;
+        }
+        else if (state instanceof Object[] &&
+            ((Object[])state).length == 2 &&
+            ((Object[])state)[0] == null &&
+            ((Object[])state)[1] == null)
+        {
+            // The generated state can be considered zero, set it as null
+            // into the map.
+            state = null;
+        }
+
+        Integer maxCount = getNumberOfSequentialViewsInSession(context);
+        if (maxCount != null)
+        {
+            if (previousRestoredKey != null)
+            {
+                if (!_serializedViews.isEmpty())
+                {
+                    _precedence.put((SerializedViewKey) key, previousRestoredKey);
+                }
+                else
+                {
+                    // Note when the session is invalidated, _serializedViews map is empty,
+                    // but we could have a not null previousRestoredKey (the last one before
+                    // invalidate the session), so we need to check that condition before
+                    // set the precence. In that way, we ensure the precedence map will always
+                    // have valid keys.
+                    previousRestoredKey = null;
+                }
+            }
+        }
+        _serializedViews.put(key, state);
+
+        while (_keys.remove(key))
+        {
+            // do nothing
+        }
+        _keys.add(key);
+
+        if (previousRestoredKey != null && maxCount != null && maxCount > 0)
+        {
+            int count = 0;
+            SerializedViewKey previousKey = (SerializedViewKey) key;
+            do
+            {
+                previousKey = _precedence.get(previousKey);
+                count++;
+            }
+            while (previousKey != null && count < maxCount);
+
+            if (previousKey != null)
+            {
+                SerializedViewKey keyToRemove = (SerializedViewKey) previousKey;
+                // In theory it should be only one key but just to be sure
+                // do it in a loop, but in this case if cache old views is on,
+                // put on that map.
+                do
+                {
+                    while (_keys.remove(keyToRemove))
+                    {
+                        // do nothing
+                    }
+
+                    if (_serializedViews.containsKey(keyToRemove) &&
+                        !ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF.
+                                equals( getCacheOldViewsInSessionMode(context)) )
+                    {
+                        getOldSerializedViewsMap().put(keyToRemove, _serializedViews.remove(keyToRemove));
+                    }
+                    else
+                    {
+                        _serializedViews.remove(keyToRemove);
+                    }
+
+                    keyToRemove = _precedence.remove(keyToRemove);
+                }
+                while (keyToRemove != null);
+            }
+        }
+        int views = getNumberOfViewsInSession(context);
+        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,
+                // so it could be at least one precedence, but to be safe
+                // do it with a loop.
+                do
+                {
+                    keyToRemove = _precedence.remove(keyToRemove);
+                }
+                while (keyToRemove != null);
+            }
+            if (_serializedViews.containsKey(key) &&
+                !ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF.
+                        equals( getCacheOldViewsInSessionMode( context )))
+            {
+
+                getOldSerializedViewsMap().put(key, _serializedViews.remove(key));
+            }
+            else
+            {
+                _serializedViews.remove(key);
+            }
+        }
+    }
+
+    protected Integer getNumberOfSequentialViewsInSession(FacesContext context)
+    {
+        return WebConfigParamUtils.getIntegerInitParameter( context.getExternalContext(),
+                ServerSideStateCacheImpl.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION_PARAM);
+    }
+
+    /**
+     * Reads the amount (default = 20) of views to be stored in session.
+     * @see ServerSideStateCacheImpl#NUMBER_OF_VIEWS_IN_SESSION_PARAM
+     * @param context FacesContext for the current request, we are processing
+     * @return Number vf views stored in the session
+     */
+    protected int getNumberOfViewsInSession(FacesContext context)
+    {
+        String value = context.getExternalContext().getInitParameter(
+                ServerSideStateCacheImpl.NUMBER_OF_VIEWS_IN_SESSION_PARAM);
+        int views = ServerSideStateCacheImpl.DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
+        if (value != null)
+        {
+            try
+            {
+                views = Integer.parseInt(value);
+                if (views <= 0)
+                {
+                    log.severe("Configured value for " + ServerSideStateCacheImpl.NUMBER_OF_VIEWS_IN_SESSION_PARAM
+                              + " is not valid, must be an value > 0, using default value ("
+                              + ServerSideStateCacheImpl.DEFAULT_NUMBER_OF_VIEWS_IN_SESSION);
+                    views = ServerSideStateCacheImpl.DEFAULT_NUMBER_OF_VIEWS_IN_SESSION;
+                }
+            }
+            catch (Throwable e)
+            {
+                log.log( Level.SEVERE, "Error determining the value for "
+                       + ServerSideStateCacheImpl.NUMBER_OF_VIEWS_IN_SESSION_PARAM
+                       + ", expected an integer value > 0, using default value ("
+                       + ServerSideStateCacheImpl.DEFAULT_NUMBER_OF_VIEWS_IN_SESSION + "): " + e.getMessage(), e);
+            }
+        }
+        return views;
+    }
+
+    public synchronized void putLastWindowKey(FacesContext context, String id, SerializedViewKey key)
+    {
+        if (_lastWindowKeys == null)
+        {
+            Integer i = getNumberOfSequentialViewsInSession(context);
+            int j = getNumberOfViewsInSession(context);
+            if (i != null && i.intValue() > 0)
+            {
+                _lastWindowKeys = new LRUMap((j / i.intValue()) + 1);
+            }
+            else
+            {
+                _lastWindowKeys = new LRUMap(j + 1);
+            }
+        }
+        _lastWindowKeys.put(id, key);
+    }
+
+    public SerializedViewKey getLastWindowKey(FacesContext context, String id)
+    {
+        if (_lastWindowKeys != null)
+        {
+            return _lastWindowKeys.get(id);
+        }
+        return null;
+    }
+
+    /**
+     * @return old serialized views map
+     */
+    @SuppressWarnings("unchecked")
+    protected Map<Object, Object> getOldSerializedViewsMap()
+    {
+        FacesContext context = FacesContext.getCurrentInstance();
+        if (_oldSerializedViews == null && context != null)
+        {
+            String cacheMode = getCacheOldViewsInSessionMode(context);
+            if ( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK.equals(cacheMode))
+            {
+                _oldSerializedViews = new ReferenceMap( AbstractReferenceMap.WEAK, AbstractReferenceMap.WEAK, true);
+            }
+            else if ( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK.equals(cacheMode))
+            {
+                _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.WEAK, true);
+            }
+            else if ( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT.equals(cacheMode))
+            {
+                _oldSerializedViews = new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT, true);
+            }
+            else if ( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT.equals(cacheMode))
+            {
+                _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
+     * @see ServerSideStateCacheImpl#CACHE_OLD_VIEWS_IN_SESSION_MODE
+     */
+    protected String getCacheOldViewsInSessionMode(FacesContext context)
+    {
+        String value = context.getExternalContext().getInitParameter(
+                ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE);
+        if (value == null)
+        {
+            return ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF;
+        }
+        else if (value.equalsIgnoreCase( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT))
+        {
+            return ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT;
+        }
+        else if (value.equalsIgnoreCase( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK))
+        {
+            return ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_SOFT_WEAK;
+        }
+        else if (value.equalsIgnoreCase( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK))
+        {
+            return ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_WEAK;
+        }
+        else if (value.equalsIgnoreCase( ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT))
+        {
+            return ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_HARD_SOFT;
+        }
+        else
+        {
+            return ServerSideStateCacheImpl.CACHE_OLD_VIEWS_IN_SESSION_MODE_OFF;
+        }
+    }
+
+    public Object get(SerializedViewKey key)
+    {
+        Object value = _serializedViews.get(key);
+        if (value == null)
+        {
+            if (_serializedViews.containsKey(key))
+            {
+                return EMPTY_STATES;
+            }
+            Map<Object,Object> oldSerializedViewMap = getOldSerializedViewsMap();
+            if (oldSerializedViewMap != null)
+            {
+                value = oldSerializedViewMap.get(key);
+                if (value == null && oldSerializedViewMap.containsKey(key) )
+                {
+                    return EMPTY_STATES;
+                }
+            }
+        }
+        else if (value instanceof Object[] &&
+            ((Object[])value).length == 2 &&
+            ((Object[])value)[0] == null &&
+            ((Object[])value)[1] == null)
+        {
+            // Remember inside the state map null is stored as an empty array.
+            return null;
+        }
+        return value;
+    }
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewCollection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewKey.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewKey.java?rev=1410208&view=auto
==============================================================================
--- myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewKey.java (added)
+++ myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewKey.java Fri Nov 16 06:03:50 2012
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application.viewstate;
+
+import java.io.Serializable;
+
+/**
+ * Base implementation where all keys used to identify the state of a view should
+ * extend.
+ */
+abstract class SerializedViewKey implements Serializable
+{
+    
+}

Propchange: myfaces/core/branches/2.2.x/impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewKey.java
------------------------------------------------------------------------------
    svn:eol-style = native