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


Reply via email to