You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2020/05/25 11:11:37 UTC

[myfaces] branch master updated: MYFACES-3655 - enhanced SerialFactory

This is an automated email from the ASF dual-hosted git repository.

tandraschko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/master by this push:
     new 49bf5f1  MYFACES-3655 - enhanced SerialFactory
49bf5f1 is described below

commit 49bf5f1f7a75c9f3aa38016b6c67786fbc16ad00
Author: Thomas Andraschko <ta...@apache.org>
AuthorDate: Mon May 25 13:11:26 2020 +0200

    MYFACES-3655 - enhanced SerialFactory
---
 .../viewstate/StateCacheServerSide.java            |  10 +-
 .../myfaces/application/viewstate/StateUtils.java  | 105 ++-------------------
 .../java/org/apache/myfaces/spi/SerialFactory.java |  44 ++++++++-
 .../myfaces/spi/impl/DefaultSerialFactory.java     |   6 +-
 .../util/lang/FastByteArrayInputStream.java        |   5 +
 5 files changed, 62 insertions(+), 108 deletions(-)

diff --git a/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java b/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java
index 63e71ca..cc86326 100644
--- a/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java
+++ b/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java
@@ -92,7 +92,7 @@ class StateCacheServerSide extends StateCache<Object, Object>
         String randomMode = config.getRandomKeyInViewStateSessionToken();
         if (MyfacesConfig.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_SECURE_RANDOM.equals(randomMode))
         {
-            sessionViewStorageFactory = new SessionViewStorageFactoryImpl( new KeyFactorySecureRandom(facesContext));
+            sessionViewStorageFactory = new SessionViewStorageFactoryImpl(new KeyFactorySecureRandom(facesContext));
         }
         else if (MyfacesConfig.RANDOM_KEY_IN_VIEW_STATE_SESSION_TOKEN_RANDOM.equals(randomMode))
         {
@@ -133,7 +133,7 @@ class StateCacheServerSide extends StateCache<Object, Object>
         return null;
     }
 
-    protected void saveSerializedViewInServletSession(FacesContext context, Object serializedView)
+    protected void saveSerializedViewInSession(FacesContext context, Object serializedView)
     {
         Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
         SerializedViewCollection viewCollection = (SerializedViewCollection) sessionMap.computeIfAbsent(
@@ -210,7 +210,7 @@ class StateCacheServerSide extends StateCache<Object, Object>
         sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
     }
 
-    protected Object getSerializedViewFromServletSession(FacesContext context, String viewId, Object sequence)
+    protected Object getSerializedViewFromSession(FacesContext context, String viewId, Object sequence)
     {
         ExternalContext externalContext = context.getExternalContext();
         Map<Object, Object> attributeMap = context.getAttributes();
@@ -460,7 +460,7 @@ class StateCacheServerSide extends StateCache<Object, Object>
             log.finest("Processing saveSerializedView - server-side state saving - save state");
         }
         //save state in server session
-        saveSerializedViewInServletSession(facesContext, serializedView);
+        saveSerializedViewInSession(facesContext, serializedView);
         
         if (log.isLoggable(Level.FINEST))
         {
@@ -482,7 +482,7 @@ class StateCacheServerSide extends StateCache<Object, Object>
 
         return (serverStateId == null)
                 ? null
-                : getSerializedViewFromServletSession(facesContext, viewId, serverStateId);
+                : getSerializedViewFromSession(facesContext, viewId, serverStateId);
     }
 
     @Override
diff --git a/impl/src/main/java/org/apache/myfaces/application/viewstate/StateUtils.java b/impl/src/main/java/org/apache/myfaces/application/viewstate/StateUtils.java
index 30899f2..b92df73 100644
--- a/impl/src/main/java/org/apache/myfaces/application/viewstate/StateUtils.java
+++ b/impl/src/main/java/org/apache/myfaces/application/viewstate/StateUtils.java
@@ -21,12 +21,8 @@ package org.apache.myfaces.application.viewstate;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
 import java.io.UnsupportedEncodingException;
-import java.security.AccessController;
 import java.security.NoSuchAlgorithmException;
-import java.security.PrivilegedExceptionAction;
 import java.util.Base64;
 import java.util.Random;
 import java.util.logging.Level;
@@ -292,19 +288,10 @@ public final class StateUtils
         // get the Factory that was instantiated @ startup
         SerialFactory serialFactory = (SerialFactory) ctx.getApplicationMap().get(SERIAL_FACTORY);
         Assert.notNull(serialFactory, "serialFactory");
-        
+
         try
         {
-            try (ByteArrayOutputStream baos = new ByteArrayOutputStream())
-            {
-                try (ObjectOutputStream oos = serialFactory.getObjectOutputStream(baos))
-                {
-                    oos.writeObject(object);
-                    oos.flush();
-
-                    return baos.toByteArray();
-                }
-            }
+            return serialFactory.toByteArray(object);
         }
         catch (IOException e)
         {
@@ -491,93 +478,17 @@ public final class StateUtils
      */
     public static final Object getAsObject(byte[] bytes, ExternalContext ctx)
     {
-        ByteArrayInputStream input = null;
+        // get the Factory that was instantiated @ startup
+        SerialFactory serialFactory = (SerialFactory) ctx.getApplicationMap().get(SERIAL_FACTORY);
+        Assert.notNull(serialFactory, "serialFactory");
 
         try
         {
-            input = new ByteArrayInputStream(bytes);
-
-            // get the Factory that was instantiated @ startup
-            SerialFactory serialFactory = (SerialFactory) ctx.getApplicationMap().get(SERIAL_FACTORY);
-            
-            Assert.notNull(serialFactory, "serialFactory");
-
-            ObjectInputStream s = null;
-            Exception pendingException = null;
-            try
-            {
-                s = serialFactory.getObjectInputStream(input); 
-                Object object = null;
-                if (System.getSecurityManager() != null)
-                {
-                    final ObjectInputStream finalS = s;
-
-                    //Put IOException and ClassNotFoundException as "checked" exceptions,
-                    //so AccessController wrap them in a PrivilegedActionException
-                    object = AccessController.doPrivileged((PrivilegedExceptionAction) () -> finalS.readObject());
-                }
-                else
-                {
-                    object = s.readObject();
-                }
-                return object;
-            }
-            catch (Exception e)
-            {
-                pendingException = e;
-                throw new FacesException(e);
-            }
-            finally
-            {
-                if (s != null)
-                {
-                    try
-                    {
-                        s.close();
-                    }
-                    catch (IOException e)
-                    {
-                        // If a previous exception is thrown 
-                        // ignore this, but if not, wrap it in a
-                        // FacesException and throw it. In this way
-                        // we preserve the original semantic of this
-                        // method, but we handle correctly the case
-                        // when we close a stream. Obviously, the 
-                        // information about this exception is lost,
-                        // but note that the interesting information 
-                        // is always on pendingException, since we
-                        // only do a readObject() on the outer try block.
-                        if (pendingException == null)
-                        {
-                            throw new FacesException(e);
-                        }                        
-                    }
-                    finally
-                    {
-                        s = null;
-                    }
-                }
-            }
+            return serialFactory.toObject(bytes);
         }
-        finally
+        catch (Exception e)
         {
-            if (input != null)
-            {
-                try
-                {
-                    input.close();
-                }
-                catch (IOException e)
-                {
-                    //ignore it, because ByteArrayInputStream.close has
-                    //no effect, but it is better to call close and preserve
-                    //semantic from previous code.
-                }
-                finally
-                {
-                    input = null;
-                }
-            }
+            throw new FacesException(e);
         }
     }
 
diff --git a/impl/src/main/java/org/apache/myfaces/spi/SerialFactory.java b/impl/src/main/java/org/apache/myfaces/spi/SerialFactory.java
index 3a9fa74..cab7134 100644
--- a/impl/src/main/java/org/apache/myfaces/spi/SerialFactory.java
+++ b/impl/src/main/java/org/apache/myfaces/spi/SerialFactory.java
@@ -18,14 +18,52 @@
  */
 package org.apache.myfaces.spi;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import org.apache.myfaces.util.lang.FastByteArrayInputStream;
 
-public interface SerialFactory
+public abstract class SerialFactory
 {
-    ObjectOutputStream getObjectOutputStream(OutputStream outputStream) throws IOException;
-    ObjectInputStream getObjectInputStream(InputStream inputStream) throws IOException;
+    public byte[] toByteArray(Object object) throws IOException
+    {
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream())
+        {
+            try (ObjectOutputStream oos = getObjectOutputStream(baos))
+            {
+                oos.writeObject(object);
+                oos.flush();
+
+                return baos.toByteArray();
+            }
+        }
+    }
+    
+    public Object toObject(byte[] bytes) throws IOException, PrivilegedActionException, ClassNotFoundException
+    {
+        try (InputStream bias = new FastByteArrayInputStream(bytes))
+        {
+            try (ObjectInputStream ois = getObjectInputStream(bias))
+            {
+                if (System.getSecurityManager() != null)
+                {
+                    //Put IOException and ClassNotFoundException as "checked" exceptions,
+                    //so AccessController wrap them in a PrivilegedActionException
+                    return AccessController.doPrivileged((PrivilegedExceptionAction) () -> ois.readObject());
+                }
+
+                return ois.readObject();
+            }
+        }
+    }
+
+    protected abstract ObjectOutputStream getObjectOutputStream(OutputStream outputStream) throws IOException;
+
+    protected abstract ObjectInputStream getObjectInputStream(InputStream inputStream) throws IOException;
 }
diff --git a/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultSerialFactory.java b/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultSerialFactory.java
index 810e398..8c34fb2 100644
--- a/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultSerialFactory.java
+++ b/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultSerialFactory.java
@@ -26,16 +26,16 @@ import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import org.apache.myfaces.util.MyFacesObjectInputStream;
 
-public class DefaultSerialFactory implements SerialFactory
+public class DefaultSerialFactory extends SerialFactory
 {
     @Override
-    public ObjectOutputStream getObjectOutputStream(OutputStream outputStream) throws IOException
+    protected ObjectOutputStream getObjectOutputStream(OutputStream outputStream) throws IOException
     {
         return new ObjectOutputStream(outputStream);
     }
 
     @Override
-    public ObjectInputStream getObjectInputStream(InputStream inputStream) throws IOException
+    protected ObjectInputStream getObjectInputStream(InputStream inputStream) throws IOException
     {
         return new MyFacesObjectInputStream(inputStream);
     }
diff --git a/impl/src/main/java/org/apache/myfaces/util/lang/FastByteArrayInputStream.java b/impl/src/main/java/org/apache/myfaces/util/lang/FastByteArrayInputStream.java
index 7e15dca..049366a 100644
--- a/impl/src/main/java/org/apache/myfaces/util/lang/FastByteArrayInputStream.java
+++ b/impl/src/main/java/org/apache/myfaces/util/lang/FastByteArrayInputStream.java
@@ -40,6 +40,11 @@ public class FastByteArrayInputStream extends InputStream
      */
     protected int pos = 0;
 
+    public FastByteArrayInputStream(byte[] buf)
+    {
+        this(buf, buf.length);
+    }
+
     public FastByteArrayInputStream(byte[] buf, int count)
     {
         this.buf = buf;