commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ohe...@apache.org
Subject svn commit: r1394243 - in /commons/proper/configuration/trunk/src: main/java/org/apache/commons/configuration/builder/BasicConfigurationBuilder.java test/java/org/apache/commons/configuration/builder/TestBasicConfigurationBuilder.java
Date Thu, 04 Oct 2012 20:18:31 GMT
Author: oheger
Date: Thu Oct  4 20:18:31 2012
New Revision: 1394243

URL: http://svn.apache.org/viewvc?rev=1394243&view=rev
Log:
Added support for event listeners to BasicConfigurationBuilder.

Modified:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicConfigurationBuilder.java
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBasicConfigurationBuilder.java

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicConfigurationBuilder.java?rev=1394243&r1=1394242&r2=1394243&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicConfigurationBuilder.java
(original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BasicConfigurationBuilder.java
Thu Oct  4 20:18:31 2012
@@ -16,6 +16,8 @@
  */
 package org.apache.commons.configuration.builder;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -25,6 +27,9 @@ import org.apache.commons.configuration.
 import org.apache.commons.configuration.ConfigurationRuntimeException;
 import org.apache.commons.configuration.beanutils.BeanDeclaration;
 import org.apache.commons.configuration.beanutils.BeanHelper;
+import org.apache.commons.configuration.event.ConfigurationErrorListener;
+import org.apache.commons.configuration.event.ConfigurationListener;
+import org.apache.commons.configuration.event.EventSource;
 
 /**
  * <p>
@@ -78,9 +83,51 @@ import org.apache.commons.configuration.
 public class BasicConfigurationBuilder<T extends Configuration> implements
         ConfigurationBuilder<T>
 {
+    /**
+     * A dummy event source that is used for registering listeners if no
+     * compatible result object is available. This source has empty dummy
+     * implementations for listener registration methods.
+     */
+    private static final EventSource DUMMY_EVENT_SOURCE = new EventSource()
+    {
+        @Override
+        public void addConfigurationListener(ConfigurationListener l)
+        {
+        }
+
+        @Override
+        public boolean removeConfigurationListener(ConfigurationListener l)
+        {
+            return false;
+        }
+
+        @Override
+        public void addErrorListener(ConfigurationErrorListener l)
+        {
+        }
+
+        @Override
+        public boolean removeErrorListener(ConfigurationErrorListener l)
+        {
+            return false;
+        }
+    };
+
     /** The class of the objects produced by this builder instance. */
     private final Class<T> resultClass;
 
+    /**
+     * A collection with configuration listeners to be registered at newly
+     * created configuration objects.
+     */
+    private final Collection<ConfigurationListener> configListeners;
+
+    /**
+     * A collection with error listeners to be registered at newly created
+     * configuration objects.
+     */
+    private final Collection<ConfigurationErrorListener> errorListeners;
+
     /** The map with current initialization parameters. */
     private Map<String, Object> parameters;
 
@@ -121,6 +168,8 @@ public class BasicConfigurationBuilder<T
         }
 
         resultClass = resCls;
+        configListeners = new ArrayList<ConfigurationListener>();
+        errorListeners = new ArrayList<ConfigurationErrorListener>();
         updateParameters(params);
     }
 
@@ -192,6 +241,69 @@ public class BasicConfigurationBuilder<T
     }
 
     /**
+     * Adds the specified listener for {@code ConfigurationEvent}s to this
+     * builder. It is also registered at the result objects produced by this
+     * builder.
+     *
+     * @param l the listener to be registered
+     * @return a reference to this builder for method chaining
+     */
+    public synchronized BasicConfigurationBuilder<T> addConfigurationListener(
+            ConfigurationListener l)
+    {
+        configListeners.add(l);
+        fetchEventSource().addConfigurationListener(l);
+        return this;
+    }
+
+    /**
+     * Removes the specified listener for {@code ConfigurationEvent}s from this
+     * builder. It is also removed from the current result object if it exists.
+     *
+     * @param l the listener to be removed
+     * @return a reference to this builder for method chaining
+     */
+    public synchronized BasicConfigurationBuilder<T> removeConfigurationListener(
+            ConfigurationListener l)
+    {
+        configListeners.remove(l);
+        fetchEventSource().removeConfigurationListener(l);
+        return this;
+    }
+
+    /**
+     * Adds the specified listener for {@code ConfigurationErrorEvent}s to this
+     * builder. It is also registered at the result objects produced by this
+     * builder.
+     *
+     * @param l the listener to be registered
+     * @return a reference to this builder for method chaining
+     */
+    public BasicConfigurationBuilder<T> addErrorListener(
+            ConfigurationErrorListener l)
+    {
+        errorListeners.add(l);
+        fetchEventSource().addErrorListener(l);
+        return this;
+    }
+
+    /**
+     * Removes the specified listener for {@code ConfigurationErrorEvent}s from
+     * this builder. It is also removed from the current result object if it
+     * exists.
+     *
+     * @param l the listener to be removed
+     * @return a reference to this builder for method chaining
+     */
+    public BasicConfigurationBuilder<T> removeErrorListener(
+            ConfigurationErrorListener l)
+    {
+        errorListeners.remove(l);
+        fetchEventSource().removeErrorListener(l);
+        return this;
+    }
+
+    /**
      * {@inheritDoc} This implementation creates the result configuration on
      * first access. Later invocations return the same object until this builder
      * is reset. The double-check idiom for lazy initialization is used (Bloch,
@@ -298,6 +410,7 @@ public class BasicConfigurationBuilder<T
     protected void initResultInstance(T obj) throws ConfigurationException
     {
         BeanHelper.initBean(obj, getResultDeclaration());
+        registerEventListeners(obj);
     }
 
     /**
@@ -397,6 +510,37 @@ public class BasicConfigurationBuilder<T
     }
 
     /**
+     * Registers the available event listeners at the given object. This method
+     * is called for each result object created by the builder.
+     *
+     * @param obj the object to initialize
+     */
+    private void registerEventListeners(T obj)
+    {
+        EventSource evSrc = fetchEventSource(obj);
+        for (ConfigurationListener l : configListeners)
+        {
+            evSrc.addConfigurationListener(l);
+        }
+        for (ConfigurationErrorListener l : errorListeners)
+        {
+            evSrc.addErrorListener(l);
+        }
+    }
+
+    /**
+     * Returns an {@code EventSource} for the current result object. If there is
+     * no current result or if it does not extend {@code EventSource}, a dummy
+     * event source is returned.
+     *
+     * @return the {@code EventSource} for the current result object
+     */
+    private EventSource fetchEventSource()
+    {
+        return fetchEventSource(result);
+    }
+
+    /**
      * Checks whether the bean class of the given {@code BeanDeclaration} equals
      * this builder's result class. This is done to ensure that only objects of
      * the expected result class are created.
@@ -413,4 +557,18 @@ public class BasicConfigurationBuilder<T
                     + decl.getBeanClassName());
         }
     }
+
+    /**
+     * Returns an {@code EventSource} for the specified object. If the object is
+     * an {@code EventSource}, it is returned. Otherwise, a dummy event source
+     * is returned.
+     *
+     * @param obj the object in question
+     * @return an {@code EventSource} for this object
+     */
+    private static EventSource fetchEventSource(Object obj)
+    {
+        return (obj instanceof EventSource) ? (EventSource) obj
+                : DUMMY_EVENT_SOURCE;
+    }
 }

Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBasicConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBasicConfigurationBuilder.java?rev=1394243&r1=1394242&r2=1394243&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBasicConfigurationBuilder.java
(original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBasicConfigurationBuilder.java
Thu Oct  4 20:18:31 2012
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertNot
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -34,6 +35,8 @@ import org.apache.commons.configuration.
 import org.apache.commons.configuration.ConfigurationRuntimeException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.commons.configuration.beanutils.BeanDeclaration;
+import org.apache.commons.configuration.event.ConfigurationErrorListener;
+import org.apache.commons.configuration.event.ConfigurationListener;
 import org.easymock.EasyMock;
 import org.junit.Test;
 
@@ -312,6 +315,100 @@ public class TestBasicConfigurationBuild
     }
 
     /**
+     * Tests whether configuration listeners can be added.
+     */
+    @Test
+    public void testAddConfigurationListener() throws ConfigurationException
+    {
+        ConfigurationListener l1 =
+                EasyMock.createMock(ConfigurationListener.class);
+        ConfigurationListener l2 =
+                EasyMock.createMock(ConfigurationListener.class);
+        EasyMock.replay(l1, l2);
+        BasicConfigurationBuilder<PropertiesConfiguration> builder =
+                new BasicConfigurationBuilder<PropertiesConfiguration>(
+                        PropertiesConfiguration.class)
+                        .addConfigurationListener(l1);
+        PropertiesConfiguration config = builder.getConfiguration();
+        builder.addConfigurationListener(l2);
+        assertTrue("Listeners not registered", config
+                .getConfigurationListeners().containsAll(Arrays.asList(l1, l2)));
+    }
+
+    /**
+     * Tests whether configuration listeners can be removed.
+     */
+    @Test
+    public void testRemoveConfigurationListener() throws ConfigurationException
+    {
+        ConfigurationListener l1 =
+                EasyMock.createMock(ConfigurationListener.class);
+        ConfigurationListener l2 =
+                EasyMock.createMock(ConfigurationListener.class);
+        EasyMock.replay(l1, l2);
+        BasicConfigurationBuilder<PropertiesConfiguration> builder =
+                new BasicConfigurationBuilder<PropertiesConfiguration>(
+                        PropertiesConfiguration.class)
+                        .addConfigurationListener(l1).addConfigurationListener(
+                                l2);
+        builder.removeConfigurationListener(l2);
+        PropertiesConfiguration config = builder.getConfiguration();
+        assertFalse("Removed listener was registered", config
+                .getConfigurationListeners().contains(l2));
+        assertTrue("Listener not registered", config
+                .getConfigurationListeners().contains(l1));
+        builder.removeConfigurationListener(l1);
+        assertFalse("Listener still registered", config
+                .getConfigurationListeners().contains(l1));
+    }
+
+    /**
+     * Tests whether error listeners can be registered.
+     */
+    @Test
+    public void testAddErrorListener() throws ConfigurationException
+    {
+        ConfigurationErrorListener l1 =
+                EasyMock.createMock(ConfigurationErrorListener.class);
+        ConfigurationErrorListener l2 =
+                EasyMock.createMock(ConfigurationErrorListener.class);
+        EasyMock.replay(l1, l2);
+        BasicConfigurationBuilder<PropertiesConfiguration> builder =
+                new BasicConfigurationBuilder<PropertiesConfiguration>(
+                        PropertiesConfiguration.class).addErrorListener(l1);
+        PropertiesConfiguration config = builder.getConfiguration();
+        builder.addErrorListener(l2);
+        assertTrue("Listeners not registered", config.getErrorListeners()
+                .containsAll(Arrays.asList(l1, l2)));
+    }
+
+    /**
+     * Tests whether error listeners can be removed.
+     */
+    @Test
+    public void testRemoveErrorListener() throws ConfigurationException
+    {
+        ConfigurationErrorListener l1 =
+                EasyMock.createMock(ConfigurationErrorListener.class);
+        ConfigurationErrorListener l2 =
+                EasyMock.createMock(ConfigurationErrorListener.class);
+        EasyMock.replay(l1, l2);
+        BasicConfigurationBuilder<PropertiesConfiguration> builder =
+                new BasicConfigurationBuilder<PropertiesConfiguration>(
+                        PropertiesConfiguration.class).addErrorListener(l1)
+                        .addErrorListener(l2);
+        builder.removeErrorListener(l2);
+        PropertiesConfiguration config = builder.getConfiguration();
+        assertFalse("Removed listener was registered", config
+                .getErrorListeners().contains(l2));
+        assertTrue("Listener not registered", config
+                .getErrorListeners().contains(l1));
+        builder.removeErrorListener(l1);
+        assertFalse("Listener still registered", config
+                .getErrorListeners().contains(l1));
+    }
+
+    /**
      * A test thread class for testing whether the builder's result object can
      * be requested concurrently.
      */



Mime
View raw message