Author: oheger Date: Tue Dec 18 21:20:10 2012 New Revision: 1423668 URL: http://svn.apache.org/viewvc?rev=1423668&view=rev Log: Added support for nested combined configurations in the configuration definition file.
Added: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java (with props) commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml (with props) Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedBuilderParametersImpl.java 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/TestCombinedBuilderParametersImpl.java Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedBuilderParametersImpl.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedBuilderParametersImpl.java?rev=1423668&r1=1423667&r2=1423668&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedBuilderParametersImpl.java (original) +++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedBuilderParametersImpl.java Tue Dec 18 21:20:10 2012 @@ -200,6 +200,29 @@ public class CombinedBuilderParametersIm } /** + * Registers all {@code ConfigurationBuilderProvider}s in the given + * parameters object which have not yet been registered. This method works + * like the method with the same name, but the map with providers is + * obtained from the passed in parameters object. + * + * @param params the parameters object from which to copy providers(must not + * be <b>null</b>) + * @return a reference to this object for method chaining + * @throws IllegalArgumentException if the source parameters object is + * <b>null</b> + */ + public CombinedBuilderParametersImpl registerMissingProviders( + CombinedBuilderParametersImpl params) + { + if (params == null) + { + throw new IllegalArgumentException( + "Source parameters must not be null!"); + } + return registerMissingProviders(params.getProviders()); + } + + /** * Returns an (unmodifiable) map with the currently registered * {@code ConfigurationBuilderProvider} objects. * 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=1423668&r1=1423667&r2=1423668&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 Tue Dec 18 21:20:10 2012 @@ -447,19 +447,20 @@ public class CombinedConfigurationBuilde "org.apache.commons.configuration.plist.PropertyListConfiguration", EXT_XML, Arrays.asList(FILE_PARAMS)); - /** Constant for the provider for configuration definition files.*/ - private static final BaseConfigurationBuilderProvider BUILDER_PROVIDER = null; + /** Constant for the provider for configuration definition files. */ + private static final BaseConfigurationBuilderProvider COMBINED_PROVIDER = + new CombinedConfigurationBuilderProvider(); /** 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" }; /** 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/*, BUILDER_PROVIDER */ + SYSTEM_PROVIDER, ENV_PROVIDER, JNDI_PROVIDER, COMBINED_PROVIDER }; /** A map with the default configuration builder providers. */ @@ -502,6 +503,9 @@ public class CombinedConfigurationBuilde /** The current XML parameters object. */ private XMLBuilderParametersImpl currentXMLParameters; + /** The configuration that is currently constructed. */ + private CombinedConfiguration currentConfiguration; + /** * Creates a new instance of {@code CombinedConfigurationBuilder}. No parameters * are set. @@ -738,6 +742,9 @@ public class CombinedConfigurationBuilde protected void initResultInstance(CombinedConfiguration result) throws ConfigurationException { + super.initResultInstance(result); + + currentConfiguration = result; HierarchicalConfiguration config = getDefinitionConfiguration(); if (config.getMaxIndex(KEY_COMBINER) < 0) { @@ -762,6 +769,7 @@ public class CombinedConfigurationBuilde initNodeCombinerListNodes(addConfig, config, KEY_ADDITIONAL_LIST); createAndAddConfigurations(addConfig, data.getUnionBuilders(), data); } + currentConfiguration = null; } /** @@ -953,6 +961,35 @@ public class CombinedConfigurationBuilde { initChildFileBasedParameters((FileBasedBuilderProperties<?>) params); } + if(params instanceof CombinedBuilderParametersImpl) { + initChildCombinedParameters((CombinedBuilderParametersImpl) params); + } + } + + /** + * Initializes the event listeners of the specified builder from this + * object. This method is used to inherit all listeners from a parent + * builder. + * + * @param dest the destination builder object which is to be initialized + */ + void initChildEventListeners( + BasicConfigurationBuilder<? extends Configuration> dest) + { + copyEventListeners(dest); + } + + /** + * Returns the configuration object that is currently constructed. This + * method can be called during construction of the result configuration. It + * is intended for internal usage, e.g. some specialized builder providers + * need access to this configuration to perform advanced initialization. + * + * @return the configuration that us currently under construction + */ + CombinedConfiguration getConfigurationUnderConstruction() + { + return currentConfiguration; } /** @@ -1036,6 +1073,21 @@ public class CombinedConfigurationBuilde } /** + * Initializes a parameters object for a combined configuration builder with + * properties already set for this parent builder. This implementation deals + * only with a subset of properties. Other properties are already handled by + * the specialized builder provider. + * + * @param params the parameters object + */ + private void initChildCombinedParameters( + CombinedBuilderParametersImpl params) + { + params.registerMissingProviders(currentParameters); + params.setBasePath(getBasePath()); + } + + /** * Obtains the data object for the configuration sources and the * corresponding builders. This object is created on first access and reset * when the definition builder sends a change event. This method is called Added: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java?rev=1423668&view=auto ============================================================================== --- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java (added) +++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java Tue Dec 18 21:20:10 2012 @@ -0,0 +1,123 @@ +/* + * 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 java.util.Collection; + +import org.apache.commons.configuration.CombinedConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.builder.BasicBuilderParameters; +import org.apache.commons.configuration.builder.BasicConfigurationBuilder; +import org.apache.commons.configuration.builder.BuilderParameters; + +/** + * <p> + * A specialized {@code ConfigurationBuilderProvider} implementation which deals + * with combined configuration builders. + * </p> + * <p> + * This class is used to support {@code <configuration>} elements in + * configuration definition files. The provider creates another + * {@link CombinedConfigurationBuilder} which inherits some of the properties + * from its parent builder. + * </p> + * + * @version $Id$ + * @since 2.0 + */ +public class CombinedConfigurationBuilderProvider extends + BaseConfigurationBuilderProvider +{ + /** Constant for the name of the supported builder class. */ + private static final String BUILDER_CLASS = + "org.apache.commons.configuration.builder.combined.CombinedConfigurationBuilder"; + + /** Constant for the name of the supported configuration class. */ + private static final String CONFIGURATION_CLASS = + "org.apache.commons.configuration.CombinedConfiguration"; + + /** Constant for the combined configuration builder parameters class. */ + private static final String COMBINED_PARAMS = + "org.apache.commons.configuration.builder.combined.CombinedBuilderParametersImpl"; + + /** Constant for the name of the file-based builder parameters class. */ + private static final String FILE_PARAMS = + "org.apache.commons.configuration.builder.FileBasedBuilderParametersImpl"; + + /** + * Creates a new instance of {@code CombinedConfigurationBuilderProvider}. + */ + public CombinedConfigurationBuilderProvider() + { + super(BUILDER_CLASS, BUILDER_CLASS, CONFIGURATION_CLASS, Arrays.asList( + COMBINED_PARAMS, FILE_PARAMS)); + } + + /** + * {@inheritDoc} This implementation creates the result builder object + * directly, not using reflection. (The reflection-based approach of the + * base class does not work here because a combined configuration builder + * has constructors with a different signature.) It also performs some + * additional initializations. + */ + @Override + protected BasicConfigurationBuilder<? extends Configuration> createBuilder( + ConfigurationDeclaration decl, Collection<BuilderParameters> params) + throws Exception + { + CombinedConfigurationBuilder builder = + new CombinedConfigurationBuilder(); + decl.getConfigurationBuilder().initChildEventListeners(builder); + return builder; + } + + /** + * {@inheritDoc} This implementation pre-fills basic parameters from the + * basic properties of the parent builder's result configuration. + */ + @Override + protected void initializeParameterObjects(ConfigurationDeclaration decl, + Collection<BuilderParameters> params) throws Exception + { + // we know that the first object is the combined builder parameters + // object + BasicBuilderParameters basicParams = + (BasicBuilderParameters) params.iterator().next(); + setUpBasicParameters(decl.getConfigurationBuilder() + .getConfigurationUnderConstruction(), basicParams); + // now properties set explicitly can be overridden + super.initializeParameterObjects(decl, params); + } + + /** + * Populates the specified parameters object with properties from the given + * configuration. This method is used to set default values for basic + * properties based on the result configuration of the parent builder. + * + * @param config the configuration whose properties are to be copied + * @param params the target parameters object + */ + private static void setUpBasicParameters(CombinedConfiguration config, + BasicBuilderParameters params) + { + params.setDelimiterParsingDisabled(config.isDelimiterParsingDisabled()) + .setListDelimiter(config.getListDelimiter()) + .setLogger(config.getLogger()) + .setThrowExceptionOnMissing(config.isThrowExceptionOnMissing()); + } +} Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/builder/combined/CombinedConfigurationBuilderProvider.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedBuilderParametersImpl.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedBuilderParametersImpl.java?rev=1423668&r1=1423667&r2=1423668&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedBuilderParametersImpl.java (original) +++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/builder/combined/TestCombinedBuilderParametersImpl.java Tue Dec 18 21:20:10 2012 @@ -205,7 +205,8 @@ public class TestCombinedBuilderParamete @Test(expected = IllegalArgumentException.class) public void testRegisterMissingProvidersNullMap() { - new CombinedBuilderParametersImpl().registerMissingProviders(null); + Map<String, ConfigurationBuilderProvider> map = null; + new CombinedBuilderParametersImpl().registerMissingProviders(map); } /** @@ -221,6 +222,46 @@ public class TestCombinedBuilderParamete } /** + * Tests whether missing providers can be copied from a parameters object. + */ + @Test + public void testRegisterMissingProvidersParams() + { + ConfigurationBuilderProvider provider1 = + EasyMock.createMock(ConfigurationBuilderProvider.class); + ConfigurationBuilderProvider provider2 = + EasyMock.createMock(ConfigurationBuilderProvider.class); + ConfigurationBuilderProvider provider3 = + EasyMock.createMock(ConfigurationBuilderProvider.class); + String tagPrefix = "testTag"; + CombinedBuilderParametersImpl params = + new CombinedBuilderParametersImpl(); + CombinedBuilderParametersImpl params2 = + new CombinedBuilderParametersImpl(); + params.registerProvider(tagPrefix, provider1); + params2.registerProvider(tagPrefix, provider2); + params2.registerProvider(tagPrefix + 1, provider3); + assertSame("Wrong result", params, + params.registerMissingProviders(params2)); + assertEquals("Wrong number of providers", 2, params.getProviders() + .size()); + assertSame("Wrong provider (1)", provider1, + params.providerForTag(tagPrefix)); + assertSame("Wrong provider (2)", provider3, + params.providerForTag(tagPrefix + 1)); + } + + /** + * Tries to copy providers from a null parameters object. + */ + @Test(expected = IllegalArgumentException.class) + public void testRegisterMissingProvidersParamsNull() + { + new CombinedBuilderParametersImpl() + .registerMissingProviders((CombinedBuilderParametersImpl) null); + } + + /** * Tests the result for an unknown provider. */ @Test Added: commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml?rev=1423668&view=auto ============================================================================== --- commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml (added) +++ commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml Tue Dec 18 21:20:10 2012 @@ -0,0 +1,31 @@ +<?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 another source for a + combined configuration. Some basic properties are defined to test the + inheritance of properties. + $Id$ +--> + +<configuration> + <header> + <result throwExceptionOnMissing="true"> + </result> + </header> + <configuration fileName="testDigesterConfiguration.xml" config-name="subcc" + throwExceptionOnMissing="false"/> +</configuration> Propchange: commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Propchange: commons/proper/configuration/trunk/src/test/resources/testCCCombinedChildBuilder.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml