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/27 21:40:34 UTC
svn commit: r1439172 - 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: Sun Jan 27 20:40:33 2013
New Revision: 1439172
URL: http://svn.apache.org/viewvc?rev=1439172&view=rev
Log:
Initial integration of MultiFileConfigurationBuilder with CombinedConfigurationBuilder.
Added:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java (with props)
commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml (with props)
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.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/CombinedConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java?rev=1439172&r1=1439171&r2=1439172&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilder.java Sun Jan 27 20:40:33 2013
@@ -26,7 +26,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.commons.configuration.AbstractConfiguration;
import org.apache.commons.configuration.CombinedConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
@@ -455,16 +454,23 @@ public class CombinedConfigurationBuilde
private static final BaseConfigurationBuilderProvider COMBINED_PROVIDER =
new CombinedConfigurationBuilderProvider();
+ /** Constant for the provider for multiple XML configurations. */
+ private static final MultiFileConfigurationBuilderProvider MULTI_XML_PROVIDER =
+ new MultiFileConfigurationBuilderProvider(
+ "org.apache.commons.configuration.XMLConfiguration",
+ "org.apache.commons.configuration.builder.XMLBuilderParametersImpl");
+
/** An array with the names of the default tags. */
private static final String[] DEFAULT_TAGS = {
"properties", "xml", "hierarchicalXml", "plist",
- "ini", "system", "env", "jndi", "configuration"
+ "ini", "system", "env", "jndi", "configuration", "multiXml"
};
/** An array with the providers for the default tags. */
private static final ConfigurationBuilderProvider[] DEFAULT_PROVIDERS = {
PROPERTIES_PROVIDER, XML_PROVIDER, XML_PROVIDER, PLIST_PROVIDER, INI_PROVIDER,
- SYSTEM_PROVIDER, ENV_PROVIDER, JNDI_PROVIDER, COMBINED_PROVIDER
+ SYSTEM_PROVIDER, ENV_PROVIDER, JNDI_PROVIDER, COMBINED_PROVIDER,
+ MULTI_XML_PROVIDER
};
/** A map with the default configuration builder providers. */
@@ -1496,7 +1502,7 @@ public class CombinedConfigurationBuilde
try
{
ccResult.addConfiguration(
- (AbstractConfiguration) builder.getConfiguration(),
+ builder.getConfiguration(),
decl.getName(), decl.getAt());
}
catch (ConfigurationException cex)
Added: 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=1439172&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java (added)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java Sun Jan 27 20:40:33 2013
@@ -0,0 +1,155 @@
+/*
+ * 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.Arrays;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.ConfigurationUtils;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.builder.BuilderConfigurationWrapperFactory;
+import org.apache.commons.configuration.builder.BuilderConfigurationWrapperFactory.EventSourceSupport;
+import org.apache.commons.configuration.builder.BuilderListener;
+import org.apache.commons.configuration.builder.ConfigurationBuilder;
+
+/**
+ * <p>
+ * A specialized {@code ConfigurationBuilderProvider} implementation for
+ * integrating {@link MultiFileConfigurationBuilder} with
+ * {@code CombinedConfigurationBuilder}.
+ * </p>
+ * <p>
+ * When using a configuration source managed by
+ * {@code MultiFileConfigurationBuilder} it is not sufficient to store the
+ * configuration once obtained from the builder in the resulting combined
+ * configuration. Rather, it has to be ensured that each access to this
+ * configuration queries the builder anew so that it can evaluate its file
+ * pattern and return a different configuration if necessary. Therefore, this
+ * class returns a specialized wrapper over a
+ * {@code MultiFileConfigurationBuilder} which returns a configuration wrapping
+ * the builder; so accessing the configuration's properties actually calls back
+ * to the builder. This constellation is compatible with the way
+ * {@code DynamicCombinedConfiguration} manages its data.
+ * </p>
+ *
+ * @version $Id$
+ * @since 2.0
+ */
+public class MultiFileConfigurationBuilderProvider extends
+ BaseConfigurationBuilderProvider
+{
+ /** Constant for the name of the builder class. */
+ private static final String BUILDER_CLASS =
+ "org.apache.commons.configuration.builder.combined.MultiFileConfigurationBuilder";
+
+ /** Constant for the name of the reloading builder class. */
+ private static final String RELOADING_BUILDER_CLASS =
+ "org.apache.commons.configuration.builder.combined.ReloadingMultiFileConfigurationBuilder";
+
+ /** Constant for the name of the parameters class. */
+ private static final String PARAM_CLASS =
+ "org.apache.commons.configuration.builder.combined.MultiFileBuilderParametersImpl";
+
+ /**
+ * Creates a new instance of {@code MultiFileConfigurationBuilderProvider}
+ * and sets the name of the configuration class to be returned by
+ * {@code MultiFileConfigurationBuilder}.
+ *
+ * @param configCls the name of the managed configuration class
+ * @param paramCls the name of the class of the parameters object to
+ * configure the managed configuration
+ */
+ public MultiFileConfigurationBuilderProvider(String configCls,
+ String paramCls)
+ {
+ super(BUILDER_CLASS, RELOADING_BUILDER_CLASS, configCls, Arrays.asList(
+ paramCls, PARAM_CLASS));
+ }
+
+ /**
+ * {@inheritDoc} This implementation lets the super class create a fully
+ * configured builder. Then it returns a special wrapper around it.
+ */
+ @Override
+ public ConfigurationBuilder<? extends Configuration> getConfigurationBuilder(
+ ConfigurationDeclaration decl) throws ConfigurationException
+ {
+ ConfigurationBuilder<? extends Configuration> multiBuilder =
+ super.getConfigurationBuilder(decl);
+ Configuration wrapConfig = createWrapperConfiguration(multiBuilder);
+ return createWrapperBuilder(multiBuilder, wrapConfig);
+ }
+
+ /**
+ * Creates a configuration which wraps the specified builder.
+ *
+ * @param builder the builder
+ * @return the wrapping configuration
+ */
+ // It is safe to disable any type checks because we manually determine
+ // the interface class to be passed to BuilderConfigurationWrapperFactory
+ @SuppressWarnings({
+ "unchecked", "rawtypes"
+ })
+ private Configuration createWrapperConfiguration(
+ ConfigurationBuilder builder)
+ {
+ Class<?> configClass =
+ ConfigurationUtils.loadClassNoEx(getConfigurationClass());
+ Class ifcClass =
+ HierarchicalConfiguration.class.isAssignableFrom(configClass) ? HierarchicalConfiguration.class
+ : Configuration.class;
+ return BuilderConfigurationWrapperFactory
+ .createBuilderConfigurationWrapper(ifcClass, builder,
+ EventSourceSupport.BUILDER_OPTIONAL);
+ }
+
+ /**
+ * 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}.
+ *
+ * @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)
+ {
+ return new ConfigurationBuilder<Configuration>()
+ {
+ public Configuration getConfiguration()
+ throws ConfigurationException
+ {
+ return wrapConfig;
+ }
+
+ public void addBuilderListener(BuilderListener l)
+ {
+ multiBuilder.addBuilderListener(l);
+ }
+
+ public void removeBuilderListener(BuilderListener l)
+ {
+ multiBuilder.removeBuilderListener(l);
+ }
+ };
+ }
+}
Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/MultiFileConfigurationBuilderProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
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=1439172&r1=1439171&r2=1439172&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 Sun Jan 27 20:40:33 2013
@@ -38,6 +38,7 @@ import org.apache.commons.configuration.
import org.apache.commons.configuration.ConfigurationAssert;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.DefaultFileSystem;
+import org.apache.commons.configuration.DynamicCombinedConfiguration;
import org.apache.commons.configuration.FileSystem;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.PropertiesConfiguration;
@@ -55,7 +56,9 @@ import org.apache.commons.configuration.
import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
import org.apache.commons.configuration.interpol.Lookup;
import org.apache.commons.configuration.resolver.CatalogResolver;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
import org.easymock.EasyMock;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -76,6 +79,12 @@ public class TestCombinedConfigurationBu
/** Constant for a named builder. */
private static final String BUILDER_NAME = "subBuilderName";
+ /**
+ * The name of the system property for selecting a file managed by a
+ * MultiFileConfigurationBuilder.
+ */
+ private static final String MULTI_FILE_PROPERTY = "Id";
+
/** Stores the object to be tested. */
protected CombinedConfigurationBuilder builder;
@@ -89,6 +98,12 @@ public class TestCombinedConfigurationBu
builder = new CombinedConfigurationBuilder();
}
+ @After
+ public void tearDown() throws Exception
+ {
+ System.getProperties().remove(MULTI_FILE_PROPERTY);
+ }
+
/**
* Creates a configuration builder for the definition configuration which
* always returns the passed in definition configuration.
@@ -988,6 +1003,88 @@ public class TestCombinedConfigurationBu
}
/**
+ * Loads a test file which includes a MultiFileConfigurationBuilder
+ * declaration and returns the resulting configuration.
+ *
+ * @return the resulting combined configuration
+ * @throws ConfigurationException if an error occurs
+ */
+ private CombinedConfiguration createMultiFileConfig()
+ throws ConfigurationException
+ {
+ File testFile =
+ ConfigurationAssert.getTestFile("testCCMultiTenent.xml");
+ builder.configure(new FileBasedBuilderParametersImpl()
+ .setFile(testFile));
+ CombinedConfiguration config = builder.getConfiguration();
+ assertTrue("Incorrect result configuration",
+ config instanceof DynamicCombinedConfiguration);
+ return config;
+ }
+
+ /**
+ * Tests whether a MultiFileConfigurationBuilder can be integrated into a
+ * combined configuration definition.
+ */
+ @Test
+ public void testMultiTenentConfiguration() throws ConfigurationException
+ {
+ CombinedConfiguration config = createMultiFileConfig();
+ checkMultiFile("1001", config, 15);
+ checkMultiFile("1002", config, 25);
+ checkMultiFile("1003", config, 35);
+ checkMultiFile("1004", config, 50);
+ }
+
+ /**
+ * Tests whether a configuration created by a MultiFileConfigurationBuilder
+ * has been initialized correctly.
+ */
+ @Test
+ public void testMultiTenentConfigurationProperties()
+ throws ConfigurationException
+ {
+ CombinedConfiguration config = createMultiFileConfig();
+ switchToMultiFile("1001");
+ HierarchicalConfiguration multiConf =
+ (HierarchicalConfiguration) config
+ .getConfiguration("clientConfig");
+ assertTrue(
+ "Expression engine not configured",
+ multiConf.getExpressionEngine() instanceof XPathExpressionEngine);
+ assertEquals("Wrong bg color", "#808080",
+ config.getString("colors.background"));
+ assertEquals("Wrong text color", "#000000",
+ multiConf.getString("colors/text"));
+ }
+
+ /**
+ * Helper method for testing whether properties of a MultiFileConfiguration
+ * can be obtained.
+ *
+ * @param key the key of the file to be accessed
+ * @param config the configuration to check
+ * @param rows the expected value of the test property
+ */
+ private void checkMultiFile(String key, CombinedConfiguration config,
+ int rows)
+ {
+ switchToMultiFile(key);
+ assertEquals("Wrong property value", rows, config.getInt("rowsPerPage"));
+ }
+
+ /**
+ * Sets the system property which selects a specific file managed by a
+ * MultiFileConfigurationBuilder.
+ *
+ * @param key the key to select the desired file
+ */
+ private static void switchToMultiFile(String key)
+ {
+ System.setProperty(MULTI_FILE_PROPERTY, key);
+ }
+
+ /**
* A test builder provider implementation for testing whether providers can
* be defined in the definition file.
*/
Added: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml?rev=1439172&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml (added)
+++ commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml Sun Jan 27 20:40:33 2013
@@ -0,0 +1,43 @@
+<?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. It collaborates with a
+ DynamicCombinedConfiguration.
+ $Id$
+-->
+<configuration>
+ <header>
+ <result loggerName="TestLogger"
+ config-class="org.apache.commons.configuration.DynamicCombinedConfiguration"
+ keyPattern="$${sys:Id}">
+ <nodeCombiner config-class="org.apache.commons.configuration.tree.MergeCombiner"/>
+ </result>
+ </header>
+ <override>
+ <multiXml filePattern="testMultiConfiguration_$${sys:Id}.xml"
+ config-name="clientConfig" schemaValidation="false">
+ <expressionEngine
+ config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
+ </multiXml>
+ <xml fileName="testMultiConfiguration_default.xml"
+ config-name="defaultConfig" delimiterParsingDisabled="true">
+ <expressionEngine
+ config-class="org.apache.commons.configuration.tree.xpath.XPathExpressionEngine"/>
+ </xml>
+ </override>
+</configuration>
\ No newline at end of file
Propchange: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: commons/proper/configuration/trunk/src/test/resources/testCCMultiTenent.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml