You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by rg...@apache.org on 2009/03/23 19:05:26 UTC

svn commit: r757474 [2/2] - in /commons/proper/configuration/trunk: ./ conf/ src/java/org/apache/commons/configuration/ src/java/org/apache/commons/configuration/reloading/ src/test/org/apache/commons/configuration/ src/test/org/apache/commons/configur...

Modified: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestJNDIConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestJNDIConfiguration.java?rev=757474&r1=757473&r2=757474&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestJNDIConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestJNDIConfiguration.java Mon Mar 23 18:05:25 2009
@@ -18,6 +18,7 @@
 package org.apache.commons.configuration;
 
 import java.util.Hashtable;
+import java.util.Properties;
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
@@ -46,7 +47,10 @@
 
         System.setProperty("java.naming.factory.initial", CONTEXT_FACTORY);
 
-        conf = new PotentialErrorJNDIConfiguration();
+        Properties props = new Properties();
+        props.put("java.naming.factory.initial", CONTEXT_FACTORY);
+        Context ctx = new InitialContext(props);
+        conf = new PotentialErrorJNDIConfiguration(ctx);
 
         nonStringTestHolder = new NonStringTestHolder();
         nonStringTestHolder.setConfiguration(conf);
@@ -278,16 +282,11 @@
      * throw an exception when accessing the base context. Used for testing the
      * exception handling.
      */
-    static class PotentialErrorJNDIConfiguration extends JNDIConfiguration
+    public static class PotentialErrorJNDIConfiguration extends JNDIConfiguration
     {
         /** A flag whether an exception should be thrown. */
         boolean failOnGetCtx;
 
-        public PotentialErrorJNDIConfiguration() throws NamingException
-        {
-            super();
-        }
-
         public PotentialErrorJNDIConfiguration(Context ctx) throws NamingException
         {
             super(ctx);

Added: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java?rev=757474&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java (added)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestVFSConfigurationBuilder.java Mon Mar 23 18:05:25 2009
@@ -0,0 +1,898 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.configuration.beanutils.BeanHelper;
+import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
+import org.apache.commons.configuration.tree.DefaultConfigurationNode;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+
+/**
+ * Test class for DefaultConfigurationBuilder.
+ *
+ * @author Oliver Heger
+ * @version $Id: TestDefaultConfigurationBuilder.java 737642 2009-01-26 07:27:11Z rgoers $
+ */
+public class TestVFSConfigurationBuilder extends TestCase
+{
+    /** Test configuration definition file. */
+    private static final File TEST_FILE = new File(
+            "conf/testDigesterConfiguration.xml");
+
+    private static final File ADDITIONAL_FILE = new File(
+            "conf/testDigesterConfiguration2.xml");
+
+    private static final File OPTIONAL_FILE = new File(
+            "conf/testDigesterOptionalConfiguration.xml");
+
+    private static final File OPTIONALEX_FILE = new File(
+            "conf/testDigesterOptionalConfigurationEx.xml");
+
+    private static final File MULTI_FILE = new File(
+            "conf/testDigesterConfiguration3.xml");
+
+    private static final File INIT_FILE = new File(
+            "conf/testComplexInitialization.xml");
+
+    private static final File CLASS_FILE = new File(
+            "conf/testExtendedClass.xml");
+
+    private static final File PROVIDER_FILE = new File(
+            "conf/testConfigurationProvider.xml");
+
+    private static final File EXTENDED_PROVIDER_FILE = new File(
+            "conf/testExtendedXMLConfigurationProvider.xml");
+
+    private static final File GLOBAL_LOOKUP_FILE = new File(
+            "conf/testGlobalLookup.xml");
+
+    private static final File SYSTEM_PROPS_FILE = new File(
+            "conf/testSystemProperties.xml");
+
+    private static final File VALIDATION_FILE = new File(
+            "conf/testValidation.xml");
+
+    private static final File MULTI_TENENT_FILE = new File(
+            "conf/testMultiTenentConfigurationBuilder.xml");
+
+    /** Constant for the name of an optional configuration.*/
+    private static final String OPTIONAL_NAME = "optionalConfig";
+
+    /** Stores the object to be tested. */
+    DefaultConfigurationBuilder factory;
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        System
+                .setProperty("java.naming.factory.initial",
+                        "org.apache.commons.configuration.MockInitialContextFactory");
+        System.setProperty("test_file_xml", "test.xml");
+        System.setProperty("test_file_combine", "testcombine1.xml");
+        FileSystem.setDefaultFileSystem(new VFSFileSystem());
+        factory = new DefaultConfigurationBuilder();
+        factory.clearErrorListeners();  // avoid exception messages
+    }
+
+    protected void tearDown() throws Exception
+    {
+        FileSystem.resetDefaultFileSystem();
+        super.tearDown();
+    }
+
+    /**
+     * Tests the isReservedNode() method of ConfigurationDeclaration.
+     */
+    public void testConfigurationDeclarationIsReserved()
+    {
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory);
+        DefaultConfigurationNode parent = new DefaultConfigurationNode();
+        DefaultConfigurationNode nd = new DefaultConfigurationNode("at");
+        parent.addAttribute(nd);
+        assertTrue("Attribute at not recognized", decl.isReservedNode(nd));
+        nd = new DefaultConfigurationNode("optional");
+        parent.addAttribute(nd);
+        assertTrue("Attribute optional not recognized", decl.isReservedNode(nd));
+        nd = new DefaultConfigurationNode("config-class");
+        parent.addAttribute(nd);
+        assertTrue("Inherited attribute not recognized", decl
+                .isReservedNode(nd));
+        nd = new DefaultConfigurationNode("different");
+        parent.addAttribute(nd);
+        assertFalse("Wrong reserved attribute", decl.isReservedNode(nd));
+        nd = new DefaultConfigurationNode("at");
+        parent.addChild(nd);
+        assertFalse("Node type not evaluated", decl.isReservedNode(nd));
+    }
+
+    /**
+     * Tests if the at attribute is correctly detected as reserved attribute.
+     */
+    public void testConfigurationDeclarationIsReservedAt()
+    {
+        checkOldReservedAttribute("at");
+    }
+
+    /**
+     * Tests if the optional attribute is correctly detected as reserved
+     * attribute.
+     */
+    public void testConfigurationDeclarationIsReservedOptional()
+    {
+        checkOldReservedAttribute("optional");
+    }
+
+    /**
+     * Tests if special reserved attributes are recognized by the
+     * isReservedNode() method. For compatibility reasons the attributes "at"
+     * and "optional" are also treated as reserved attributes, but only if there
+     * are no corresponding attributes with the "config-" prefix.
+     *
+     * @param name the attribute name
+     */
+    private void checkOldReservedAttribute(String name)
+    {
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory);
+        DefaultConfigurationNode parent = new DefaultConfigurationNode();
+        DefaultConfigurationNode nd = new DefaultConfigurationNode("config-"
+                + name);
+        parent.addAttribute(nd);
+        assertTrue("config-" + name + " attribute not recognized", decl
+                .isReservedNode(nd));
+        DefaultConfigurationNode nd2 = new DefaultConfigurationNode(name);
+        parent.addAttribute(nd2);
+        assertFalse(name + " is reserved though config- exists", decl
+                .isReservedNode(nd2));
+        assertTrue("config- attribute not recognized when " + name + " exists",
+                decl.isReservedNode(nd));
+    }
+
+    /**
+     * Tests access to certain reserved attributes of a
+     * ConfigurationDeclaration.
+     */
+    public void testConfigurationDeclarationGetAttributes()
+    {
+        factory.addProperty("xml.fileName", "test.xml");
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory.configurationAt("xml"));
+        assertNull("Found an at attribute", decl.getAt());
+        assertFalse("Found an optional attribute", decl.isOptional());
+        factory.addProperty("xml[@config-at]", "test1");
+        assertEquals("Wrong value of at attribute", "test1", decl.getAt());
+        factory.addProperty("xml[@at]", "test2");
+        assertEquals("Wrong value of config-at attribute", "test1", decl.getAt());
+        factory.clearProperty("xml[@config-at]");
+        assertEquals("Old at attribute not detected", "test2", decl.getAt());
+        factory.addProperty("xml[@config-optional]", "true");
+        assertTrue("Wrong value of optional attribute", decl.isOptional());
+        factory.addProperty("xml[@optional]", "false");
+        assertTrue("Wrong value of config-optional attribute", decl.isOptional());
+        factory.clearProperty("xml[@config-optional]");
+        factory.setProperty("xml[@optional]", Boolean.TRUE);
+        assertTrue("Old optional attribute not detected", decl.isOptional());
+        factory.setProperty("xml[@optional]", "invalid value");
+        try
+        {
+            decl.isOptional();
+            fail("Invalid optional attribute was not detected!");
+        }
+        catch (ConfigurationRuntimeException crex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests adding a new configuration provider.
+     */
+    public void testAddConfigurationProvider()
+    {
+        DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider();
+        assertNull("Provider already registered", factory
+                .providerForTag("test"));
+        factory.addConfigurationProvider("test", provider);
+        assertSame("Provider not registered", provider, factory
+                .providerForTag("test"));
+    }
+
+    /**
+     * Tries to register a null configuration provider. This should cause an
+     * exception.
+     */
+    public void testAddConfigurationProviderNull()
+    {
+        try
+        {
+            factory.addConfigurationProvider("test", null);
+            fail("Could register null provider");
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tries to register a configuration provider for a null tag. This should
+     * cause an exception to be thrown.
+     */
+    public void testAddConfigurationProviderNullTag()
+    {
+        try
+        {
+            factory.addConfigurationProvider(null,
+                    new DefaultConfigurationBuilder.ConfigurationProvider());
+            fail("Could register provider for null tag!");
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests removing configuration providers.
+     */
+    public void testRemoveConfigurationProvider()
+    {
+        assertNull("Removing unknown provider", factory
+                .removeConfigurationProvider("test"));
+        assertNull("Removing provider for null tag", factory
+                .removeConfigurationProvider(null));
+        DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider();
+        factory.addConfigurationProvider("test", provider);
+        assertSame("Failed to remove provider", provider, factory
+                .removeConfigurationProvider("test"));
+        assertNull("Provider still registered", factory.providerForTag("test"));
+    }
+
+    /**
+     * Tests creating a configuration object from a configuration declaration.
+     */
+    public void testConfigurationBeanFactoryCreateBean()
+    {
+        factory.addConfigurationProvider("test",
+                new DefaultConfigurationBuilder.ConfigurationProvider(
+                        PropertiesConfiguration.class));
+        factory.addProperty("test[@throwExceptionOnMissing]", "true");
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory.configurationAt("test"));
+        PropertiesConfiguration conf = (PropertiesConfiguration) BeanHelper
+                .createBean(decl);
+        assertTrue("Property was not initialized", conf
+                .isThrowExceptionOnMissing());
+    }
+
+    /**
+     * Tests creating a configuration object from an unknown tag. This should
+     * cause an exception.
+     */
+    public void testConfigurationBeanFactoryCreateUnknownTag()
+    {
+        factory.addProperty("test[@throwExceptionOnMissing]", "true");
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory.configurationAt("test"));
+        try
+        {
+            BeanHelper.createBean(decl);
+            fail("Could create configuration from unknown tag!");
+        }
+        catch (ConfigurationRuntimeException crex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests loading a simple configuration definition file.
+     */
+    public void testLoadConfiguration() throws ConfigurationException
+    {
+        factory.setFile(TEST_FILE);
+        checkConfiguration();
+    }
+
+    /**
+     * Tests the file constructor.
+     */
+    public void testLoadConfigurationFromFile() throws ConfigurationException
+    {
+        factory = new DefaultConfigurationBuilder(TEST_FILE);
+        checkConfiguration();
+    }
+
+    /**
+     * Tests the file name constructor.
+     */
+    public void testLoadConfigurationFromFileName()
+            throws ConfigurationException
+    {
+        factory = new DefaultConfigurationBuilder(TEST_FILE.getAbsolutePath());
+        checkConfiguration();
+    }
+
+    /**
+     * Tests the URL constructor.
+     */
+    public void testLoadConfigurationFromURL() throws Exception
+    {
+        factory = new DefaultConfigurationBuilder(TEST_FILE.toURL());
+        checkConfiguration();
+    }
+
+    /**
+     * Tests if the configuration was correctly created by the factory.
+     */
+    private void checkConfiguration() throws ConfigurationException
+    {
+        CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory
+                .getConfiguration();
+
+        assertEquals("Number of configurations", 3, compositeConfiguration
+                .getNumberOfConfigurations());
+        assertEquals(PropertiesConfiguration.class, compositeConfiguration
+                .getConfiguration(0).getClass());
+        assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration
+                .getConfiguration(1).getClass());
+        assertEquals(XMLConfiguration.class, compositeConfiguration
+                .getConfiguration(2).getClass());
+
+        // check the first configuration
+        PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration
+                .getConfiguration(0);
+        assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc
+                .getFileName());
+
+        // check some properties
+        checkProperties(compositeConfiguration);
+    }
+
+    /**
+     * Checks if the passed in configuration contains the expected properties.
+     *
+     * @param compositeConfiguration the configuration to check
+     */
+    private void checkProperties(Configuration compositeConfiguration)
+    {
+        assertTrue("Make sure we have loaded our key", compositeConfiguration
+                .getBoolean("test.boolean"));
+        assertEquals("I'm complex!", compositeConfiguration
+                .getProperty("element2.subelement.subsubelement"));
+        assertEquals("property in the XMLPropertiesConfiguration", "value1",
+                compositeConfiguration.getProperty("key1"));
+    }
+
+    /**
+     * Tests loading a configuration definition file with an additional section.
+     */
+    public void testLoadAdditional() throws ConfigurationException
+    {
+        factory.setFile(ADDITIONAL_FILE);
+        CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory
+                .getConfiguration();
+        assertEquals("Verify how many configs", 2, compositeConfiguration
+                .getNumberOfConfigurations());
+
+        // Test if union was constructed correctly
+        Object prop = compositeConfiguration.getProperty("tables.table.name");
+        assertTrue(prop instanceof Collection);
+        assertEquals(3, ((Collection) prop).size());
+        assertEquals("users", compositeConfiguration
+                .getProperty("tables.table(0).name"));
+        assertEquals("documents", compositeConfiguration
+                .getProperty("tables.table(1).name"));
+        assertEquals("tasks", compositeConfiguration
+                .getProperty("tables.table(2).name"));
+
+        prop = compositeConfiguration
+                .getProperty("tables.table.fields.field.name");
+        assertTrue(prop instanceof Collection);
+        assertEquals(17, ((Collection) prop).size());
+
+        assertEquals("smtp.mydomain.org", compositeConfiguration
+                .getString("mail.host.smtp"));
+        assertEquals("pop3.mydomain.org", compositeConfiguration
+                .getString("mail.host.pop"));
+
+        // This was overriden
+        assertEquals("masterOfPost", compositeConfiguration
+                .getString("mail.account.user"));
+        assertEquals("topsecret", compositeConfiguration
+                .getString("mail.account.psswd"));
+
+        // This was overriden, too, but not in additional section
+        assertEquals("enhanced factory", compositeConfiguration
+                .getString("test.configuration"));
+    }
+
+    /**
+     * Tests whether a default log error listener is registered at the builder
+     * instance.
+     */
+    public void testLogErrorListener()
+    {
+        assertEquals("No default error listener registered", 1,
+                new DefaultConfigurationBuilder().getErrorListeners().size());
+    }
+
+    /**
+     * Tests loading a definition file that contains optional configurations.
+     */
+    public void testLoadOptional() throws Exception
+    {
+        factory.setURL(OPTIONAL_FILE.toURL());
+        Configuration config = factory.getConfiguration();
+        assertTrue(config.getBoolean("test.boolean"));
+        assertEquals("value", config.getProperty("element"));
+    }
+
+    /**
+     * Tests whether loading a failing optional configuration causes an error
+     * event.
+     */
+    public void testLoadOptionalErrorEvent() throws Exception
+    {
+        factory.clearErrorListeners();
+        ConfigurationErrorListenerImpl listener = new ConfigurationErrorListenerImpl();
+        factory.addErrorListener(listener);
+        prepareOptionalTest("configuration", false);
+        listener.verify(DefaultConfigurationBuilder.EVENT_ERR_LOAD_OPTIONAL,
+                OPTIONAL_NAME, null);
+    }
+
+    /**
+     * Tests loading a definition file with optional and non optional
+     * configuration sources. One non optional does not exist, so this should
+     * cause an exception.
+     */
+    public void testLoadOptionalWithException()
+    {
+        factory.setFile(OPTIONALEX_FILE);
+        try
+        {
+            factory.getConfiguration();
+            fail("Non existing source did not cause an exception!");
+        }
+        catch (ConfigurationException cex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tries to load a configuration file with an optional, non file-based
+     * configuration. The optional attribute should work for other configuration
+     * classes, too.
+     */
+    public void testLoadOptionalNonFileBased() throws ConfigurationException
+    {
+        CombinedConfiguration config = prepareOptionalTest("configuration", false);
+        assertTrue("Configuration not empty", config.isEmpty());
+        assertEquals("Wrong number of configurations", 0, config
+                .getNumberOfConfigurations());
+    }
+
+    /**
+     * Tests an optional, non existing configuration with the forceCreate
+     * attribute. This configuration should be added to the resulting
+     * configuration.
+     */
+    public void testLoadOptionalForceCreate() throws ConfigurationException
+    {
+        factory.setBasePath(TEST_FILE.getParent());
+        CombinedConfiguration config = prepareOptionalTest("xml", true);
+        assertEquals("Wrong number of configurations", 1, config
+                .getNumberOfConfigurations());
+        FileConfiguration fc = (FileConfiguration) config
+                .getConfiguration(OPTIONAL_NAME);
+        assertNotNull("Optional config not found", fc);
+        assertEquals("File name was not set", "nonExisting.xml", fc
+                .getFileName());
+        assertNotNull("Base path was not set", fc.getBasePath());
+    }
+
+    /**
+     * Tests loading an embedded optional configuration builder with the force
+     * create attribute.
+     */
+    public void testLoadOptionalBuilderForceCreate()
+            throws ConfigurationException
+    {
+        CombinedConfiguration config = prepareOptionalTest("configuration",
+                true);
+        assertEquals("Wrong number of configurations", 1, config
+                .getNumberOfConfigurations());
+        assertTrue(
+                "Wrong optional configuration type",
+                config.getConfiguration(OPTIONAL_NAME) instanceof CombinedConfiguration);
+    }
+
+    /**
+     * Tests loading an optional configuration with the force create attribute
+     * set. The provider will always throw an exception. In this case the
+     * configuration will not be added to the resulting combined configuration.
+     */
+    public void testLoadOptionalForceCreateWithException()
+            throws ConfigurationException
+    {
+        factory.addConfigurationProvider("test",
+                new DefaultConfigurationBuilder.ConfigurationBuilderProvider()
+                {
+                    // Throw an exception here, too
+                    public AbstractConfiguration getEmptyConfiguration(
+                            DefaultConfigurationBuilder.ConfigurationDeclaration decl) throws Exception
+                    {
+                        throw new Exception("Unable to create configuration!");
+                    }
+                });
+        CombinedConfiguration config = prepareOptionalTest("test", true);
+        assertEquals("Optional configuration could be created", 0, config
+                .getNumberOfConfigurations());
+    }
+
+    /**
+     * Prepares a test for loading a configuration definition file with an
+     * optional configuration declaration.
+     *
+     * @param tag the tag name with the optional configuration
+     * @param force the forceCreate attribute
+     * @return the combined configuration obtained from the builder
+     * @throws org.apache.commons.configuration.ConfigurationException if an error occurs
+     */
+    private CombinedConfiguration prepareOptionalTest(String tag, boolean force)
+            throws ConfigurationException
+    {
+        String prefix = "override." + tag;
+        factory.addProperty(prefix + "[@fileName]", "nonExisting.xml");
+        factory.addProperty(prefix + "[@config-optional]", Boolean.TRUE);
+        factory.addProperty(prefix + "[@config-name]", OPTIONAL_NAME);
+        if (force)
+        {
+            factory.addProperty(prefix + "[@config-forceCreate]", Boolean.TRUE);
+        }
+        return factory.getConfiguration(false);
+    }
+
+    /**
+     * Tests loading a definition file with multiple different sources.
+     */
+    public void testLoadDifferentSources() throws ConfigurationException
+    {
+        factory.setFile(MULTI_FILE);
+        Configuration config = factory.getConfiguration();
+        assertFalse(config.isEmpty());
+        assertTrue(config instanceof CombinedConfiguration);
+        CombinedConfiguration cc = (CombinedConfiguration) config;
+        assertEquals("Wrong number of configurations", 1, cc
+                .getNumberOfConfigurations());
+
+        assertNotNull(config
+                .getProperty("tables.table(0).fields.field(2).name"));
+        assertNotNull(config.getProperty("element2.subelement.subsubelement"));
+        assertEquals("value", config.getProperty("element3"));
+        assertEquals("foo", config.getProperty("element3[@name]"));
+        assertNotNull(config.getProperty("mail.account.user"));
+
+        // test JNDIConfiguration
+        assertNotNull(config.getProperty("test.onlyinjndi"));
+        assertTrue(config.getBoolean("test.onlyinjndi"));
+
+        Configuration subset = config.subset("test");
+        assertNotNull(subset.getProperty("onlyinjndi"));
+        assertTrue(subset.getBoolean("onlyinjndi"));
+
+        // test SystemConfiguration
+        assertNotNull(config.getProperty("java.version"));
+        assertEquals(System.getProperty("java.version"), config
+                .getString("java.version"));
+    }
+
+    /**
+     * Tests if the base path is correctly evaluated.
+     */
+    public void testSetConfigurationBasePath() throws ConfigurationException
+    {
+        factory.addProperty("properties[@fileName]", "test.properties");
+        File deepDir = new File("conf/config/deep");
+        factory.setConfigurationBasePath(deepDir.getAbsolutePath());
+
+        Configuration config = factory.getConfiguration(false);
+        assertEquals("Wrong property value", "somevalue", config
+                .getString("somekey"));
+    }
+
+    /**
+     * Tests reading a configuration definition file that contains complex
+     * initialization of properties of the declared configuration sources.
+     */
+    public void testComplexInitialization() throws ConfigurationException
+    {
+        factory.setFile(INIT_FILE);
+        CombinedConfiguration cc = (CombinedConfiguration) factory
+                .getConfiguration();
+
+        assertEquals("System property not found", "test.xml",
+                cc.getString("test_file_xml"));
+        PropertiesConfiguration c1 = (PropertiesConfiguration) cc
+                .getConfiguration(1);
+        assertTrue(
+                "Reloading strategy was not set",
+                c1.getReloadingStrategy() instanceof FileChangedReloadingStrategy);
+        assertEquals("Refresh delay was not set", 10000,
+                ((FileChangedReloadingStrategy) c1.getReloadingStrategy())
+                        .getRefreshDelay());
+
+        Configuration xmlConf = cc.getConfiguration("xml");
+        assertEquals("Property not found", "I'm complex!", xmlConf
+                .getString("element2/subelement/subsubelement"));
+        assertEquals("List index not found", "two", xmlConf
+                .getString("list[0]/item[1]"));
+        assertEquals("Property in combiner file not found", "yellow", cc
+                .getString("/gui/selcolor"));
+
+        assertTrue("Delimiter flag was not set", cc
+                .isDelimiterParsingDisabled());
+        assertTrue("Expression engine was not set",
+                cc.getExpressionEngine() instanceof XPathExpressionEngine);
+    }
+
+    /**
+     * Tests if the returned combined configuration has the expected structure.
+     */
+    public void testCombinedConfiguration() throws ConfigurationException
+    {
+        factory.setFile(INIT_FILE);
+        CombinedConfiguration cc = (CombinedConfiguration) factory
+                .getConfiguration();
+        assertNotNull("Properties configuration not found", cc
+                .getConfiguration("properties"));
+        assertNotNull("XML configuration not found", cc.getConfiguration("xml"));
+        assertEquals("Wrong number of contained configs", 4, cc
+                .getNumberOfConfigurations());
+
+        CombinedConfiguration cc2 = (CombinedConfiguration) cc
+                .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);
+        assertNotNull("No additional configuration found", cc2);
+        Set names = cc2.getConfigurationNames();
+        assertEquals("Wrong number of contained additional configs", 2, names
+                .size());
+        assertTrue("Config 1 not contained", names.contains("combiner1"));
+        assertTrue("Config 2 not contained", names.contains("combiner2"));
+    }
+
+    /**
+     * Tests the structure of the returned combined configuration if there is no
+     * additional section.
+     */
+    public void testCombinedConfigurationNoAdditional()
+            throws ConfigurationException
+    {
+        factory.setFile(TEST_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        assertNull("Additional configuration was found", cc
+                .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME));
+    }
+
+    /**
+     * Tests whether the list node definition was correctly processed.
+     */
+    public void testCombinedConfigurationListNodes()
+            throws ConfigurationException
+    {
+        factory.setFile(INIT_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        Set listNodes = cc.getNodeCombiner().getListNodes();
+        assertEquals("Wrong number of list nodes", 2, listNodes.size());
+        assertTrue("table node not a list node", listNodes.contains("table"));
+        assertTrue("list node not a list node", listNodes.contains("list"));
+
+        CombinedConfiguration cca = (CombinedConfiguration) cc
+                .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);
+        listNodes = cca.getNodeCombiner().getListNodes();
+        assertTrue("Found list nodes for additional combiner", listNodes
+                .isEmpty());
+    }
+
+    /**
+     * Tests whether a configuration builder can itself be declared in a
+     * configuration definition file.
+     */
+    public void testConfigurationBuilderProvider()
+            throws ConfigurationException
+    {
+        factory.addProperty("override.configuration[@fileName]", TEST_FILE
+                .getAbsolutePath());
+        CombinedConfiguration cc = factory.getConfiguration(false);
+        assertEquals("Wrong number of configurations", 1, cc
+                .getNumberOfConfigurations());
+        checkProperties(cc);
+    }
+
+    /**
+     * Tests whether XML settings can be inherited.
+     */
+    public void testLoadXMLWithSettings() throws ConfigurationException,
+            IOException
+    {
+        File confDir = new File("conf");
+        File targetDir = new File("target");
+        File testXMLSource = new File(confDir, "testDtd.xml");
+        File testXMLValidationSource = new File(confDir,
+                "testValidateInvalid.xml");
+        File testSavedXML = new File(targetDir, "testSave.xml");
+        File testSavedFactory = new File(targetDir, "testSaveFactory.xml");
+        File dtdFile = new File(confDir, "properties.dtd");
+        final String publicId = "http://commons.apache.org/test.dtd";
+
+        XMLConfiguration config = new XMLConfiguration(testXMLSource);
+        config.setPublicID(publicId);
+        config.save(testSavedXML);
+        factory.addProperty("xml[@fileName]", testSavedXML.getAbsolutePath());
+        factory.addProperty("xml(0)[@validating]", "true");
+        factory.addProperty("xml(-1)[@fileName]", testXMLValidationSource
+                .getAbsolutePath());
+        factory.addProperty("xml(1)[@config-optional]", "true");
+        factory.addProperty("xml(1)[@validating]", "true");
+        factory.save(testSavedFactory);
+
+        factory = new DefaultConfigurationBuilder();
+        factory.setFile(testSavedFactory);
+        factory.registerEntityId(publicId, dtdFile.toURL());
+        factory.clearErrorListeners();
+        Configuration c = factory.getConfiguration();
+        assertEquals("Wrong property value", "value1", c.getString("entry(0)"));
+        assertFalse("Invalid XML source was loaded", c
+                .containsKey("table.name"));
+
+        testSavedXML.delete();
+        testSavedFactory.delete();
+    }
+
+    /**
+     * Tests loading a configuration definition file that defines a custom
+     * result class.
+     */
+    public void testExtendedClass() throws ConfigurationException
+    {
+        factory.setFile(CLASS_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String prop = (String)cc.getProperty("test");
+        assertEquals("Expected 'Extended', actual '" + prop + "'", "Extended", prop);
+        assertTrue("Wrong result class: " + cc.getClass(),
+                cc instanceof TestDefaultConfigurationBuilder.ExtendedCombinedConfiguration);
+    }
+
+    /**
+     * Tests loading a configuration definition file that defines new providers.
+     */
+    public void testConfigurationProvider() throws ConfigurationException
+    {
+        factory.setFile(PROVIDER_FILE);
+        factory.getConfiguration(true);
+        DefaultConfigurationBuilder.ConfigurationProvider provider = factory
+                .providerForTag("test");
+        assertNotNull("Provider 'test' not registered", provider);
+    }
+
+        /**
+     * Tests loading a configuration definition file that defines new providers.
+     */
+    public void testExtendedXMLConfigurationProvider() throws ConfigurationException
+    {
+        factory.setFile(EXTENDED_PROVIDER_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        DefaultConfigurationBuilder.ConfigurationProvider provider = factory
+                .providerForTag("test");
+        assertNotNull("Provider 'test' not registered", provider);
+        Configuration config = cc.getConfiguration("xml");
+        assertNotNull("Test configuration not present", config);
+        assertTrue("Configuration is not ExtendedXMLConfiguration, is " +
+                config.getClass().getName(), 
+                config instanceof TestDefaultConfigurationBuilder.ExtendedXMLConfiguration);
+    }
+
+    public void testGlobalLookup() throws Exception
+    {
+        factory.setFile(GLOBAL_LOOKUP_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String value = cc.getInterpolator().lookup("test:test_key");
+        assertNotNull("The test key was not located", value);
+        assertEquals("Incorrect value retrieved","test.value",value);
+    }
+
+    public void testSystemProperties() throws Exception
+    {
+        factory.setFile(SYSTEM_PROPS_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String value = System.getProperty("key1");
+        assertNotNull("The test key was not located", value);
+        assertEquals("Incorrect value retrieved","value1",value);
+    }
+
+
+    public void testValidation() throws Exception
+    {
+        factory.setFile(VALIDATION_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String value = System.getProperty("key1");
+        assertNotNull("The test key was not located", value);
+        assertEquals("Incorrect value retrieved","value1",value);
+    }
+
+    public void testMultiTenentConfiguration() throws Exception
+    {
+        factory.setFile(MULTI_TENENT_FILE);
+        System.clearProperty("Id");
+
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration);
+
+        verify("1001", config, 15);
+        verify("1002", config, 25);
+        verify("1003", config, 35);
+        verify("1004", config, 50);
+        verify("1005", config, 50);
+    }
+
+    public void testMultiTenentConfiguration2() throws Exception
+    {
+        factory.setFile(MULTI_TENENT_FILE);
+        System.setProperty("Id", "1004");
+
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration);
+
+        verify("1001", config, 15);
+        verify("1002", config, 25);
+        verify("1003", config, 35);
+        verify("1004", config, 50);
+        verify("1005", config, 50);
+    }
+
+    public void testMultiTenentConfiguration3() throws Exception
+    {
+        factory.setFile(MULTI_TENENT_FILE);
+        System.setProperty("Id", "1005");
+
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration);
+
+        verify("1001", config, 15);
+        verify("1002", config, 25);
+        verify("1003", config, 35);
+        verify("1004", config, 50);
+        verify("1005", config, 50);
+    }
+
+    private void verify(String key, CombinedConfiguration config, int rows)
+    {
+        System.setProperty("Id", key);
+        int actual = config.getInt("rowsPerPage");
+        assertTrue("expected: " + rows + " actual: " + actual, actual == rows);
+    }
+
+}
\ No newline at end of file

Added: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java?rev=757474&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java (added)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestWebdavConfigurationBuilder.java Mon Mar 23 18:05:25 2009
@@ -0,0 +1,901 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.configuration.beanutils.BeanHelper;
+import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
+import org.apache.commons.configuration.tree.DefaultConfigurationNode;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+import org.apache.commons.lang.text.StrLookup;
+
+/**
+ * Test class for DefaultConfigurationBuilder.
+ *
+ * @author Oliver Heger
+ * @version $Id: TestDefaultConfigurationBuilder.java 737642 2009-01-26 07:27:11Z rgoers $
+ */
+public class TestWebdavConfigurationBuilder extends TestCase implements FileOptionsProvider
+{
+    /** Test configuration definition file. */
+    private static final String TEST_FILE =
+            "testDigesterConfiguration.xml";
+
+    private static final String ADDITIONAL_FILE =
+            "testDigesterConfiguration2.xml";
+
+    private static final String OPTIONAL_FILE =
+            "testDigesterOptionalConfiguration.xml";
+
+    private static final String OPTIONALEX_FILE =
+            "testDigesterOptionalConfigurationEx.xml";
+
+    private static final String MULTI_FILE =
+            "testDigesterConfiguration3.xml";
+
+    private static final String INIT_FILE =
+            "testComplexInitialization.xml";
+
+    private static final String CLASS_FILE =
+            "testExtendedClass.xml";
+
+    private static final String PROVIDER_FILE =
+            "testConfigurationProvider.xml";
+
+    private static final String EXTENDED_PROVIDER_FILE =
+            "testExtendedXMLConfigurationProvider.xml";
+
+    private static final String GLOBAL_LOOKUP_FILE =
+            "testGlobalLookup.xml";
+
+    private static final String SYSTEM_PROPS_FILE =
+            "testSystemProperties.xml";
+
+    private static final String VALIDATION_FILE =
+            "testValidation.xml";
+
+    private static final String MULTI_TENENT_FILE =
+            "testMultiTenentConfigurationBuilder.xml";
+
+    private static final String TEST_PROPERTIES = "test.properties.xml";
+
+    private static final String TEST_SAVE = "testsave.xml";
+
+    /** Constant for the name of an optional configuration.*/
+    private static final String OPTIONAL_NAME = "optionalConfig";
+
+    private Map options;
+
+
+    /** Stores the object to be tested. */
+    DefaultConfigurationBuilder factory;
+
+    private String getBasePath()
+    {
+        String path = System.getProperty("test.webdav.base");
+        assertNotNull("No base url provided", path);
+        return path;
+    }
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        System.setProperty("java.naming.factory.initial",
+                        "org.apache.commons.configuration.MockInitialContextFactory");
+        System.setProperty("test_file_xml", "test.xml");
+        System.setProperty("test_file_combine", "testcombine1.xml");
+        FileSystem fs = new VFSFileSystem();
+        fs.setFileOptionsProvider(this);
+        FileSystem.setDefaultFileSystem(fs);
+        factory = new DefaultConfigurationBuilder();
+        factory.setBasePath(getBasePath());
+        factory.clearErrorListeners();  // avoid exception messages
+    }
+
+    protected void tearDown() throws Exception
+    {
+        FileSystem.resetDefaultFileSystem();
+        super.tearDown();
+    }
+
+    /**
+     * Tests the isReservedNode() method of ConfigurationDeclaration.
+     */
+    public void testConfigurationDeclarationIsReserved()
+    {
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory);
+        DefaultConfigurationNode parent = new DefaultConfigurationNode();
+        DefaultConfigurationNode nd = new DefaultConfigurationNode("at");
+        parent.addAttribute(nd);
+        assertTrue("Attribute at not recognized", decl.isReservedNode(nd));
+        nd = new DefaultConfigurationNode("optional");
+        parent.addAttribute(nd);
+        assertTrue("Attribute optional not recognized", decl.isReservedNode(nd));
+        nd = new DefaultConfigurationNode("config-class");
+        parent.addAttribute(nd);
+        assertTrue("Inherited attribute not recognized", decl
+                .isReservedNode(nd));
+        nd = new DefaultConfigurationNode("different");
+        parent.addAttribute(nd);
+        assertFalse("Wrong reserved attribute", decl.isReservedNode(nd));
+        nd = new DefaultConfigurationNode("at");
+        parent.addChild(nd);
+        assertFalse("Node type not evaluated", decl.isReservedNode(nd));
+    }
+
+    /**
+     * Tests if the at attribute is correctly detected as reserved attribute.
+     */
+    public void testConfigurationDeclarationIsReservedAt()
+    {
+        checkOldReservedAttribute("at");
+    }
+
+    /**
+     * Tests if the optional attribute is correctly detected as reserved
+     * attribute.
+     */
+    public void testConfigurationDeclarationIsReservedOptional()
+    {
+        checkOldReservedAttribute("optional");
+    }
+
+    /**
+     * Tests if special reserved attributes are recognized by the
+     * isReservedNode() method. For compatibility reasons the attributes "at"
+     * and "optional" are also treated as reserved attributes, but only if there
+     * are no corresponding attributes with the "config-" prefix.
+     *
+     * @param name the attribute name
+     */
+    private void checkOldReservedAttribute(String name)
+    {
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory);
+        DefaultConfigurationNode parent = new DefaultConfigurationNode();
+        DefaultConfigurationNode nd = new DefaultConfigurationNode("config-"
+                + name);
+        parent.addAttribute(nd);
+        assertTrue("config-" + name + " attribute not recognized", decl
+                .isReservedNode(nd));
+        DefaultConfigurationNode nd2 = new DefaultConfigurationNode(name);
+        parent.addAttribute(nd2);
+        assertFalse(name + " is reserved though config- exists", decl
+                .isReservedNode(nd2));
+        assertTrue("config- attribute not recognized when " + name + " exists",
+                decl.isReservedNode(nd));
+    }
+
+    /**
+     * Tests access to certain reserved attributes of a
+     * ConfigurationDeclaration.
+     */
+    public void testConfigurationDeclarationGetAttributes()
+    {
+        factory.addProperty("xml.fileName", "test.xml");
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory.configurationAt("xml"));
+        assertNull("Found an at attribute", decl.getAt());
+        assertFalse("Found an optional attribute", decl.isOptional());
+        factory.addProperty("xml[@config-at]", "test1");
+        assertEquals("Wrong value of at attribute", "test1", decl.getAt());
+        factory.addProperty("xml[@at]", "test2");
+        assertEquals("Wrong value of config-at attribute", "test1", decl.getAt());
+        factory.clearProperty("xml[@config-at]");
+        assertEquals("Old at attribute not detected", "test2", decl.getAt());
+        factory.addProperty("xml[@config-optional]", "true");
+        assertTrue("Wrong value of optional attribute", decl.isOptional());
+        factory.addProperty("xml[@optional]", "false");
+        assertTrue("Wrong value of config-optional attribute", decl.isOptional());
+        factory.clearProperty("xml[@config-optional]");
+        factory.setProperty("xml[@optional]", Boolean.TRUE);
+        assertTrue("Old optional attribute not detected", decl.isOptional());
+        factory.setProperty("xml[@optional]", "invalid value");
+        try
+        {
+            decl.isOptional();
+            fail("Invalid optional attribute was not detected!");
+        }
+        catch (ConfigurationRuntimeException crex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests adding a new configuration provider.
+     */
+    public void testAddConfigurationProvider()
+    {
+        DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider();
+        assertNull("Provider already registered", factory
+                .providerForTag("test"));
+        factory.addConfigurationProvider("test", provider);
+        assertSame("Provider not registered", provider, factory
+                .providerForTag("test"));
+    }
+
+    /**
+     * Tries to register a null configuration provider. This should cause an
+     * exception.
+     */
+    public void testAddConfigurationProviderNull()
+    {
+        try
+        {
+            factory.addConfigurationProvider("test", null);
+            fail("Could register null provider");
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tries to register a configuration provider for a null tag. This should
+     * cause an exception to be thrown.
+     */
+    public void testAddConfigurationProviderNullTag()
+    {
+        try
+        {
+            factory.addConfigurationProvider(null,
+                    new DefaultConfigurationBuilder.ConfigurationProvider());
+            fail("Could register provider for null tag!");
+        }
+        catch (IllegalArgumentException iex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests removing configuration providers.
+     */
+    public void testRemoveConfigurationProvider()
+    {
+        assertNull("Removing unknown provider", factory
+                .removeConfigurationProvider("test"));
+        assertNull("Removing provider for null tag", factory
+                .removeConfigurationProvider(null));
+        DefaultConfigurationBuilder.ConfigurationProvider provider = new DefaultConfigurationBuilder.ConfigurationProvider();
+        factory.addConfigurationProvider("test", provider);
+        assertSame("Failed to remove provider", provider, factory
+                .removeConfigurationProvider("test"));
+        assertNull("Provider still registered", factory.providerForTag("test"));
+    }
+
+    /**
+     * Tests creating a configuration object from a configuration declaration.
+     */
+    public void testConfigurationBeanFactoryCreateBean()
+    {
+        factory.addConfigurationProvider("test",
+                new DefaultConfigurationBuilder.ConfigurationProvider(
+                        PropertiesConfiguration.class));
+        factory.addProperty("test[@throwExceptionOnMissing]", "true");
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory.configurationAt("test"));
+        PropertiesConfiguration conf = (PropertiesConfiguration) BeanHelper
+                .createBean(decl);
+        assertTrue("Property was not initialized", conf
+                .isThrowExceptionOnMissing());
+    }
+
+    /**
+     * Tests creating a configuration object from an unknown tag. This should
+     * cause an exception.
+     */
+    public void testConfigurationBeanFactoryCreateUnknownTag()
+    {
+        factory.addProperty("test[@throwExceptionOnMissing]", "true");
+        DefaultConfigurationBuilder.ConfigurationDeclaration decl = new DefaultConfigurationBuilder.ConfigurationDeclaration(
+                factory, factory.configurationAt("test"));
+        try
+        {
+            BeanHelper.createBean(decl);
+            fail("Could create configuration from unknown tag!");
+        }
+        catch (ConfigurationRuntimeException crex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tests loading a simple configuration definition file.
+     */
+    public void testLoadConfiguration() throws ConfigurationException
+    {
+        factory.setFileName(TEST_FILE);
+        checkConfiguration();
+    }
+
+    /**
+     * Tests the file constructor.
+     */
+    public void testLoadConfigurationFromFile() throws ConfigurationException
+    {
+        factory = new DefaultConfigurationBuilder(getBasePath() + TEST_FILE);
+        checkConfiguration();
+    }
+
+    /**
+     * This test doesn't test DefaultConfigurationBuilder. It tests saving a file
+     * using Webdav file options.
+     */
+    public void testSaveConfiguration() throws ConfigurationException
+    {
+        options = new HashMap();
+        options.put(FileOptionsProvider.VERSIONING, Boolean.TRUE);
+        options.put(FileOptionsProvider.CURRENT_USER, "TestUser");
+        XMLConfiguration conf = new XMLConfiguration();
+        conf.setFileName(getBasePath() + TEST_PROPERTIES);
+        conf.load();
+        conf.save(getBasePath() + TEST_SAVE);
+        XMLConfiguration checkConfig = new XMLConfiguration();
+        checkConfig.setFileName(getBasePath() + TEST_SAVE);
+        checkSavedConfig(conf, checkConfig);
+        options = null;
+    }
+
+    /**
+     * Tests if the configuration was correctly created by the factory.
+     */
+    private void checkConfiguration() throws ConfigurationException
+    {
+        CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory
+                .getConfiguration();
+
+        assertEquals("Number of configurations", 3, compositeConfiguration
+                .getNumberOfConfigurations());
+        assertEquals(PropertiesConfiguration.class, compositeConfiguration
+                .getConfiguration(0).getClass());
+        assertEquals(XMLPropertiesConfiguration.class, compositeConfiguration
+                .getConfiguration(1).getClass());
+        assertEquals(XMLConfiguration.class, compositeConfiguration
+                .getConfiguration(2).getClass());
+
+        // check the first configuration
+        PropertiesConfiguration pc = (PropertiesConfiguration) compositeConfiguration
+                .getConfiguration(0);
+        assertNotNull("Make sure we have a fileName: " + pc.getFileName(), pc
+                .getFileName());
+
+        // check some properties
+        checkProperties(compositeConfiguration);
+    }
+
+    /**
+     * Checks if the passed in configuration contains the expected properties.
+     *
+     * @param compositeConfiguration the configuration to check
+     */
+    private void checkProperties(Configuration compositeConfiguration)
+    {
+        assertTrue("Make sure we have loaded our key", compositeConfiguration
+                .getBoolean("test.boolean"));
+        assertEquals("I'm complex!", compositeConfiguration
+                .getProperty("element2.subelement.subsubelement"));
+        assertEquals("property in the XMLPropertiesConfiguration", "value1",
+                compositeConfiguration.getProperty("key1"));
+    }
+
+    /**
+     * Tests loading a configuration definition file with an additional section.
+     */
+    public void testLoadAdditional() throws ConfigurationException
+    {
+        factory.setFileName(ADDITIONAL_FILE);
+        CombinedConfiguration compositeConfiguration = (CombinedConfiguration) factory
+                .getConfiguration();
+        assertEquals("Verify how many configs", 2, compositeConfiguration
+                .getNumberOfConfigurations());
+
+        // Test if union was constructed correctly
+        Object prop = compositeConfiguration.getProperty("tables.table.name");
+        assertTrue(prop instanceof Collection);
+        assertEquals(3, ((Collection) prop).size());
+        assertEquals("users", compositeConfiguration
+                .getProperty("tables.table(0).name"));
+        assertEquals("documents", compositeConfiguration
+                .getProperty("tables.table(1).name"));
+        assertEquals("tasks", compositeConfiguration
+                .getProperty("tables.table(2).name"));
+
+        prop = compositeConfiguration
+                .getProperty("tables.table.fields.field.name");
+        assertTrue(prop instanceof Collection);
+        assertEquals(17, ((Collection) prop).size());
+
+        assertEquals("smtp.mydomain.org", compositeConfiguration
+                .getString("mail.host.smtp"));
+        assertEquals("pop3.mydomain.org", compositeConfiguration
+                .getString("mail.host.pop"));
+
+        // This was overriden
+        assertEquals("masterOfPost", compositeConfiguration
+                .getString("mail.account.user"));
+        assertEquals("topsecret", compositeConfiguration
+                .getString("mail.account.psswd"));
+
+        // This was overriden, too, but not in additional section
+        assertEquals("enhanced factory", compositeConfiguration
+                .getString("test.configuration"));
+    }
+
+    /**
+     * Tests whether a default log error listener is registered at the builder
+     * instance.
+     */
+    public void testLogErrorListener()
+    {
+        assertEquals("No default error listener registered", 1,
+                new DefaultConfigurationBuilder().getErrorListeners().size());
+    }
+
+    /**
+     * Tests loading a definition file that contains optional configurations.
+     */
+    public void testLoadOptional() throws Exception
+    {
+        factory.setFileName(OPTIONAL_FILE);
+        Configuration config = factory.getConfiguration();
+        assertTrue(config.getBoolean("test.boolean"));
+        assertEquals("value", config.getProperty("element"));
+    }
+
+    /**
+     * Tests whether loading a failing optional configuration causes an error
+     * event.
+     */
+    public void testLoadOptionalErrorEvent() throws Exception
+    {
+        factory.clearErrorListeners();
+        ConfigurationErrorListenerImpl listener = new ConfigurationErrorListenerImpl();
+        factory.addErrorListener(listener);
+        prepareOptionalTest("configuration", false);
+        listener.verify(DefaultConfigurationBuilder.EVENT_ERR_LOAD_OPTIONAL,
+                OPTIONAL_NAME, null);
+    }
+
+    /**
+     * Tests loading a definition file with optional and non optional
+     * configuration sources. One non optional does not exist, so this should
+     * cause an exception.
+     */
+    public void testLoadOptionalWithException()
+    {
+        factory.setFileName(OPTIONALEX_FILE);
+        try
+        {
+            factory.getConfiguration();
+            fail("Non existing source did not cause an exception!");
+        }
+        catch (ConfigurationException cex)
+        {
+            // ok
+        }
+    }
+
+    /**
+     * Tries to load a configuration file with an optional, non file-based
+     * configuration. The optional attribute should work for other configuration
+     * classes, too.
+     */
+    public void testLoadOptionalNonFileBased() throws ConfigurationException
+    {
+        CombinedConfiguration config = prepareOptionalTest("configuration", false);
+        assertTrue("Configuration not empty", config.isEmpty());
+        assertEquals("Wrong number of configurations", 0, config
+                .getNumberOfConfigurations());
+    }
+
+    /**
+     * Tests loading an embedded optional configuration builder with the force
+     * create attribute.
+     */
+    public void testLoadOptionalBuilderForceCreate()
+            throws ConfigurationException
+    {
+        CombinedConfiguration config = prepareOptionalTest("configuration",
+                true);
+        assertEquals("Wrong number of configurations", 1, config
+                .getNumberOfConfigurations());
+        assertTrue(
+                "Wrong optional configuration type",
+                config.getConfiguration(OPTIONAL_NAME) instanceof CombinedConfiguration);
+    }
+
+    /**
+     * Tests loading an optional configuration with the force create attribute
+     * set. The provider will always throw an exception. In this case the
+     * configuration will not be added to the resulting combined configuration.
+     */
+    public void testLoadOptionalForceCreateWithException()
+            throws ConfigurationException
+    {
+        factory.addConfigurationProvider("test",
+                new DefaultConfigurationBuilder.ConfigurationBuilderProvider()
+                {
+                    // Throw an exception here, too
+                    public AbstractConfiguration getEmptyConfiguration(
+                            DefaultConfigurationBuilder.ConfigurationDeclaration decl) throws Exception
+                    {
+                        throw new Exception("Unable to create configuration!");
+                    }
+                });
+        CombinedConfiguration config = prepareOptionalTest("test", true);
+        assertEquals("Optional configuration could be created", 0, config
+                .getNumberOfConfigurations());
+    }
+
+    /**
+     * Prepares a test for loading a configuration definition file with an
+     * optional configuration declaration.
+     *
+     * @param tag the tag name with the optional configuration
+     * @param force the forceCreate attribute
+     * @return the combined configuration obtained from the builder
+     * @throws ConfigurationException if an error occurs
+     */
+    private CombinedConfiguration prepareOptionalTest(String tag, boolean force)
+            throws ConfigurationException
+    {
+        String prefix = "override." + tag;
+        factory.addProperty(prefix + "[@fileName]", "nonExisting.xml");
+        factory.addProperty(prefix + "[@config-optional]", Boolean.TRUE);
+        factory.addProperty(prefix + "[@config-name]", OPTIONAL_NAME);
+        if (force)
+        {
+            factory.addProperty(prefix + "[@config-forceCreate]", Boolean.TRUE);
+        }
+        return factory.getConfiguration(false);
+    }
+
+    /**
+     * Tests loading a definition file with multiple different sources.
+     */
+    public void testLoadDifferentSources() throws ConfigurationException
+    {
+        factory.setFileName(MULTI_FILE);
+        Configuration config = factory.getConfiguration();
+        assertFalse(config.isEmpty());
+        assertTrue(config instanceof CombinedConfiguration);
+        CombinedConfiguration cc = (CombinedConfiguration) config;
+        assertEquals("Wrong number of configurations", 1, cc
+                .getNumberOfConfigurations());
+
+        assertNotNull(config
+                .getProperty("tables.table(0).fields.field(2).name"));
+        assertNotNull(config.getProperty("element2.subelement.subsubelement"));
+        assertEquals("value", config.getProperty("element3"));
+        assertEquals("foo", config.getProperty("element3[@name]"));
+        assertNotNull(config.getProperty("mail.account.user"));
+
+        // test JNDIConfiguration
+        assertNotNull(config.getProperty("test.onlyinjndi"));
+        assertTrue(config.getBoolean("test.onlyinjndi"));
+
+        Configuration subset = config.subset("test");
+        assertNotNull(subset.getProperty("onlyinjndi"));
+        assertTrue(subset.getBoolean("onlyinjndi"));
+
+        // test SystemConfiguration
+        assertNotNull(config.getProperty("java.version"));
+        assertEquals(System.getProperty("java.version"), config
+                .getString("java.version"));
+    }
+
+    /**
+     * Tests if the base path is correctly evaluated.
+     */
+    public void testSetConfigurationBasePath() throws ConfigurationException
+    {
+        factory.addProperty("properties[@fileName]", "test.properties");
+        File deepDir = new File("conf/config/deep");
+        factory.setConfigurationBasePath(deepDir.getAbsolutePath());
+
+        Configuration config = factory.getConfiguration(false);
+        assertEquals("Wrong property value", "somevalue", config
+                .getString("somekey"));
+    }
+
+    /**
+     * Tests reading a configuration definition file that contains complex
+     * initialization of properties of the declared configuration sources.
+     */
+    public void testComplexInitialization() throws ConfigurationException
+    {
+        factory.setFileName(INIT_FILE);
+        CombinedConfiguration cc = (CombinedConfiguration) factory
+                .getConfiguration();
+
+        assertEquals("System property not found", "test.xml",
+                cc.getString("test_file_xml"));
+        PropertiesConfiguration c1 = (PropertiesConfiguration) cc
+                .getConfiguration(1);
+        assertTrue(
+                "Reloading strategy was not set",
+                c1.getReloadingStrategy() instanceof FileChangedReloadingStrategy);
+        assertEquals("Refresh delay was not set", 10000,
+                ((FileChangedReloadingStrategy) c1.getReloadingStrategy())
+                        .getRefreshDelay());
+
+        Configuration xmlConf = cc.getConfiguration("xml");
+        assertEquals("Property not found", "I'm complex!", xmlConf
+                .getString("element2/subelement/subsubelement"));
+        assertEquals("List index not found", "two", xmlConf
+                .getString("list[0]/item[1]"));
+        assertEquals("Property in combiner file not found", "yellow", cc
+                .getString("/gui/selcolor"));
+
+        assertTrue("Delimiter flag was not set", cc
+                .isDelimiterParsingDisabled());
+        assertTrue("Expression engine was not set",
+                cc.getExpressionEngine() instanceof XPathExpressionEngine);
+    }
+
+    /**
+     * Tests if the returned combined configuration has the expected structure.
+     */
+    public void testCombinedConfiguration() throws ConfigurationException
+    {
+        factory.setFileName(INIT_FILE);
+        CombinedConfiguration cc = (CombinedConfiguration) factory
+                .getConfiguration();
+        assertNotNull("Properties configuration not found", cc
+                .getConfiguration("properties"));
+        assertNotNull("XML configuration not found", cc.getConfiguration("xml"));
+        assertEquals("Wrong number of contained configs", 4, cc
+                .getNumberOfConfigurations());
+
+        CombinedConfiguration cc2 = (CombinedConfiguration) cc
+                .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);
+        assertNotNull("No additional configuration found", cc2);
+        Set names = cc2.getConfigurationNames();
+        assertEquals("Wrong number of contained additional configs", 2, names
+                .size());
+        assertTrue("Config 1 not contained", names.contains("combiner1"));
+        assertTrue("Config 2 not contained", names.contains("combiner2"));
+    }
+
+    /**
+     * Tests the structure of the returned combined configuration if there is no
+     * additional section.
+     */
+    public void testCombinedConfigurationNoAdditional()
+            throws ConfigurationException
+    {
+        factory.setFileName(TEST_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        assertNull("Additional configuration was found", cc
+                .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME));
+    }
+
+    /**
+     * Tests whether the list node definition was correctly processed.
+     */
+    public void testCombinedConfigurationListNodes()
+            throws ConfigurationException
+    {
+        factory.setFileName(INIT_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        Set listNodes = cc.getNodeCombiner().getListNodes();
+        assertEquals("Wrong number of list nodes", 2, listNodes.size());
+        assertTrue("table node not a list node", listNodes.contains("table"));
+        assertTrue("list node not a list node", listNodes.contains("list"));
+
+        CombinedConfiguration cca = (CombinedConfiguration) cc
+                .getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);
+        listNodes = cca.getNodeCombiner().getListNodes();
+        assertTrue("Found list nodes for additional combiner", listNodes
+                .isEmpty());
+    }
+
+    /**
+     * Tests whether XML settings can be inherited.
+     */
+    public void testLoadXMLWithSettings() throws ConfigurationException,
+            IOException
+    {
+        File confDir = new File("conf");
+        File targetDir = new File("target");
+        File testXMLSource = new File(confDir, "testDtd.xml");
+        File testXMLValidationSource = new File(confDir,
+                "testValidateInvalid.xml");
+        File testSavedXML = new File(targetDir, "testSave.xml");
+        File testSavedFactory = new File(targetDir, "testSaveFactory.xml");
+        File dtdFile = new File(confDir, "properties.dtd");
+        final String publicId = "http://commons.apache.org/test.dtd";
+
+        XMLConfiguration config = new XMLConfiguration(testXMLSource);
+        config.setPublicID(publicId);
+        config.save(testSavedXML);
+        factory.addProperty("xml[@fileName]", testSavedXML.getAbsolutePath());
+        factory.addProperty("xml(0)[@validating]", "true");
+        factory.addProperty("xml(-1)[@fileName]", testXMLValidationSource
+                .getAbsolutePath());
+        factory.addProperty("xml(1)[@config-optional]", "true");
+        factory.addProperty("xml(1)[@validating]", "true");
+        factory.save(testSavedFactory);
+
+        factory = new DefaultConfigurationBuilder();
+        factory.setFile(testSavedFactory);
+        factory.registerEntityId(publicId, dtdFile.toURL());
+        factory.clearErrorListeners();
+        Configuration c = factory.getConfiguration();
+        assertEquals("Wrong property value", "value1", c.getString("entry(0)"));
+        assertFalse("Invalid XML source was loaded", c
+                .containsKey("table.name"));
+
+        testSavedXML.delete();
+        testSavedFactory.delete();
+    }
+
+    /**
+     * Tests loading a configuration definition file that defines a custom
+     * result class.
+     */
+    public void testExtendedClass() throws ConfigurationException
+    {
+        factory.setFileName(CLASS_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String prop = (String)cc.getProperty("test");
+        assertEquals("Expected 'Extended', actual '" + prop + "'", "Extended", prop);
+        assertTrue("Wrong result class: " + cc.getClass(),
+                cc instanceof TestDefaultConfigurationBuilder.ExtendedCombinedConfiguration);
+    }
+
+    /**
+     * Tests loading a configuration definition file that defines new providers.
+     */
+    public void testConfigurationProvider() throws ConfigurationException
+    {
+        factory.setFileName(PROVIDER_FILE);
+        factory.getConfiguration(true);
+        DefaultConfigurationBuilder.ConfigurationProvider provider = factory
+                .providerForTag("test");
+        assertNotNull("Provider 'test' not registered", provider);
+    }
+
+        /**
+     * Tests loading a configuration definition file that defines new providers.
+     */
+    public void testExtendedXMLConfigurationProvider() throws ConfigurationException
+    {
+        factory.setFileName(EXTENDED_PROVIDER_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        DefaultConfigurationBuilder.ConfigurationProvider provider = factory
+                .providerForTag("test");
+        assertNotNull("Provider 'test' not registered", provider);
+        Configuration config = cc.getConfiguration("xml");
+        assertNotNull("Test configuration not present", config);
+        assertTrue("Configuration is not ExtendedXMLConfiguration, is " +
+                config.getClass().getName(),
+                config instanceof TestDefaultConfigurationBuilder.ExtendedXMLConfiguration);
+    }
+
+    public void testGlobalLookup() throws Exception
+    {
+        factory.setFileName(GLOBAL_LOOKUP_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String value = cc.getInterpolator().lookup("test:test_key");
+        assertNotNull("The test key was not located", value);
+        assertEquals("Incorrect value retrieved","test.value",value);
+    }
+
+    public void testSystemProperties() throws Exception
+    {
+        factory.setFileName(SYSTEM_PROPS_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String value = System.getProperty("key1");
+        assertNotNull("The test key was not located", value);
+        assertEquals("Incorrect value retrieved","value1",value);
+    }
+
+
+    public void testValidation() throws Exception
+    {
+        factory.setFileName(VALIDATION_FILE);
+        CombinedConfiguration cc = factory.getConfiguration(true);
+        String value = System.getProperty("key1");
+        assertNotNull("The test key was not located", value);
+        assertEquals("Incorrect value retrieved","value1",value);
+    }
+
+    public void testMultiTenentConfiguration() throws Exception
+    {
+        factory.setFileName(MULTI_TENENT_FILE);
+        System.clearProperty("Id");
+
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration);
+
+        verify("1001", config, 15);
+        verify("1002", config, 25);
+        verify("1003", config, 35);
+        verify("1004", config, 50);
+        verify("1005", config, 50);
+    }
+
+    public void testMultiTenentConfiguration2() throws Exception
+    {
+        factory.setFileName(MULTI_TENENT_FILE);
+        System.setProperty("Id", "1004");
+
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration);
+
+        verify("1001", config, 15);
+        verify("1002", config, 25);
+        verify("1003", config, 35);
+        verify("1004", config, 50);
+        verify("1005", config, 50);
+    }
+
+    public void testMultiTenentConfiguration3() throws Exception
+    {
+        factory.setFileName(MULTI_TENENT_FILE);
+        System.setProperty("Id", "1005");
+
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertTrue("Incorrect configuration", config instanceof DynamicCombinedConfiguration);
+
+        verify("1001", config, 15);
+        verify("1002", config, 25);
+        verify("1003", config, 35);
+        verify("1004", config, 50);
+        verify("1005", config, 50);
+    }
+
+    private void verify(String key, CombinedConfiguration config, int rows)
+    {
+        System.setProperty("Id", key);
+        int actual = config.getInt("rowsPerPage");
+        assertTrue("expected: " + rows + " actual: " + actual, actual == rows);
+    }
+
+    public Map getOptions()
+    {
+        return this.options;
+    }
+
+    /**
+     * Helper method for checking if a save operation was successful. Loads a
+     * saved configuration and then tests against a reference configuration.
+     * @param conf the original configuration
+     * @param newConfig the configuration to check
+     * @throws ConfigurationException if an error occurs
+     */
+    private void checkSavedConfig(XMLConfiguration conf, FileConfiguration newConfig)
+        throws ConfigurationException
+    {
+        newConfig.load();
+        ConfigurationAssert.assertEquals(conf, newConfig);
+    }
+}
\ No newline at end of file

Modified: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java?rev=757474&r1=757473&r2=757474&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestXMLConfiguration.java Mon Mar 23 18:05:25 2009
@@ -768,6 +768,18 @@
         assertEquals("a,b,c", conf2.getString("split.list1"));
         assertEquals(0, conf2.getMaxIndex("split.list1"));
         assertEquals("a\\,b\\,c", conf2.getString("split.list2"));
+        conf2 = new XMLConfiguration();
+        conf2.setExpressionEngine(new XPathExpressionEngine());
+        conf2.setDelimiterParsingDisabled(true);
+        conf2.setFile(new File(testProperties));
+        conf2.load();
+
+        assertEquals("a,b,c", conf2.getString("split/list3/@values"));
+        assertEquals(0, conf2.getMaxIndex("split/list3/@values"));
+        assertEquals("a\\,b\\,c", conf2.getString("split/list4/@values"));
+        assertEquals("a,b,c", conf2.getString("split/list1"));
+        assertEquals(0, conf2.getMaxIndex("split/list1"));
+        assertEquals("a\\,b\\,c", conf2.getString("split/list2"));
     }
 
     /**

Copied: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java (from r744551, commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java)
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java?p2=commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java&p1=commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java&r1=744551&r2=757474&rev=757474&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestFileChangedReloadingStrategy.java (original)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java Mon Mar 23 18:05:25 2009
@@ -26,18 +26,32 @@
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.configuration.FileSystem;
+import org.apache.commons.configuration.VFSFileSystem;
 
 /**
- * Test case for the ReloadableConfiguration class.
+ * Test case for the VFSFileMonitorReloadingStrategy class.
  *
- * @author Emmanuel Bourg
- * @version $Revision$, $Date$
+ * @author Ralph Goers
+ * @version $Revision$
  */
-public class TestFileChangedReloadingStrategy extends TestCase
+public class TestVFSFileMonitorReloadingStrategy extends TestCase
 {
     /** Constant for the name of a test properties file.*/
     private static final String TEST_FILE = "test.properties";
 
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        FileSystem.setDefaultFileSystem(new VFSFileSystem());
+    }
+
+    protected void tearDown() throws Exception
+    {
+        FileSystem.resetDefaultFileSystem();
+        super.tearDown();
+    }
+
     public void testAutomaticReloading() throws Exception
     {
         // create a new configuration
@@ -56,12 +70,12 @@
 
         // load the configuration
         PropertiesConfiguration config = new PropertiesConfiguration("target/testReload.properties");
-        FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
-        strategy.setRefreshDelay(500);
+        VFSFileMonitorReloadingStrategy strategy = new VFSFileMonitorReloadingStrategy();
+        strategy.setDelay(500);
         config.setReloadingStrategy(strategy);
         assertEquals("Initial value", "value1", config.getString("string"));
 
-        Thread.sleep(2000);
+        Thread.sleep(1000);
 
         // change the file
         out = new FileWriter(file);
@@ -69,8 +83,15 @@
         out.flush();
         out.close();
 
+        Thread.sleep(2000);
+
         // test the automatic reloading
         assertEquals("Modified value with enabled reloading", "value2", config.getString("string"));
+        strategy.stopMonitor();
+        if (file.exists())
+        {
+            file.delete();
+        }
     }
 
     public void testNewFileReloading() throws Exception
@@ -85,8 +106,8 @@
 
         PropertiesConfiguration config = new PropertiesConfiguration();
         config.setFile(file);
-        FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
-        strategy.setRefreshDelay(500);
+        VFSFileMonitorReloadingStrategy strategy = new VFSFileMonitorReloadingStrategy();
+        strategy.setDelay(500);
         config.setReloadingStrategy(strategy);
 
         assertNull("Initial value", config.getString("string"));
@@ -101,66 +122,61 @@
 
         // test the automatic reloading
         assertEquals("Modified value with enabled reloading", "value1", config.getString("string"));
+        strategy.stopMonitor();
+        if (file.exists())
+        {
+            file.delete();
+        }
     }
 
-    public void testGetRefreshDelay()
+    public void testGetRefreshDelay() throws Exception
     {
-        FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
-        strategy.setRefreshDelay(500);
-        assertEquals("refresh delay", 500, strategy.getRefreshDelay());
-    }
+        // create a new configuration
+        File file = new File("target/testReload.properties");
 
-    /**
-     * Tests if a file from the classpath can be monitored.
-     */
-    public void testFromClassPath() throws Exception
-    {
-        PropertiesConfiguration config = new PropertiesConfiguration();
-        config.setFileName(TEST_FILE);
-        config.load();
-        assertTrue(config.getBoolean("configuration.loaded"));
-        FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
+        if (file.exists())
+        {
+            file.delete();
+        }
+
+        // create the configuration file
+        FileWriter out = new FileWriter(file);
+        out.write("string=value1");
+        out.flush();
+        out.close();
+
+        PropertiesConfiguration config = new PropertiesConfiguration("target/testReload.properties");
+        VFSFileMonitorReloadingStrategy strategy = new VFSFileMonitorReloadingStrategy();
+        strategy.setDelay(500);
         config.setReloadingStrategy(strategy);
-        assertEquals(config.getURL(), strategy.getFile().toURL());
-    }
+        // Minimum is 1 second.
+        assertEquals("refresh delay", 1000, strategy.getDelay());
 
-    /**
-     * Tests to watch a configuration file in a jar. In this case the jar file
-     * itself should be monitored.
-     */
-    public void testFromJar() throws Exception
-    {
-        XMLConfiguration config = new XMLConfiguration();
-        // use some jar: URL
-        config.setURL(new URL("jar:" + new File("conf/resources.jar").getAbsoluteFile().toURL() + "!/test-jar.xml"));
-        FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
-        config.setReloadingStrategy(strategy);
-        File file = strategy.getFile();
-        assertNotNull("Strategy's file is null", file);
-        assertEquals("Strategy does not monitor the jar file", "resources.jar", file.getName());
-    }
+        config = new PropertiesConfiguration("target/testReload.properties");
+        strategy = new VFSFileMonitorReloadingStrategy();
+        strategy.setDelay(1500);
+        config.setReloadingStrategy(strategy);
+        // Can be made longer
+        assertEquals("refresh delay", 1500, strategy.getDelay());
 
-    /**
-     * Tests calling reloadingRequired() multiple times before a reload actually
-     * happens. This test is related to CONFIGURATION-302.
-     */
-    public void testReloadingRequiredMultipleTimes()
-            throws ConfigurationException
-    {
-        FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy()
+        config = new PropertiesConfiguration("target/testReload.properties");
+        strategy = new VFSFileMonitorReloadingStrategy();
+        strategy.setDelay(500);
+        config.setReloadingStrategy(strategy);
+        // Can't be made shorter
+        assertEquals("refresh delay", 1500, strategy.getDelay());
+
+        strategy.stopMonitor();
+        // Reset and verify everything clears
+        config = new PropertiesConfiguration("target/testReload.properties");
+        strategy = new VFSFileMonitorReloadingStrategy();
+        strategy.setDelay(1100);
+        config.setReloadingStrategy(strategy);
+        assertEquals("refresh delay", 1100, strategy.getDelay());
+        strategy.stopMonitor();
+        if (file.exists())
         {
-            protected boolean hasChanged()
-            {
-                // signal always a change
-                return true;
-            }
-        };
-        strategy.setRefreshDelay(100000);
-        PropertiesConfiguration config = new PropertiesConfiguration(TEST_FILE);
-        config.setReloadingStrategy(strategy);
-        assertTrue("Reloading not required", strategy.reloadingRequired());
-        assertTrue("Reloading no more required", strategy.reloadingRequired());
-        strategy.reloadingPerformed();
-        assertFalse("Reloading still required", strategy.reloadingRequired());
+            file.delete();
+        }
     }
-}
+}
\ No newline at end of file

Propchange: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

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

Propchange: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/reloading/TestVFSFileMonitorReloadingStrategy.java
------------------------------------------------------------------------------
    svn:mergeinfo = 

Modified: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestDefaultConfigurationNode.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestDefaultConfigurationNode.java?rev=757474&r1=757473&r2=757474&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestDefaultConfigurationNode.java (original)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/tree/TestDefaultConfigurationNode.java Mon Mar 23 18:05:25 2009
@@ -469,7 +469,7 @@
      * It also supports a maximum number of visits to be set; if this number is
      * reached, the <code>terminate()</code> method returns <b>true</b>.
      */
-    static class CountNodeVisitor implements ConfigurationNodeVisitor
+    public static class CountNodeVisitor implements ConfigurationNodeVisitor
     {
         public int beforeCalls;
 

Modified: commons/proper/configuration/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/xdocs/changes.xml?rev=757474&r1=757473&r2=757474&view=diff
==============================================================================
--- commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ commons/proper/configuration/trunk/xdocs/changes.xml Mon Mar 23 18:05:25 2009
@@ -23,6 +23,11 @@
 
   <body>
     <release version="1.7" date="in SVN" description="">
+      <action dev="rgoers" type="add" issue="CONFIGURATION-340">
+        File system access has been abstracted to a FileSystem interface. Two implementations
+        are provided, DefaultFileSystem that behaves in a backward compatible manner and
+        VFSFileSystem which uses Commons VFS to retreive and store files.
+      </action>
       <action dev="oheger" type="add" issue="CONFIGURATION-370">
         PropertiesConfiguration now defines a nested interface IOFactory. Using
         this interface it is possible to inject custom PropertiesReader and