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);
+ }
+ }
}