Author: oheger
Date: Fri Jul 11 20:35:22 2014
New Revision: 1609822

URL: http://svn.apache.org/r1609822
Log:
Removed obsolete addConfigurationListener() method from EventSource.

This caused some adaptations in BuilderConfigurationWrapperFactory. Here the
way how an EventSource implementation is provided for a configuration mock
had to be reworked.

Modified:
    
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java
    
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderConfigurationWrapperFactory.java
    
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/BaseEventSource.java
    
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java
    
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBuilderConfigurationWrapperFactory.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=1609822&r1=1609821&r2=1609822&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
 Fri Jul 11 20:35:22 2014
@@ -27,7 +27,6 @@ import java.util.Iterator;
 
 import org.apache.commons.configuration.event.ConfigurationErrorEvent;
 import org.apache.commons.configuration.event.ConfigurationErrorListener;
-import org.apache.commons.configuration.event.ConfigurationListener;
 import org.apache.commons.configuration.event.Event;
 import org.apache.commons.configuration.event.EventListener;
 import org.apache.commons.configuration.event.EventSource;
@@ -81,10 +80,6 @@ public final class ConfigurationUtils
      */
     private static final EventSource DUMMY_EVENT_SOURCE = new EventSource()
     {
-        @Override
-        public void addConfigurationListener(ConfigurationListener l)
-        {
-        }
 
         @Override
         public void addErrorListener(ConfigurationErrorListener l)

Modified: 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderConfigurationWrapperFactory.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderConfigurationWrapperFactory.java?rev=1609822&r1=1609821&r2=1609822&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderConfigurationWrapperFactory.java
 (original)
+++ 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/BuilderConfigurationWrapperFactory.java
 Fri Jul 11 20:35:22 2014
@@ -87,7 +87,6 @@ public class BuilderConfigurationWrapper
      *        <b>null</b>
      * @param builder the wrapped {@code ConfigurationBuilder} (must not be
      *        <b>null</b>)
-     * @param evSrcSupport the level of {@code EventSource} support
      * @throws IllegalArgumentException if a required parameter is missing
      * @throws ConfigurationRuntimeException if an error occurs when creating
      *         the result {@code Configuration}
@@ -184,7 +183,7 @@ public class BuilderConfigurationWrapper
      * {@code Configuration} object returned by
      * {@code BuilderConfigurationWrapperFactory} also implements the
      * {@code EventSource} interface and how this implementation should work.
-     * See the documentation of the single constants for more details
+     * See the documentation of the single constants for more details.
      * </p>
      */
     public static enum EventSourceSupport
@@ -211,8 +210,12 @@ public class BuilderConfigurationWrapper
          * associated {@code ConfigurationBuilder} object. If this option is
          * used, generated {@code Configuration} objects provide a fully
          * functional implementation of {@code EventSource} by delegating to 
the
-         * builder. The builder must implement the {@code EventSource}
-         * interface, otherwise an exception is thrown.
+         * builder. It is expected that the builder defines the methods
+         * {@code addConfigurationListener()} and
+         * {@code removeConfigurationListener()}, to which the methods of the
+         * {@code EventSource} interface are mapped. This is the case for all
+         * builder implementations derived from
+         * {@code BasicConfigurationBuilder}.
          */
         BUILDER,
 
@@ -232,6 +235,18 @@ public class BuilderConfigurationWrapper
     private static class BuilderConfigurationWrapperInvocationHandler 
implements
             InvocationHandler
     {
+        /** The name of the event source method for removing a listener. */
+        private static final String METHOD_SOURCE_REMOVE =
+                "removeEventListener";
+
+        /** The name of the builder method for adding a listener. */
+        private static final String METHOD_BUILDER_ADD =
+                "addConfigurationListener";
+
+        /** The name of the builder method for removing a listener. */
+        private static final String METHOD_BUILDER_REMOVE =
+                "removeConfigurationListener";
+
         /** The wrapped builder. */
         private final ConfigurationBuilder<? extends Configuration> builder;
 
@@ -311,23 +326,75 @@ public class BuilderConfigurationWrapper
         private Object handleEventSourceInvocation(Method method, Object[] 
args)
                 throws Exception
         {
-            Object src;
-            boolean mockIfUnsupported;
+            Object target;
+            Method methodToInvoke;
             if (EventSourceSupport.DUMMY == eventSourceSupport)
             {
-                src = this;
-                mockIfUnsupported = true;
+                target = ConfigurationUtils.asEventSource(this, true);
+                methodToInvoke = method;
             }
             else
             {
-                src = builder;
-                mockIfUnsupported =
-                        EventSourceSupport.BUILDER_OPTIONAL == 
eventSourceSupport;
+                target = builder;
+                methodToInvoke = findBuilderMethod(method);
+                if (methodToInvoke == null)
+                {
+                    target =
+                            ConfigurationUtils
+                                    .asEventSource(
+                                            builder,
+                                            
EventSourceSupport.BUILDER_OPTIONAL == eventSourceSupport);
+                    methodToInvoke = method;
+                }
+            }
+
+            return convertResult(method.getReturnType(),
+                    methodToInvoke.invoke(target, args));
+        }
+
+        /**
+         * Determines the method on the builder to be called for the specified
+         * event source method. If no such method can be found, result is
+         * <b>null</b>.
+         *
+         * @param method the event source method to be called
+         * @return the corresponding builder method or <b>null</b>
+         */
+        private Method findBuilderMethod(Method method)
+        {
+            String builderMethodName =
+                    METHOD_SOURCE_REMOVE.equals(method.getName()) ? 
METHOD_BUILDER_REMOVE
+                            : METHOD_BUILDER_ADD;
+            try
+            {
+                return builder.getClass().getMethod(builderMethodName,
+                        method.getParameterTypes());
+            }
+            catch (NoSuchMethodException e)
+            {
+                return null;
             }
+        }
 
-            Object target =
-                    ConfigurationUtils.asEventSource(src, mockIfUnsupported);
-            return method.invoke(target, args);
+        /**
+         * Performs a conversion of the invocation result if necessary. The
+         * {@code removeEventListener()} method of {@code EventSource} returns 
a
+         * boolean, but the corresponding builder method returns a reference to
+         * the builder for method chaining. So these types have to be adapted.
+         *
+         * @param returnType the expected return type of the current invocation
+         * @param methodResult the actual result returned from the method
+         * @return the converted result
+         */
+        private static Object convertResult(Class<?> returnType,
+                Object methodResult)
+        {
+            if (Boolean.TYPE.equals(returnType)
+                    && !Boolean.class.isInstance(methodResult))
+            {
+                return Boolean.FALSE;
+            }
+            return methodResult;
         }
     }
 }

Modified: 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/BaseEventSource.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/BaseEventSource.java?rev=1609822&r1=1609821&r2=1609822&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/BaseEventSource.java
 (original)
+++ 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/BaseEventSource.java
 Fri Jul 11 20:35:22 2014
@@ -94,13 +94,6 @@ public class BaseEventSource implements 
         initListeners();
     }
 
-    @Override
-    public void addConfigurationListener(ConfigurationListener l)
-    {
-        checkListener(l);
-        listeners.add(l);
-    }
-
     /**
      * Returns a collection with all configuration event listeners that are
      * currently registered at this object.

Modified: 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java?rev=1609822&r1=1609821&r2=1609822&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java
 (original)
+++ 
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java
 Fri Jul 11 20:35:22 2014
@@ -33,15 +33,6 @@ package org.apache.commons.configuration
 public interface EventSource
 {
     /**
-     * Adds a configuration listener to this object.
-     *
-     * @param l the listener to add
-     * @deprecated Use {@code addEventListener()}
-     */
-    @Deprecated
-    void addConfigurationListener(ConfigurationListener l);
-
-    /**
      * Adds a new configuration error listener to this object. This listener
      * will then be notified about internal problems.
      *

Modified: 
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBuilderConfigurationWrapperFactory.java
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBuilderConfigurationWrapperFactory.java?rev=1609822&r1=1609821&r2=1609822&view=diff
==============================================================================
--- 
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBuilderConfigurationWrapperFactory.java
 (original)
+++ 
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/TestBuilderConfigurationWrapperFactory.java
 Fri Jul 11 20:35:22 2014
@@ -19,12 +19,19 @@ package org.apache.commons.configuration
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.util.Collection;
+
 import org.apache.commons.configuration.BaseHierarchicalConfiguration;
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.PropertiesConfiguration;
 import 
org.apache.commons.configuration.builder.BuilderConfigurationWrapperFactory.EventSourceSupport;
+import org.apache.commons.configuration.event.ConfigurationEvent;
+import org.apache.commons.configuration.event.EventListener;
+import org.apache.commons.configuration.event.EventListenerTestImpl;
 import org.apache.commons.configuration.event.EventSource;
 import org.apache.commons.configuration.ex.ConfigurationException;
 import org.apache.commons.configuration.ex.ConfigurationRuntimeException;
@@ -90,7 +97,7 @@ public class TestBuilderConfigurationWra
         conf.addProperty("test2", "42");
         BuilderConfigurationWrapperFactory factory =
                 new BuilderConfigurationWrapperFactory();
-        HierarchicalConfiguration wrapper =
+        HierarchicalConfiguration<?> wrapper =
                 factory.createBuilderConfigurationWrapper(
                         HierarchicalConfiguration.class, builder);
         assertEquals("Wrong value (1)", "value1", wrapper.getString("test1"));
@@ -111,7 +118,7 @@ public class TestBuilderConfigurationWra
         EasyMock.replay(builder);
         BuilderConfigurationWrapperFactory factory =
                 new BuilderConfigurationWrapperFactory();
-        HierarchicalConfiguration wrapper =
+        HierarchicalConfiguration<?> wrapper =
                 factory.createBuilderConfigurationWrapper(
                         HierarchicalConfiguration.class, builder);
         assertFalse("EventSource support", wrapper instanceof EventSource);
@@ -133,7 +140,7 @@ public class TestBuilderConfigurationWra
         EventSource src =
                 (EventSource) factory.createBuilderConfigurationWrapper(
                         HierarchicalConfiguration.class, builder);
-        src.addConfigurationListener(null);
+        src.addEventListener(ConfigurationEvent.ANY, null);
     }
 
     /**
@@ -153,7 +160,7 @@ public class TestBuilderConfigurationWra
         EventSource src =
                 (EventSource) factory.createBuilderConfigurationWrapper(
                         HierarchicalConfiguration.class, builder);
-        src.addConfigurationListener(null);
+        src.addEventListener(ConfigurationEvent.ANY, null);
     }
 
     /**
@@ -161,25 +168,28 @@ public class TestBuilderConfigurationWra
      */
     @Test
     public void testEventSourceSupportBuilderOptionalSupported()
+            throws ConfigurationException
     {
-        //TODO enable after code compiles again
-//        BuilderWithEventSource builder =
-//                EasyMock.createMock(BuilderWithEventSource.class);
-//        ConfigurationListener l =
-//                EasyMock.createMock(ConfigurationListener.class);
-//        builder.addConfigurationListener(l);
-//        EasyMock.expect(builder.removeConfigurationListener(l)).andReturn(
-//                Boolean.TRUE);
-//        EasyMock.replay(builder, l);
-//        BuilderConfigurationWrapperFactory factory =
-//                new BuilderConfigurationWrapperFactory(
-//                        EventSourceSupport.BUILDER_OPTIONAL);
-//        EventSource src =
-//                (EventSource) factory.createBuilderConfigurationWrapper(
-//                        Configuration.class, builder);
-//        src.addConfigurationListener(l);
-//        assertTrue("Wrong result", src.removeConfigurationListener(l));
-//        EasyMock.verify(builder);
+        BasicConfigurationBuilder<PropertiesConfiguration> builder =
+                new BasicConfigurationBuilder<PropertiesConfiguration>(
+                        PropertiesConfiguration.class);
+        EventListener<ConfigurationEvent> l1 = new EventListenerTestImpl(null);
+        EventListener<ConfigurationEvent> l2 = new EventListenerTestImpl(null);
+        BuilderConfigurationWrapperFactory factory =
+                new BuilderConfigurationWrapperFactory(
+                        EventSourceSupport.BUILDER_OPTIONAL);
+        EventSource src =
+                (EventSource) factory.createBuilderConfigurationWrapper(
+                        Configuration.class, builder);
+
+        src.addEventListener(ConfigurationEvent.ANY, l1);
+        src.addEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2);
+        src.removeEventListener(ConfigurationEvent.ANY_HIERARCHICAL, l2);
+        PropertiesConfiguration config = builder.getConfiguration();
+        Collection<EventListener<? super ConfigurationEvent>> listeners =
+                config.getEventListeners(ConfigurationEvent.ANY_HIERARCHICAL);
+        assertTrue("Registered listener not found", listeners.contains(l1));
+        assertFalse("Removed listener still found", listeners.contains(l2));
     }
 
     /**
@@ -200,7 +210,7 @@ public class TestBuilderConfigurationWra
         EventSource src =
                 (EventSource) factory.createBuilderConfigurationWrapper(
                         HierarchicalConfiguration.class, builder);
-        src.addErrorListener(null);
+        src.addEventListener(ConfigurationEvent.ANY, null);
     }
 
     /**
@@ -213,7 +223,7 @@ public class TestBuilderConfigurationWra
                 new BuilderConfigurationWrapperFactory(
                         EventSourceSupport.BUILDER_OPTIONAL);
         factory.createBuilderConfigurationWrapper(null,
-                EasyMock.createMock(BuilderWithEventSource.class));
+                createBuilderMock(new BaseHierarchicalConfiguration()));
     }
 
     /**
@@ -226,12 +236,4 @@ public class TestBuilderConfigurationWra
                 new BuilderConfigurationWrapperFactory();
         factory.createBuilderConfigurationWrapper(Configuration.class, null);
     }
-
-    /**
-     * A combined interface needed for mock generation.
-     */
-    private static interface BuilderWithEventSource extends
-            ConfigurationBuilder<Configuration>/*, EventSource*/
-    {
-    }
 }


Reply via email to