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/28 21:58:46 UTC
svn commit: r1439624 - in /commons/proper/configuration/trunk/src:
main/java/org/apache/commons/configuration/builder/combined/
test/java/org/apache/commons/configuration/builder/combined/ test/resources/
Author: oheger
Date: Mon Jan 28 20:58:46 2013
New Revision: 1439624
URL: http://svn.apache.org/viewvc?rev=1439624&view=rev
Log:
Added reloading support for the integration of MultiFileConfigurationBuilder with CombinedConfigurationBuilder.
Added:
commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml (with props)
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java
commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java
Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java?rev=1439624&r1=1439623&r2=1439624&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java Mon Jan 28 20:58:46 2013
@@ -26,6 +26,8 @@ import org.apache.commons.configuration.
import org.apache.commons.configuration.builder.BuilderConfigurationWrapperFactory.EventSourceSupport;
import org.apache.commons.configuration.builder.BuilderListener;
import org.apache.commons.configuration.builder.ConfigurationBuilder;
+import org.apache.commons.configuration.reloading.ReloadingController;
+import org.apache.commons.configuration.reloading.ReloadingControllerSupport;
/**
* <p>
@@ -123,33 +125,100 @@ public class MultiFileConfigurationBuild
* Creates the {@code ConfigurationBuilder} to be returned by this provider.
* This is a very simple implementation which always returns the same
* wrapper configuration instance. The handling of builder listeners is
- * delegated to the wrapped {@code MultiFileConfigurationBuilder}.
+ * delegated to the wrapped {@code MultiFileConfigurationBuilder}. If
+ * reloading is support, the builder returned by this method also implements
+ * the {@link ReloadingControllerSupport} interface.
*
* @param multiBuilder the {@code MultiFileConfigurationBuilder}
* @param wrapConfig the configuration to be returned
* @return the wrapper builder
*/
private static ConfigurationBuilder<? extends Configuration> createWrapperBuilder(
- final ConfigurationBuilder<? extends Configuration> multiBuilder,
- final Configuration wrapConfig)
+ ConfigurationBuilder<? extends Configuration> multiBuilder,
+ Configuration wrapConfig)
{
- return new ConfigurationBuilder<Configuration>()
+ if (multiBuilder instanceof ReloadingControllerSupport)
{
- public Configuration getConfiguration()
- throws ConfigurationException
- {
- return wrapConfig;
- }
-
- public void addBuilderListener(BuilderListener l)
- {
- multiBuilder.addBuilderListener(l);
- }
-
- public void removeBuilderListener(BuilderListener l)
- {
- multiBuilder.removeBuilderListener(l);
- }
- };
+ return new ReloadableWrapperBuilder(wrapConfig, multiBuilder);
+ }
+ else
+ {
+ return new WrapperBuilder(wrapConfig, multiBuilder);
+ }
+ }
+
+ /**
+ * A simple wrapper implementation of the {@code ConfigurationBuilder}
+ * interface which returns a fix configuration and delegates to another
+ * builder for event listener management.
+ */
+ private static class WrapperBuilder implements
+ ConfigurationBuilder<Configuration>
+ {
+ /** The configuration managed by this builder. */
+ private final Configuration configuration;
+
+ /** The builder to which this instance delegates. */
+ private final ConfigurationBuilder<? extends Configuration> builder;
+
+ /**
+ * Creates a new instance of {@code WrapperBuilder}.
+ *
+ * @param conf the managed configuration
+ * @param bldr the underlying builder
+ */
+ public WrapperBuilder(Configuration conf,
+ ConfigurationBuilder<? extends Configuration> bldr)
+ {
+ configuration = conf;
+ builder = bldr;
+ }
+
+ public Configuration getConfiguration() throws ConfigurationException
+ {
+ return configuration;
+ }
+
+ public void addBuilderListener(BuilderListener l)
+ {
+ builder.addBuilderListener(l);
+ }
+
+ public void removeBuilderListener(BuilderListener l)
+ {
+ builder.removeBuilderListener(l);
+ }
+ }
+
+ /**
+ * A wrapper builder implementation which also provides a
+ * {@code ReloadingController}. This class assumes that the wrapped builder
+ * implements {@code ReloadingControllerSupport}. So the reloading
+ * controller can be obtained from this object.
+ */
+ private static class ReloadableWrapperBuilder extends WrapperBuilder
+ implements ReloadingControllerSupport
+ {
+ /** The object for obtaining the reloading controller. */
+ private final ReloadingControllerSupport ctrlSupport;
+
+ /**
+ * Creates a new instance of {@code ReloadableWrapperBuilder}.
+ *
+ * @param conf the managed configuration
+ * @param bldr the underlying builder (must implement
+ * {@code ReloadingControllerSupport})
+ */
+ public ReloadableWrapperBuilder(Configuration conf,
+ ConfigurationBuilder<? extends Configuration> bldr)
+ {
+ super(conf, bldr);
+ ctrlSupport = (ReloadingControllerSupport) bldr;
+ }
+
+ public ReloadingController getReloadingController()
+ {
+ return ctrlSupport.getReloadingController();
+ }
}
}
Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java?rev=1439624&r1=1439623&r2=1439624&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java (original)
+++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedConfigurationBuilder.java Mon Jan 28 20:58:46 2013
@@ -28,6 +28,7 @@ import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -46,6 +47,7 @@ import org.apache.commons.configuration.
import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.configuration.XMLPropertiesConfiguration;
import org.apache.commons.configuration.builder.BasicConfigurationBuilder;
+import org.apache.commons.configuration.builder.BuilderListener;
import org.apache.commons.configuration.builder.ConfigurationBuilder;
import org.apache.commons.configuration.builder.FileBasedBuilderParametersImpl;
import org.apache.commons.configuration.builder.FileBasedConfigurationBuilder;
@@ -55,6 +57,8 @@ import org.apache.commons.configuration.
import org.apache.commons.configuration.event.ConfigurationListener;
import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
import org.apache.commons.configuration.interpol.Lookup;
+import org.apache.commons.configuration.reloading.ReloadingController;
+import org.apache.commons.configuration.reloading.ReloadingControllerSupport;
import org.apache.commons.configuration.resolver.CatalogResolver;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
import org.easymock.EasyMock;
@@ -1006,14 +1010,14 @@ public class TestCombinedConfigurationBu
* Loads a test file which includes a MultiFileConfigurationBuilder
* declaration and returns the resulting configuration.
*
+ * @param fileName the name of the file to be loaded
* @return the resulting combined configuration
* @throws ConfigurationException if an error occurs
*/
- private CombinedConfiguration createMultiFileConfig()
+ private CombinedConfiguration createMultiFileConfig(String fileName)
throws ConfigurationException
{
- File testFile =
- ConfigurationAssert.getTestFile("testCCMultiTenent.xml");
+ File testFile = ConfigurationAssert.getTestFile(fileName);
builder.configure(new FileBasedBuilderParametersImpl()
.setFile(testFile));
CombinedConfiguration config = builder.getConfiguration();
@@ -1029,7 +1033,7 @@ public class TestCombinedConfigurationBu
@Test
public void testMultiTenentConfiguration() throws ConfigurationException
{
- CombinedConfiguration config = createMultiFileConfig();
+ CombinedConfiguration config = createMultiFileConfig("testCCMultiTenent.xml");
checkMultiFile("1001", config, 15);
checkMultiFile("1002", config, 25);
checkMultiFile("1003", config, 35);
@@ -1044,7 +1048,7 @@ public class TestCombinedConfigurationBu
public void testMultiTenentConfigurationProperties()
throws ConfigurationException
{
- CombinedConfiguration config = createMultiFileConfig();
+ CombinedConfiguration config = createMultiFileConfig("testCCMultiTenent.xml");
switchToMultiFile("1001");
HierarchicalConfiguration multiConf =
(HierarchicalConfiguration) config
@@ -1085,6 +1089,66 @@ public class TestCombinedConfigurationBu
}
/**
+ * Tests whether reloading support works for MultiFileConfigurationBuilder.
+ */
+ @Test
+ public void testMultiTenentConfigurationReloading()
+ throws ConfigurationException, InterruptedException
+ {
+ CombinedConfiguration config =
+ createMultiFileConfig("testCCMultiTenentReloading.xml");
+ File outFile =
+ ConfigurationAssert.getOutFile("MultiFileReloadingTest.xml");
+ switchToMultiFile(outFile.getAbsolutePath());
+ XMLConfiguration reloadConfig = new XMLConfiguration();
+ final String key = "test.reload";
+ reloadConfig.setProperty(key, "no");
+ reloadConfig.save(outFile);
+ try
+ {
+ assertEquals("Wrong property", "no", config.getString(key));
+ ConfigurationBuilder<? extends Configuration> childBuilder =
+ builder.getNamedBuilder("clientConfig");
+ assertTrue("Not a reloading builder",
+ childBuilder instanceof ReloadingControllerSupport);
+ ReloadingController ctrl =
+ ((ReloadingControllerSupport) childBuilder)
+ .getReloadingController();
+ ctrl.checkForReloading(null); // initialize reloading
+ BuilderListenerTestImpl l = new BuilderListenerTestImpl();
+ childBuilder.addBuilderListener(l);
+ reloadConfig.setProperty(key, "yes");
+ reloadConfig.save(outFile);
+
+ int attempts = 10;
+ boolean changeDetected;
+ do
+ {
+ changeDetected = ctrl.checkForReloading(null);
+ if (!changeDetected)
+ {
+ Thread.sleep(1000);
+ }
+ } while (!changeDetected && --attempts > 0);
+ assertTrue("No change detected", changeDetected);
+ assertEquals("Wrong updated property", "yes", builder
+ .getConfiguration().getString(key));
+ assertEquals("No change event received", 1, l.getBuilders().size());
+ BasicConfigurationBuilder<? extends Configuration> multiBuilder =
+ (BasicConfigurationBuilder<? extends Configuration>) l
+ .getBuilders().get(0);
+ childBuilder.removeBuilderListener(l);
+ multiBuilder.resetResult();
+ assertEquals("Got another change event received", 1, l
+ .getBuilders().size());
+ }
+ finally
+ {
+ outFile.delete();
+ }
+ }
+
+ /**
* A test builder provider implementation for testing whether providers can
* be defined in the definition file.
*/
@@ -1231,4 +1295,31 @@ public class TestCombinedConfigurationBu
return map.get(key);
}
}
+
+ /**
+ * A test implementation of the BuilderListener interface.
+ */
+ private static class BuilderListenerTestImpl implements BuilderListener
+ {
+ /** A list for the notified builders. */
+ private final List<ConfigurationBuilder<? extends Configuration>> builders =
+ new LinkedList<ConfigurationBuilder<? extends Configuration>>();
+
+ public void builderReset(
+ ConfigurationBuilder<? extends Configuration> builder)
+ {
+ builders.add(builder);
+ }
+
+ /**
+ * Returns a list with builders for which a reset notification was
+ * received.
+ *
+ * @return the list with builders
+ */
+ public List<ConfigurationBuilder<? extends Configuration>> getBuilders()
+ {
+ return builders;
+ }
+ }
}
Added: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml?rev=1439624&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml (added)
+++ commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml Mon Jan 28 20:58:46 2013
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+ 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.
+-->
+<!-- Test configuration definition file that includes a builder for
+ multiple configuration files that is configured to support reloading.
+ $Id$
+-->
+<configuration>
+ <header>
+ <result keyPattern="$${sys:Id}"
+ config-class="org.apache.commons.configuration.DynamicCombinedConfiguration">
+ </result>
+ </header>
+ <override>
+ <multiXml filePattern="$${sys:Id}"
+ config-name="clientConfig" config-reload="true"/>
+ </override>
+</configuration>
\ No newline at end of file
Propchange: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenentReloading.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml