Updated Branches:
  refs/heads/sandbox/WICKET-4744-WicketObjects-use-Java-Serialization-APIs 
[created] 629d59163


WICKET-4744 Investigate reworking WicketObjects#clone(Object|Model) methods to 
use ISerializer

Rework WicketObjects#cloneObject() to use ISerializer.
WicketObjects#cloneModel() has special logic to avoid cloning Component 
instances and it is not easy to be reworked

Additionally improved the API by using type inference for the return types.


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/629d5916
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/629d5916
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/629d5916

Branch: refs/heads/sandbox/WICKET-4744-WicketObjects-use-Java-Serialization-APIs
Commit: 629d591630a0e70e9e7d17a3ad87c223232f7762
Parents: aa84e95
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Thu Jan 16 15:05:31 2014 +0200
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Thu Jan 16 15:05:31 2014 +0200

----------------------------------------------------------------------
 .../java/org/apache/wicket/Application.java     |  2 +-
 .../wicket/core/util/lang/WicketObjects.java    | 87 ++++----------------
 .../html/TransparentWebMarkupContainerTest.java |  2 +-
 .../wicket/page/PageAccessSynchronizerTest.java |  2 +-
 .../wicket/util/lang/WicketObjectsTest.java     |  6 +-
 .../apache/wicket/guice/GuiceInjectorTest.java  |  2 +-
 .../wicket/proxy/LazyInitProxyFactoryTest.java  | 33 +++++++-
 .../wicket/spring/SpringBeanLocatorTest.java    | 24 +++++-
 8 files changed, 73 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-core/src/main/java/org/apache/wicket/Application.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/Application.java 
b/wicket-core/src/main/java/org/apache/wicket/Application.java
index ff4b501..aae9d55b 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Application.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Application.java
@@ -570,7 +570,7 @@ public abstract class Application implements 
UnboundListener, IEventSink
         */
        private void addInitializer(final String className)
        {
-               IInitializer initializer = 
(IInitializer)WicketObjects.newInstance(className);
+               IInitializer initializer = WicketObjects.newInstance(className);
                if (initializer != null)
                {
                        initializers.add(initializer);

http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java 
b/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java
index bb7fa21..9065717 100644
--- 
a/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java
+++ 
b/wicket-core/src/main/java/org/apache/wicket/core/util/lang/WicketObjects.java
@@ -127,7 +127,7 @@ public class WicketObjects
                        }
                        else
                        {
-                               serializer = new 
JavaSerializer("SerializingObjectSizeOfStrategy");
+                               serializer = new 
JavaSerializer(SerializingObjectSizeOfStrategy.class.getName());
                        }
                        byte[] serialized = serializer.serialize(object);
                        int size = -1;
@@ -240,11 +240,15 @@ public class WicketObjects
         * serializable to be cloned. This method will not clone wicket 
Components, it will just reuse
         * those instances so that the complete component tree is not copied 
over only the model data.
         *
+        * <strong>Warning</strong>: this method uses Java Serialization APIs 
to be able to avoid cloning
+        * of {@link org.apache.wicket.Component} instances. If the application 
uses custom
+        * {@link org.apache.wicket.serialize.ISerializer} then most probably 
this method cannot be used.
+        *
         * @param object
         *            The object to clone
         * @return A deep copy of the object
         */
-       public static Object cloneModel(final Object object)
+       public static <T> T cloneModel(final T object)
        {
                if (object == null)
                {
@@ -260,13 +264,9 @@ public class WicketObjects
                                oos.writeObject(object);
                                ObjectInputStream ois = new 
ReplaceObjectInputStream(new ByteArrayInputStream(
                                        out.toByteArray()), replacedObjects, 
object.getClass().getClassLoader());
-                               return ois.readObject();
-                       }
-                       catch (ClassNotFoundException e)
-                       {
-                               throw new WicketRuntimeException("Internal 
error cloning object", e);
+                               return (T) ois.readObject();
                        }
-                       catch (IOException e)
+                       catch (ClassNotFoundException | IOException e)
                        {
                                throw new WicketRuntimeException("Internal 
error cloning object", e);
                        }
@@ -290,7 +290,7 @@ public class WicketObjects
         * @return A deep copy of the object
         * @see #cloneModel(Object)
         */
-       public static Object cloneObject(final Object object)
+       public static <T> T cloneObject(final T object)
        {
                if (object == null)
                {
@@ -298,67 +298,10 @@ public class WicketObjects
                }
                else
                {
-                       try
-                       {
-                               final ByteArrayOutputStream out = new 
ByteArrayOutputStream(256);
-                               ObjectOutputStream oos = new 
ObjectOutputStream(out);
-                               oos.writeObject(object);
-                               ObjectInputStream ois = new 
ObjectInputStream(new ByteArrayInputStream(
-                                       out.toByteArray()))
-                               {
-                                       // This override is required to resolve 
classes inside in different bundle, i.e.
-                                       // The classes can be resolved by OSGI 
classresolver implementation
-                                       @Override
-                                       protected Class<?> 
resolveClass(ObjectStreamClass desc) throws IOException,
-                                               ClassNotFoundException
-                                       {
-                                               String className = 
desc.getName();
-
-                                               try
-                                               {
-                                                       return 
Class.forName(className, true, object.getClass()
-                                                               
.getClassLoader());
-                                               }
-                                               catch (ClassNotFoundException 
ex1)
-                                               {
-                                                       // ignore this 
exception.
-                                                       log.debug("Class not 
found by using objects own classloader, trying the IClassResolver");
-                                               }
-
-
-                                               Application application = 
Application.get();
-                                               ApplicationSettings 
applicationSettings = application.getApplicationSettings();
-                                               IClassResolver classResolver = 
applicationSettings.getClassResolver();
-
-                                               Class<?> candidate = null;
-                                               try
-                                               {
-                                                       candidate = 
classResolver.resolveClass(className);
-                                                       if (candidate == null)
-                                                       {
-                                                               candidate = 
super.resolveClass(desc);
-                                                       }
-                                               }
-                                               catch (WicketRuntimeException 
ex)
-                                               {
-                                                       if (ex.getCause() 
instanceof ClassNotFoundException)
-                                                       {
-                                                               throw 
(ClassNotFoundException)ex.getCause();
-                                                       }
-                                               }
-                                               return candidate;
-                                       }
-                               };
-                               return ois.readObject();
-                       }
-                       catch (ClassNotFoundException e)
-                       {
-                               throw new WicketRuntimeException("Internal 
error cloning object", e);
-                       }
-                       catch (IOException e)
-                       {
-                               throw new WicketRuntimeException("Internal 
error cloning object", e);
-                       }
+                       ISerializer serializer = 
Application.get().getFrameworkSettings().getSerializer();
+                       byte[] serialized = serializer.serialize(object);
+                       Object deserialized = 
serializer.deserialize(serialized);
+                       return (T) deserialized;
                }
        }
 
@@ -370,14 +313,14 @@ public class WicketObjects
         *            The full class name
         * @return The new object instance
         */
-       public static Object newInstance(final String className)
+       public static <T> T newInstance(final String className)
        {
                if (!Strings.isEmpty(className))
                {
                        try
                        {
                                Class<?> c = 
WicketObjects.resolveClass(className);
-                               return c.newInstance();
+                               return (T) c.newInstance();
                        }
                        catch (Exception e)
                        {

http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
index 9ea081b..f1ac3b2 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/markup/html/TransparentWebMarkupContainerTest.java
@@ -115,7 +115,7 @@ public class TransparentWebMarkupContainerTest extends 
WicketTestCase
                                                        @Override
                                                        public void 
touchPage(IManageablePage page)
                                                        {
-                                                               page = 
(IManageablePage)WicketObjects.cloneObject(page);
+                                                               page = 
WicketObjects.cloneObject(page);
                                                                
super.touchPage(page);
                                                        }
                                                };

http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
 
b/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
index b5cb403..20028af 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/page/PageAccessSynchronizerTest.java
@@ -298,7 +298,7 @@ public class PageAccessSynchronizerTest extends Assert
 
                // make sure we can serialize the synchronizer
 
-               final PageAccessSynchronizer sync2 = 
(PageAccessSynchronizer)WicketObjects.cloneObject(sync);
+               final PageAccessSynchronizer sync2 = 
WicketObjects.cloneObject(sync);
                assertTrue(sync != sync2);
 
                // make sure the clone does not retain locks by attempting to 
lock page locked by locker1 in

http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-core/src/test/java/org/apache/wicket/util/lang/WicketObjectsTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-core/src/test/java/org/apache/wicket/util/lang/WicketObjectsTest.java 
b/wicket-core/src/test/java/org/apache/wicket/util/lang/WicketObjectsTest.java
index 0cd2082..d34b055 100644
--- 
a/wicket-core/src/test/java/org/apache/wicket/util/lang/WicketObjectsTest.java
+++ 
b/wicket-core/src/test/java/org/apache/wicket/util/lang/WicketObjectsTest.java
@@ -83,9 +83,9 @@ public class WicketObjectsTest extends WicketTestCase
        @Test
        public void componentClone()
        {
-               PropertyModel<String> pm = new PropertyModel<String>(new 
TextField<String>("test",
-                       new Model<String>("test")), "modelObject");
-               PropertyModel<String> pm2 = 
(PropertyModel<String>)WicketObjects.cloneModel(pm);
+               PropertyModel<String> pm = new PropertyModel<String>(new 
TextField<>("test",
+                       Model.of("test")), "modelObject");
+               PropertyModel<String> pm2 = WicketObjects.cloneModel(pm);
                assertTrue(pm.getObject() == pm2.getObject());
        }
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java 
b/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java
index 7ba0bb7..f9b4f36 100644
--- a/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java
+++ b/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java
@@ -94,7 +94,7 @@ public class GuiceInjectorTest extends Assert
                        doChecksForComponent(testComponent);
 
                        // Serialize and deserialize the object, and check it 
still works.
-                       TestComponentInterface clonedComponent = 
(TestComponentInterface)WicketObjects.cloneObject(testComponent);
+                       TestComponentInterface clonedComponent = 
WicketObjects.cloneObject(testComponent);
                        doChecksForComponent(clonedComponent);
 
                        // Test injection of a class that does not extend 
Component

http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
 
b/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
index 8231d49..1d7729d 100644
--- 
a/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
+++ 
b/wicket-ioc/src/test/java/org/apache/wicket/proxy/LazyInitProxyFactoryTest.java
@@ -20,14 +20,19 @@ import static org.hamcrest.CoreMatchers.instanceOf;
 
 import java.lang.reflect.Proxy;
 
+import org.apache.wicket.ThreadContext;
 import org.apache.wicket.core.util.lang.WicketObjects;
+import org.apache.wicket.mock.MockApplication;
+import org.apache.wicket.protocol.http.mock.MockServletContext;
 import org.apache.wicket.proxy.LazyInitProxyFactory.ProxyReplacement;
 import org.apache.wicket.proxy.util.ConcreteObject;
 import org.apache.wicket.proxy.util.IInterface;
 import org.apache.wicket.proxy.util.IObjectMethodTester;
 import org.apache.wicket.proxy.util.InterfaceObject;
 import org.apache.wicket.proxy.util.ObjectMethodTester;
+import org.junit.After;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
 
 /**
@@ -75,6 +80,26 @@ public class LazyInitProxyFactoryTest extends Assert
                }
        };
 
+       private MockApplication application;
+
+       @Before
+       public void before()
+       {
+               // the application is needed for WicketObjects#cloneObject() 
calls
+               application = new MockApplication();
+               ThreadContext.setApplication(application);
+               application.setName(LazyInitProxyFactoryTest.class.getName());
+               application.setServletContext(new 
MockServletContext(application, "/"));
+               application.initApplication();
+       }
+
+       @After
+       public void after()
+       {
+               application.internalDestroy();
+               ThreadContext.detach();
+       }
+
        /**
         * Tests lazy init proxy to represent interfaces
         */
@@ -96,7 +121,7 @@ public class LazyInitProxyFactoryTest extends Assert
                assertEquals(proxy.getMessage(), "interface");
 
                // test serialization
-               IInterface proxy2 = 
(IInterface)WicketObjects.cloneObject(proxy);
+               IInterface proxy2 = WicketObjects.cloneObject(proxy);
                assertTrue(proxy != proxy2);
                assertEquals(proxy2.getMessage(), "interface");
 
@@ -143,7 +168,7 @@ public class LazyInitProxyFactoryTest extends Assert
                assertEquals(proxy.getMessage(), "concrete");
 
                // test serialization
-               ConcreteObject proxy2 = 
(ConcreteObject)WicketObjects.cloneObject(proxy);
+               ConcreteObject proxy2 = WicketObjects.cloneObject(proxy);
                assertTrue(proxy != proxy2);
                assertEquals(proxy2.getMessage(), "concrete");
 
@@ -179,8 +204,8 @@ public class LazyInitProxyFactoryTest extends Assert
                ProxyReplacement ser = new 
ProxyReplacement(ConcreteObject.class.getName(),
                        concreteObjectLocator);
 
-               ConcreteObject proxy2 = 
(ConcreteObject)WicketObjects.cloneObject(ser);
-               assertEquals(proxy2.getMessage(), "concrete");
+               Object proxy2 = WicketObjects.cloneObject(ser);
+               assertEquals(((ConcreteObject)proxy2).getMessage(), "concrete");
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/wicket/blob/629d5916/wicket-spring/src/test/java/org/apache/wicket/spring/SpringBeanLocatorTest.java
----------------------------------------------------------------------
diff --git 
a/wicket-spring/src/test/java/org/apache/wicket/spring/SpringBeanLocatorTest.java
 
b/wicket-spring/src/test/java/org/apache/wicket/spring/SpringBeanLocatorTest.java
index 1f9109e..24200c9 100644
--- 
a/wicket-spring/src/test/java/org/apache/wicket/spring/SpringBeanLocatorTest.java
+++ 
b/wicket-spring/src/test/java/org/apache/wicket/spring/SpringBeanLocatorTest.java
@@ -16,9 +16,13 @@
  */
 package org.apache.wicket.spring;
 
+import org.apache.wicket.ThreadContext;
+import org.apache.wicket.mock.MockApplication;
+import org.apache.wicket.protocol.http.mock.MockServletContext;
 import org.apache.wicket.spring.test.ApplicationContextMock;
 import org.apache.wicket.spring.test.SpringContextLocatorMock;
 import org.apache.wicket.core.util.lang.WicketObjects;
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -35,6 +39,15 @@ public class SpringBeanLocatorTest extends Assert
 
        private ISpringContextLocator ctxLocator;
 
+       private MockApplication application;
+
+       @After
+       public void after()
+       {
+               application.internalDestroy();
+               ThreadContext.detach();
+       }
+
        /**
         * 
         */
@@ -43,6 +56,13 @@ public class SpringBeanLocatorTest extends Assert
        {
                ctx = new ApplicationContextMock();
                ctxLocator = new SpringContextLocatorMock(ctx);
+
+               // the application is needed for WicketObjects#cloneObject() 
calls
+               application = new MockApplication();
+               ThreadContext.setApplication(application);
+               application.setName(SpringBeanLocatorTest.class.getName());
+               application.setServletContext(new 
MockServletContext(application, "/"));
+               application.initApplication();
        }
 
        /**
@@ -69,7 +89,7 @@ public class SpringBeanLocatorTest extends Assert
 
                ctx.putBean("bean", bean);
 
-               SpringBeanLocator locator = 
(SpringBeanLocator)WicketObjects.cloneObject(new SpringBeanLocator(
+               SpringBeanLocator locator = WicketObjects.cloneObject(new 
SpringBeanLocator(
                        Bean.class, ctxLocator));
 
                assertNotNull(locator.locateProxyTarget());
@@ -139,7 +159,7 @@ public class SpringBeanLocatorTest extends Assert
                Bean bean = new Bean();
                ctx.putBean("bean", bean);
 
-               SpringBeanLocator locator = 
(SpringBeanLocator)WicketObjects.cloneObject(new SpringBeanLocator(
+               SpringBeanLocator locator = WicketObjects.cloneObject(new 
SpringBeanLocator(
                        "bean", Bean.class, ctxLocator));
 
                assertNotNull(locator.locateProxyTarget());

Reply via email to