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/01/20 21:34:06 UTC

svn commit: r1435947 - in /commons/proper/configuration/trunk/src: main/java/org/apache/commons/configuration/builder/combined/ test/java/org/apache/commons/configuration/builder/combined/

Author: oheger
Date: Sun Jan 20 20:34:05 2013
New Revision: 1435947

URL: http://svn.apache.org/viewvc?rev=1435947&view=rev
Log:
Added a new MultiFileConfigurationBuilder class with reloading support.

Added:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java   (with props)
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java   (with props)
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java   (with props)
Modified:
    commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilder.java
    commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestMultiFileConfigurationBuilder.java

Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilder.java?rev=1435947&r1=1435946&r2=1435947&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilder.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilder.java Sun Jan 20 20:34:05 2013
@@ -183,14 +183,14 @@ public class MultiFileConfigurationBuild
         String fileName = constructFileName(params, multiParams);
 
         FileBasedConfigurationBuilder<T> builder =
-                managedBuilders.get(fileName);
+                getManagedBuilders().get(fileName);
         if (builder == null)
         {
             builder =
                     createInitializedManagedBuilder(fileName,
                             createManagedBuilderParameters(params, multiParams));
             FileBasedConfigurationBuilder<T> newBuilder =
-                    ConcurrentUtils.putIfAbsent(managedBuilders, fileName,
+                    ConcurrentUtils.putIfAbsent(getManagedBuilders(), fileName,
                             builder);
             if (newBuilder == builder)
             {
@@ -213,7 +213,7 @@ public class MultiFileConfigurationBuild
             ConfigurationListener l)
     {
         super.addConfigurationListener(l);
-        for (FileBasedConfigurationBuilder<T> b : managedBuilders.values())
+        for (FileBasedConfigurationBuilder<T> b : getManagedBuilders().values())
         {
             b.addConfigurationListener(l);
         }
@@ -229,7 +229,7 @@ public class MultiFileConfigurationBuild
             ConfigurationListener l)
     {
         super.removeConfigurationListener(l);
-        for (FileBasedConfigurationBuilder<T> b : managedBuilders.values())
+        for (FileBasedConfigurationBuilder<T> b : getManagedBuilders().values())
         {
             b.removeConfigurationListener(l);
         }
@@ -245,7 +245,7 @@ public class MultiFileConfigurationBuild
             ConfigurationErrorListener l)
     {
         super.addErrorListener(l);
-        for (FileBasedConfigurationBuilder<T> b : managedBuilders.values())
+        for (FileBasedConfigurationBuilder<T> b : getManagedBuilders().values())
         {
             b.addErrorListener(l);
         }
@@ -261,7 +261,7 @@ public class MultiFileConfigurationBuild
             ConfigurationErrorListener l)
     {
         super.removeErrorListener(l);
-        for (FileBasedConfigurationBuilder<T> b : managedBuilders.values())
+        for (FileBasedConfigurationBuilder<T> b : getManagedBuilders().values())
         {
             b.removeErrorListener(l);
         }
@@ -275,11 +275,11 @@ public class MultiFileConfigurationBuild
     @Override
     public synchronized void resetParameters()
     {
-        for (FileBasedConfigurationBuilder<T> b : managedBuilders.values())
+        for (FileBasedConfigurationBuilder<T> b : getManagedBuilders().values())
         {
             b.removeBuilderListener(managedBuilderDelegationListener);
         }
-        managedBuilders.clear();
+        getManagedBuilders().clear();
         super.resetParameters();
     }
 
@@ -347,6 +347,19 @@ public class MultiFileConfigurationBuild
     }
 
     /**
+     * Returns the map with the managed builders created so far by this
+     * {@code MultiFileConfigurationBuilder}. This map is exposed to derived
+     * classes so they can access managed builders directly. However, derived
+     * classes are not expected to manipulate this map.
+     *
+     * @return the map with the managed builders
+     */
+    protected ConcurrentMap<String, FileBasedConfigurationBuilder<T>> getManagedBuilders()
+    {
+        return managedBuilders;
+    }
+
+    /**
      * Registers event listeners at the passed in newly created managed builder.
      * This method registers a special {@code BuilderListener} which propagates
      * builder events to listeners registered at this builder. In addition,

Added: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java?rev=1435947&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java (added)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java Sun Jan 20 20:34:05 2013
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.configuration.builder.combined;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.FileBasedConfiguration;
+import org.apache.commons.configuration.builder.FileBasedConfigurationBuilder;
+import org.apache.commons.configuration.builder.ReloadingFileBasedConfigurationBuilder;
+import org.apache.commons.configuration.reloading.CombinedReloadingController;
+import org.apache.commons.configuration.reloading.ReloadingController;
+import org.apache.commons.configuration.reloading.ReloadingControllerSupport;
+
+/**
+ * <p>
+ * A specialized {@code MultiFileConfigurationBuilder} implementation which adds
+ * support for reloading.
+ * </p>
+ * <p>
+ * This class - as its super class - allows operating on multiple configuration
+ * files whose file names are determined using a file name pattern and a
+ * {@code ConfigurationInterpolator} object. It provides the following
+ * additional features:
+ * <ul>
+ * <li>Configuration builder for managed configurations have reloading support.
+ * So reloading is possible for all configuration sources loaded by this builder
+ * instance.</li>
+ * <li>A {@link ReloadingController} is provided which can be used to trigger
+ * reload checks on all managed configurations.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Although this builder manages an arbitrary number of child configurations, to
+ * clients only a single configuration is visible - the one selected by the
+ * evaluation of the file name pattern. Builder reset notifications triggered by
+ * the reloading mechanism do not really take this fact into account; they are
+ * not limited to the currently selected child configuration, but occur for each
+ * of the managed configuration.
+ * </p>
+ *
+ * @version $Id$
+ * @since 2.0
+ * @param <T> the concrete type of {@code Configuration} objects created by this
+ *        builder
+ */
+public class ReloadingMultiFileConfigurationBuilder<T extends FileBasedConfiguration>
+        extends MultiFileConfigurationBuilder<T> implements
+        ReloadingControllerSupport
+{
+    /** The reloading controller used by this builder. */
+    private final ReloadingController reloadingController =
+            createReloadingController();
+
+    /**
+     * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder}
+     * and sets initialization parameters and a flag whether initialization
+     * failures should be ignored.
+     *
+     * @param resCls the result configuration class
+     * @param params a map with initialization parameters
+     * @param allowFailOnInit a flag whether initialization errors should be
+     *        ignored
+     * @throws IllegalArgumentException if the result class is <b>null</b>
+     */
+    public ReloadingMultiFileConfigurationBuilder(Class<T> resCls,
+            Map<String, Object> params, boolean allowFailOnInit)
+    {
+        super(resCls, params, allowFailOnInit);
+    }
+
+    /**
+     * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder}
+     * and sets initialization parameters.
+     *
+     * @param resCls the result configuration class
+     * @param params a map with initialization parameters
+     * @throws IllegalArgumentException if the result class is <b>null</b>
+     */
+    public ReloadingMultiFileConfigurationBuilder(Class<T> resCls,
+            Map<String, Object> params)
+    {
+        super(resCls, params);
+    }
+
+    /**
+     * Creates a new instance of {@code ReloadingMultiFileConfigurationBuilder}
+     * without setting initialization parameters.
+     *
+     * @param resCls the result configuration class
+     * @throws IllegalArgumentException if the result class is <b>null</b>
+     */
+    public ReloadingMultiFileConfigurationBuilder(Class<T> resCls)
+    {
+        super(resCls);
+    }
+
+    /**
+     * {@inheritDoc} This implementation returns a special
+     * {@code ReloadingController} that delegates to the reloading controllers
+     * of the managed builders created so far.
+     */
+    public ReloadingController getReloadingController()
+    {
+        return reloadingController;
+    }
+
+    /**
+     * {@inheritDoc} This implementation returns a file-based configuration
+     * builder with reloading support.
+     */
+    @Override
+    protected FileBasedConfigurationBuilder<T> createManagedBuilder(
+            String fileName, Map<String, Object> params)
+            throws ConfigurationException
+    {
+        return new ReloadingFileBasedConfigurationBuilder<T>(getResultClass(),
+                params, isAllowFailOnInit());
+    }
+
+    /**
+     * Creates the reloading controller used by this builder. This method
+     * creates a specialized {@link CombinedReloadingController} which operates
+     * on the reloading controllers of the managed builders created so far.
+     *
+     * @return the newly created {@code ReloadingController}
+     */
+    private ReloadingController createReloadingController()
+    {
+        Set<ReloadingController> empty = Collections.emptySet();
+        return new CombinedReloadingController(empty)
+        {
+            @Override
+            public Collection<ReloadingController> getSubControllers()
+            {
+                Collection<FileBasedConfigurationBuilder<T>> builders =
+                        getManagedBuilders().values();
+                Collection<ReloadingController> controllers =
+                        new ArrayList<ReloadingController>(builders.size());
+                for (FileBasedConfigurationBuilder<T> b : builders)
+                {
+                    controllers.add(((ReloadingControllerSupport) b)
+                            .getReloadingController());
+                }
+                return controllers;
+            }
+        };
+    }
+}

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/ReloadingMultiFileConfigurationBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java?rev=1435947&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java (added)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java Sun Jan 20 20:34:05 2013
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.configuration.builder.combined;
+
+import org.apache.commons.configuration.builder.BasicBuilderParameters;
+import org.apache.commons.configuration.builder.BuilderParameters;
+import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
+import org.apache.commons.configuration.interpol.DefaultLookups;
+import org.junit.After;
+
+/**
+ * A base class for test classes for {@code MultiFileConfigurationBuilder} and
+ * derived classes. This class provides some common functionality related to
+ * file name pattern which can be used by concrete tests.
+ *
+ * @version $Id$
+ */
+public class AbstractMultiFileConfigurationBuilderTest
+{
+    /** The system property which selects a sub configuration. */
+    private static final String PROP = "Id";
+
+    /** The pattern for file names. */
+    protected static String PATTERN =
+            "target/test-classes/testMultiConfiguration_${sys:Id}.xml";
+
+    /**
+     * Sets a system property for accessing a specific configuration file from
+     * the test builder.
+     *
+     * @param id the ID of the managed configuration to load
+     */
+    protected static void switchToConfig(String id)
+    {
+        System.setProperty(PROP, id);
+    }
+
+    @After
+    public void tearDown() throws Exception
+    {
+        System.getProperties().remove(PROP);
+    }
+
+    /**
+     * Selects a specific configuration to be obtained from the builder.
+     *
+     * @param index the index of the configuration to be accessed (valid indices
+     *        are 1-3)
+     */
+    protected static void switchToConfig(int index)
+    {
+        switchToConfig("100" + index);
+    }
+
+    /**
+     * Creates a {@code ConfigurationInterpolator} to be used by tests. This
+     * object contains a lookup for system properties.
+     *
+     * @return the new {@code ConfigurationInterpolator}
+     */
+    protected static ConfigurationInterpolator createInterpolator()
+    {
+        ConfigurationInterpolator ci = new ConfigurationInterpolator();
+        ci.registerLookup(DefaultLookups.SYSTEM_PROPERTIES.getPrefix(),
+                DefaultLookups.SYSTEM_PROPERTIES.getLookup());
+        return ci;
+    }
+
+    /**
+     * Creates a parameters object with default settings for a test builder
+     * instance.
+     *
+     * @param managedParams the parameters for managed configurations
+     * @return the test parameters
+     */
+    protected static BasicBuilderParameters createTestBuilderParameters(
+            BuilderParameters managedParams)
+    {
+        return new MultiFileBuilderParametersImpl().setFilePattern(PATTERN)
+                .setManagedBuilderParameters(managedParams)
+                .setInterpolator(createInterpolator());
+    }
+}

Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/AbstractMultiFileConfigurationBuilderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestMultiFileConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestMultiFileConfigurationBuilder.java?rev=1435947&r1=1435946&r2=1435947&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestMultiFileConfigurationBuilder.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestMultiFileConfigurationBuilder.java Sun Jan 20 20:34:05 2013
@@ -36,11 +36,9 @@ import org.apache.commons.configuration.
 import org.apache.commons.configuration.event.ConfigurationErrorListener;
 import org.apache.commons.configuration.event.ConfigurationListener;
 import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
-import org.apache.commons.configuration.interpol.DefaultLookups;
 import org.apache.commons.configuration.tree.ExpressionEngine;
 import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
 import org.easymock.EasyMock;
-import org.junit.After;
 import org.junit.Test;
 import org.xml.sax.SAXParseException;
 
@@ -49,72 +47,8 @@ import org.xml.sax.SAXParseException;
  *
  * @version $Id$
  */
-public class TestMultiFileConfigurationBuilder
+public class TestMultiFileConfigurationBuilder extends AbstractMultiFileConfigurationBuilderTest
 {
-    /** The system property which selects a sub configuration. */
-    private static final String PROP = "Id";
-
-    /** The pattern for file names. */
-    private static String PATTERN =
-            "target/test-classes/testMultiConfiguration_${sys:Id}.xml";
-
-    @After
-    public void tearDown() throws Exception
-    {
-        System.getProperties().remove(PROP);
-    }
-
-    /**
-     * Sets a system property for accessing a specific configuration file from
-     * the test builder.
-     *
-     * @param id the ID of the managed configuration to load
-     */
-    private static void switchToConfig(String id)
-    {
-        System.setProperty(PROP, id);
-    }
-
-    /**
-     * Selects a specific configuration to be obtained from the builder.
-     *
-     * @param index the index of the configuration to be accessed (valid indices
-     *        are 1-3)
-     */
-    private static void switchToConfig(int index)
-    {
-        switchToConfig("100" + index);
-    }
-
-    /**
-     * Creates a {@code ConfigurationInterpolator} to be used by tests. This
-     * object contains a lookup for system properties.
-     *
-     * @return the new {@code ConfigurationInterpolator}
-     */
-    private static ConfigurationInterpolator createInterpolator()
-    {
-        ConfigurationInterpolator ci = new ConfigurationInterpolator();
-        ci.registerLookup(DefaultLookups.SYSTEM_PROPERTIES.getPrefix(),
-                DefaultLookups.SYSTEM_PROPERTIES.getLookup());
-        return ci;
-    }
-
-    /**
-     * Creates a parameters object with default settings for a test builder
-     * instance.
-     *
-     * @param managedParams the parameters for managed configurations
-     * @return the test parameters
-     */
-    private static BasicBuilderParameters createTestBuilderParameters(
-            BuilderParameters managedParams)
-    {
-        return new MultiFileBuilderParametersImpl().setFilePattern(PATTERN)
-                .setManagedBuilderParameters(managedParams)
-                .setInterpolator(createInterpolator());
-    }
-
     /**
      * Creates a test builder object with default settings.
      *

Added: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java?rev=1435947&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java (added)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java Sun Jan 20 20:34:05 2013
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.configuration.builder.combined;
+
+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 java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.configuration.builder.BasicBuilderParameters;
+import org.apache.commons.configuration.builder.FileBasedConfigurationBuilder;
+import org.apache.commons.configuration.builder.ReloadingFileBasedConfigurationBuilder;
+import org.apache.commons.configuration.builder.XMLBuilderParametersImpl;
+import org.apache.commons.configuration.reloading.ReloadingController;
+import org.apache.commons.configuration.tree.ExpressionEngine;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+/**
+ * Test class for {@code ReloadingMultiFileConfigurationBuilder}.
+ *
+ * @version $Id$
+ */
+public class TestReloadingMultiFileConfigurationBuilder extends
+        AbstractMultiFileConfigurationBuilderTest
+{
+    /**
+     * Tests whether parameters passed to the constructor are passed to the
+     * super class.
+     */
+    @Test
+    public void testInitWithParameters() throws ConfigurationException
+    {
+        ExpressionEngine engine = new XPathExpressionEngine();
+        BasicBuilderParameters params =
+                createTestBuilderParameters(new XMLBuilderParametersImpl()
+                        .setExpressionEngine(engine));
+        ReloadingMultiFileConfigurationBuilder<XMLConfiguration> builder =
+                new ReloadingMultiFileConfigurationBuilder<XMLConfiguration>(
+                        XMLConfiguration.class, params.getParameters());
+        switchToConfig(1);
+        XMLConfiguration config = builder.getConfiguration();
+        assertSame("Expression engine not set", engine,
+                config.getExpressionEngine());
+    }
+
+    /**
+     * Tests whether correct managed builders are created.
+     */
+    @Test
+    public void testCreateManagedBuilder() throws ConfigurationException
+    {
+        ReloadingMultiFileConfigurationBuilder<XMLConfiguration> builder =
+                new ReloadingMultiFileConfigurationBuilder<XMLConfiguration>(
+                        XMLConfiguration.class);
+        FileBasedConfigurationBuilder<XMLConfiguration> managedBuilder =
+                builder.createManagedBuilder("test.xml",
+                        createTestBuilderParameters(null).getParameters());
+        assertTrue(
+                "Not a reloading builder",
+                managedBuilder instanceof ReloadingFileBasedConfigurationBuilder);
+        assertFalse("Wrong flag value", managedBuilder.isAllowFailOnInit());
+    }
+
+    /**
+     * Tests whether the allowFailOnInit flag is passed to newly created managed
+     * builders.
+     */
+    @Test
+    public void testCreateManagedBuilderWithAllowFailFlag()
+            throws ConfigurationException
+    {
+        ReloadingMultiFileConfigurationBuilder<XMLConfiguration> builder =
+                new ReloadingMultiFileConfigurationBuilder<XMLConfiguration>(
+                        XMLConfiguration.class, null, true);
+        FileBasedConfigurationBuilder<XMLConfiguration> managedBuilder =
+                builder.createManagedBuilder("test.xml",
+                        createTestBuilderParameters(null).getParameters());
+        assertTrue("Wrong flag value", managedBuilder.isAllowFailOnInit());
+    }
+
+    /**
+     * Tests whether a reloading check works correctly.
+     */
+    @Test
+    public void testReloadingControllerCheck() throws ConfigurationException
+    {
+        ReloadingMultiFileConfigurationBuilderTestImpl builder =
+                new ReloadingMultiFileConfigurationBuilderTestImpl();
+        switchToConfig(1);
+        builder.getConfiguration();
+        switchToConfig(2);
+        builder.getConfiguration();
+        List<ReloadingController> controllers =
+                builder.getReloadingControllers();
+        assertEquals("Wrong number of reloading controllers", 2,
+                controllers.size());
+        EasyMock.reset(controllers.toArray());
+        for (ReloadingController c : controllers)
+        {
+            EasyMock.expect(c.checkForReloading(null)).andReturn(Boolean.FALSE);
+        }
+        EasyMock.replay(controllers.toArray());
+        assertFalse("Wrong result", builder.getReloadingController()
+                .checkForReloading(this));
+        EasyMock.verify(controllers.toArray());
+    }
+
+    /**
+     * Tests a reloading check which detects the need to reload.
+     */
+    @Test
+    public void testReloadingControllerCheckReloadingRequired()
+            throws ConfigurationException
+    {
+        ReloadingMultiFileConfigurationBuilderTestImpl builder =
+                new ReloadingMultiFileConfigurationBuilderTestImpl();
+        for (int i = 1; i <= 3; i++)
+        {
+            switchToConfig(i);
+            builder.getConfiguration();
+        }
+        List<ReloadingController> controllers =
+                builder.getReloadingControllers();
+        EasyMock.reset(controllers.toArray());
+        EasyMock.expect(controllers.get(0).checkForReloading(null))
+                .andReturn(Boolean.FALSE).anyTimes();
+        EasyMock.expect(controllers.get(1).checkForReloading(null)).andReturn(
+                Boolean.TRUE);
+        EasyMock.expect(controllers.get(2).checkForReloading(null))
+                .andReturn(Boolean.FALSE).anyTimes();
+        EasyMock.replay(controllers.toArray());
+        assertTrue("Wrong result", builder.getReloadingController()
+                .checkForReloading(this));
+        EasyMock.verify(controllers.toArray());
+    }
+
+    /**
+     * Tests whether the reloading state of the reloading controller can be
+     * reset.
+     */
+    @Test
+    public void testReloadingControllerResetReloadingState()
+            throws ConfigurationException
+    {
+        ReloadingMultiFileConfigurationBuilderTestImpl builder =
+                new ReloadingMultiFileConfigurationBuilderTestImpl();
+        switchToConfig(1);
+        builder.getConfiguration();
+        switchToConfig(2);
+        builder.getConfiguration();
+        List<ReloadingController> controllers =
+                builder.getReloadingControllers();
+        EasyMock.reset(controllers.toArray());
+        for (ReloadingController c : controllers)
+        {
+            EasyMock.expect(c.checkForReloading(null)).andReturn(Boolean.TRUE)
+                    .anyTimes();
+            c.resetReloadingState();
+        }
+        EasyMock.replay(controllers.toArray());
+        builder.getReloadingController().checkForReloading(null);
+        builder.getReloadingController().resetReloadingState();
+        EasyMock.verify(controllers.toArray());
+    }
+
+    /**
+     * A test implementation of the class under test which allows access to
+     * reloading controllers of managed configuration builders.
+     *
+     * @version $Id$
+     */
+    private static class ReloadingMultiFileConfigurationBuilderTestImpl extends
+            ReloadingMultiFileConfigurationBuilder<XMLConfiguration>
+    {
+        /**
+         * A list with mocks for reloading controllers created by this instance.
+         */
+        private final List<ReloadingController> reloadingControllers;
+
+        public ReloadingMultiFileConfigurationBuilderTestImpl()
+        {
+            super(XMLConfiguration.class, createTestBuilderParameters(null)
+                    .getParameters());
+            reloadingControllers = new ArrayList<ReloadingController>();
+        }
+
+        /**
+         * Returns the list with the mock reloading controllers for the managed
+         * configuration builders created by this instance.
+         *
+         * @return the list with mock reloading controllers
+         */
+        public List<ReloadingController> getReloadingControllers()
+        {
+            return reloadingControllers;
+        }
+
+        /**
+         * {@inheritDoc} This implementation creates a specialized reloading
+         * builder which is associated with a mock reloading controller.
+         */
+        @Override
+        protected FileBasedConfigurationBuilder<XMLConfiguration> createManagedBuilder(
+                String fileName, Map<String, Object> params)
+                throws ConfigurationException
+        {
+            final ReloadingController ctrl =
+                    EasyMock.createMock(ReloadingController.class);
+            reloadingControllers.add(ctrl);
+            return new ReloadingFileBasedConfigurationBuilder<XMLConfiguration>(
+                    getResultClass(), params)
+            {
+                @Override
+                public ReloadingController getReloadingController()
+                {
+                    return ctrl;
+                }
+            };
+        }
+    }
+}

Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestReloadingMultiFileConfigurationBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain