Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id AB125DE2F for ; Thu, 4 Oct 2012 20:19:20 +0000 (UTC) Received: (qmail 39446 invoked by uid 500); 4 Oct 2012 20:19:20 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 39243 invoked by uid 500); 4 Oct 2012 20:19:20 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 39236 invoked by uid 99); 4 Oct 2012 20:19:20 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Oct 2012 20:19:20 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 04 Oct 2012 20:19:16 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id C81ED23889B8 for ; Thu, 4 Oct 2012 20:18:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@commons.apache.org From: oheger@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20121004201831.C81ED23889B8@eris.apache.org> 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; /** *

@@ -78,9 +83,51 @@ import org.apache.commons.configuration. public class BasicConfigurationBuilder implements ConfigurationBuilder { + /** + * 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 resultClass; + /** + * A collection with configuration listeners to be registered at newly + * created configuration objects. + */ + private final Collection configListeners; + + /** + * A collection with error listeners to be registered at newly created + * configuration objects. + */ + private final Collection errorListeners; + /** The map with current initialization parameters. */ private Map parameters; @@ -121,6 +168,8 @@ public class BasicConfigurationBuilder(); + errorListeners = new ArrayList(); updateParameters(params); } @@ -192,6 +241,69 @@ public class BasicConfigurationBuilder 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 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 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 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 builder = + new BasicConfigurationBuilder( + 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 builder = + new BasicConfigurationBuilder( + 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 builder = + new BasicConfigurationBuilder( + 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 builder = + new BasicConfigurationBuilder( + 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. */