You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2013/05/05 22:25:35 UTC

svn commit: r1479380 - in /commons/proper/configuration/trunk/src: main/java/org/apache/commons/configuration/ConfigurationUtils.java test/java/org/apache/commons/configuration/TestConfigurationUtils.java

Author: oheger
Date: Sun May  5 20:25:34 2013
New Revision: 1479380

URL: http://svn.apache.org/r1479380
Log:
Added a method for cloning Synchronizers to ConfigurationUtils.

This functionality is needed by implementations of clone() for
Configuration classes.

Modified:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java?rev=1479380&r1=1479379&r2=1479380&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java Sun May  5 20:25:34 2013
@@ -397,6 +397,56 @@ public final class ConfigurationUtils
     }
 
     /**
+     * Creates a clone of the specified {@code Synchronizer}. This method can be
+     * called by {@code clone()} implementations in configuration classes that
+     * also need to copy the {@code Synchronizer} object. This method can handle
+     * some well-known {@code Synchronizer} implementations directly. For other
+     * classes, it uses the following algorithm:
+     * <ul>
+     * <li>If the class of the {@code Synchronizer} has a standard constructor,
+     * a new instance is created using reflection.</li>
+     * <li>If this is not possible, it is tried whether the object can be
+     * cloned.</li>
+     * </ul>
+     * If all attempts fail, a {@code ConfigurationRuntimeException} is thrown.
+     *
+     * @param sync the {@code Synchronizer} object to be cloned
+     * @return the clone of this {@code Synchronizer}
+     * @throws ConfigurationRuntimeException if no clone can be created
+     * @throws IllegalArgumentException if <b>null</b> is passed in
+     */
+    public static Synchronizer cloneSynchronizer(Synchronizer sync)
+    {
+        if (sync == null)
+        {
+            throw new IllegalArgumentException("Synchronizer must not be null!");
+        }
+        if (NoOpSynchronizer.INSTANCE == sync)
+        {
+            return sync;
+        }
+
+        try
+        {
+            return sync.getClass().newInstance();
+        }
+        catch (Exception ex)
+        {
+            LOG.info("Cannot create new instance of " + sync.getClass());
+        }
+
+        try
+        {
+            return (Synchronizer) clone(sync);
+        }
+        catch (CloneNotSupportedException cnex)
+        {
+            throw new ConfigurationRuntimeException(
+                    "Cannot clone Synchronizer " + sync);
+        }
+    }
+
+    /**
      * Constructs a URL from a base path and a file name. The file name can
      * be absolute, relative or a full URL. If necessary the base path URL is
      * applied.

Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java?rev=1479380&r1=1479379&r2=1479380&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java Sun May  5 20:25:34 2013
@@ -19,6 +19,7 @@ package org.apache.commons.configuration
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
@@ -663,4 +664,103 @@ public class TestConfigurationUtils
         assertFalse("Wrong result (2)", source.removeErrorListener(el));
         source.addConfigurationListener(null);
     }
+
+    /**
+     * Tries to clone a null Synchronizer.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testCloneSynchronizerNull()
+    {
+        ConfigurationUtils.cloneSynchronizer(null);
+    }
+
+    /**
+     * Tests whether the NoOpSyhnchronizer can be cloned.
+     */
+    @Test
+    public void testCloneSynchronizerNoOp()
+    {
+        assertSame("Wrong result", NoOpSynchronizer.INSTANCE,
+                ConfigurationUtils.cloneSynchronizer(NoOpSynchronizer.INSTANCE));
+    }
+
+    /**
+     * Tests whether a new Synchronizer can be created using reflection.
+     */
+    @Test
+    public void testCloneSynchronizerNewInstance()
+    {
+        SynchronizerTestImpl sync = new SynchronizerTestImpl();
+        SynchronizerTestImpl sync2 =
+                (SynchronizerTestImpl) ConfigurationUtils
+                        .cloneSynchronizer(sync);
+        assertNotNull("Clone is null", sync2);
+        assertNotSame("Same instance", sync, sync2);
+    }
+
+    /**
+     * Tests whether a Synchronizer can be cloned using its clone() method.
+     */
+    @Test
+    public void testCloneSynchronizerClone()
+    {
+        CloneableSynchronizer sync = new CloneableSynchronizer(false);
+        CloneableSynchronizer sync2 =
+                (CloneableSynchronizer) ConfigurationUtils
+                        .cloneSynchronizer(sync);
+        assertTrue("Not cloned", sync2.isCloned());
+    }
+
+    /**
+     * Tests cloneSynchronizer() if the argument cannot be cloned.
+     */
+    @Test(expected = ConfigurationRuntimeException.class)
+    public void testCloneSynchronizerFailed()
+    {
+        ConfigurationUtils.cloneSynchronizer(new NonCloneableSynchronizer());
+    }
+
+    /**
+     * A test Synchronizer implementation which cannot be cloned.
+     */
+    private static class NonCloneableSynchronizer extends SynchronizerTestImpl
+    {
+    }
+
+    /**
+     * A test Synchronizer implementation which can be cloned.
+     */
+    private static class CloneableSynchronizer extends NonCloneableSynchronizer
+            implements Cloneable
+    {
+        /** A flag whether clone() was called. */
+        private final boolean cloned;
+
+        /**
+         * Creates a new instance of {@code CloneableSynchronizer} and sets the
+         * clone flag.
+         *
+         * @param clone the clone flag
+         */
+        public CloneableSynchronizer(boolean clone)
+        {
+            cloned = clone;
+        }
+
+        /**
+         * Returns a flag whether this object was cloned.
+         *
+         * @return the clone flag
+         */
+        public boolean isCloned()
+        {
+            return cloned;
+        }
+
+        @Override
+        public Object clone()
+        {
+            return new CloneableSynchronizer(true);
+        }
+    }
 }