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/10/11 00:17:02 UTC

svn commit: r823969 - in /commons/proper/configuration/branches/configuration2_experimental: src/main/java/org/apache/commons/configuration2/ src/main/java/org/apache/commons/configuration2/beanutils/ src/main/java/org/apache/commons/configuration2/fs/...

Author: rgoers
Date: Sat Oct 10 22:17:01 2009
New Revision: 823969

URL: http://svn.apache.org/viewvc?rev=823969&view=rev
Log:
Fix for CONFIGURATION-397 and add debug logging

Added:
    commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2001.xml
    commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2002.xml
    commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder2.xml
    commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder3.xml
Modified:
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/BeanHelper.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/fs/DefaultFileSystem.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/FileChangedReloadingStrategy.java
    commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestMultiFileHierarchicalConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestXMLConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/combined/TestCombinedConfiguration.java
    commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_filesystems.xml
    commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_multitenant.xml

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/AbstractHierarchicalFileConfiguration.java Sat Oct 10 22:17:01 2009
@@ -32,6 +32,8 @@
 
 import org.apache.commons.configuration2.event.ConfigurationEvent;
 import org.apache.commons.configuration2.event.ConfigurationListener;
+import org.apache.commons.configuration2.event.ConfigurationErrorEvent;
+import org.apache.commons.configuration2.event.ConfigurationErrorListener;
 import org.apache.commons.configuration2.expr.NodeList;
 import org.apache.commons.configuration2.fs.DefaultFileSystem;
 import org.apache.commons.configuration2.fs.FileSystem;
@@ -85,7 +87,7 @@
  */
 public abstract class AbstractHierarchicalFileConfiguration
 extends InMemoryConfiguration
-implements FileConfiguration, ConfigurationListener, FileSystemBased
+implements FileConfiguration, ConfigurationListener, ConfigurationErrorListener, FileSystemBased
 {
     /** Constant for the configuration reload event.*/
     public static final int EVENT_RELOAD = 20;
@@ -812,6 +814,11 @@
      */
     public void reload()
     {
+        reload(false);
+    }
+
+    public boolean reload(boolean checkReload)
+    {
         synchronized (reloadLock)
         {
             if (noReload == 0)
@@ -850,6 +857,10 @@
                 {
                     fireError(EVENT_RELOAD, null, null, e);
                     // todo rollback the changes if the file can't be reloaded
+                    if (checkReload)
+                    {
+                        return false;
+                    }
                 }
                 finally
                 {
@@ -857,6 +868,7 @@
                 }
             }
         }
+        return true;
     }
 
     /**
@@ -982,8 +994,11 @@
     @Override
     protected NodeList<ConfigurationNode> fetchNodeList(String key)
     {
-        reload();
-        return super.fetchNodeList(key);
+        if (reload(true))
+        {
+            return super.fetchNodeList(key);
+        }
+        return new NodeList<ConfigurationNode>();
     }
 
     /**
@@ -1059,6 +1074,12 @@
         }
     }
 
+    public void configurationError(ConfigurationErrorEvent event)
+    {
+        fireError(event.getType(), event.getPropertyName(), event.getPropertyValue(),
+                event.getCause());
+    }
+
     /**
      * A helper method for closing an output stream. Occurring exceptions will
      * be ignored.

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/CombinedConfiguration.java Sat Oct 10 22:17:01 2009
@@ -206,6 +206,9 @@
     /** A flag whether an enhanced reload check is to be performed.*/
     private boolean forceReloadCheck;
 
+    /** The default behavior is to ignore exceptions that occur during reload */
+    private boolean ignoreReloadExceptions = true;
+
     /**
      * Creates a new instance of <code>CombinedConfiguration</code> and
      * initializes the combiner to be used.
@@ -290,6 +293,26 @@
     }
 
     /**
+     * Retrieves the value of the ignoreReloadExceptions flag.
+     * @return true if exceptions are ignored, false otherwise.
+     */
+    public boolean isIgnoreReloadExceptions()
+    {
+        return ignoreReloadExceptions;
+    }
+
+    /**
+     * If set to true then exceptions that occur during reloading will be
+     * ignored. If false then the exceptions will be allowed to be thrown
+     * back to the caller.
+     * @param ignoreReloadExceptions true if exceptions should be ignored.
+     */
+    public void setIgnoreReloadExceptions(boolean ignoreReloadExceptions)
+    {
+        this.ignoreReloadExceptions = ignoreReloadExceptions;
+    }    
+
+    /**
      * Adds a new configuration to this combined configuration. It is possible
      * (but not mandatory) to give the new configuration a name. This name must
      * be unique, otherwise a <code>ConfigurationRuntimeException</code> will
@@ -610,8 +633,10 @@
                 }
                 catch (Exception ex)
                 {
-                    // ignore all exceptions, e.g. missing property exceptions
-                    ;
+                    if (!ignoreReloadExceptions)
+                    {
+                        throw new ConfigurationRuntimeException(ex);
+                    }
                 }
             }
         }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DefaultConfigurationBuilder.java Sat Oct 10 22:17:01 2009
@@ -26,6 +26,7 @@
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.Log;
 
 import javax.naming.InitialContext;
 import javax.sql.DataSource;
@@ -663,6 +664,11 @@
         for (AbstractHierarchicalConfiguration<ConfigurationNode> conf : containedConfigs)
         {
             ConfigurationDeclaration decl = new ConfigurationDeclaration(this, conf);
+            if (getLogger().isDebugEnabled())
+            {
+                getLogger().debug("Creating configuration " + decl.getBeanClassName() + " with name " +
+                    decl.getConfiguration().getString(ATTR_NAME));
+            }
             AbstractConfiguration newConf = createConfigurationAt(decl);
             if (newConf != null)
             {
@@ -1228,6 +1234,8 @@
      */
     static class ConfigurationBeanFactory implements BeanFactory
     {
+        private Log logger = LogFactory.getLog(DefaultConfigurationBuilder.class);
+
         /**
          * Creates an instance of a bean class. This implementation expects that
          * the passed in bean declaration is a declaration for a configuration.
@@ -1271,6 +1279,11 @@
                 }
                 else
                 {
+                    if (logger.isDebugEnabled())
+                    {
+                        logger.debug("Load failed for optional configuration " + tagName + ": "
+                            + ex.getMessage());
+                    }                    
                     // Notify registered error listeners
                     decl.getConfigurationBuilder().fireError(
                             EVENT_ERR_LOAD_OPTIONAL,

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/DynamicCombinedConfiguration.java Sat Oct 10 22:17:01 2009
@@ -32,8 +32,10 @@
 import org.apache.commons.configuration2.tree.ConfigurationNode;
 import org.apache.commons.configuration2.tree.ExpressionEngine;
 import org.apache.commons.configuration2.tree.NodeCombiner;
+import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.logging.Log;
+import org.apache.commons.lang.text.StrSubstitutor;
 
 /**
  * DynamicCombinedConfiguration allows a set of CombinedConfigurations to be used. Each CombinedConfiguration
@@ -75,7 +77,10 @@
     private NodeCombiner nodeCombiner;
 
     /** The name of the logger to use for each CombinedConfiguration */
-    private String loggerName;
+    private String loggerName = DynamicCombinedConfiguration.class.getName();
+
+    private StrSubstitutor localSubst = new StrSubstitutor(new ConfigurationInterpolator());
+
 
     /**
      * Creates a new instance of <code>CombinedConfiguration</code> and
@@ -88,6 +93,8 @@
     {
         super();
         setNodeCombiner(comb);
+        setIgnoreReloadExceptions(false);
+        setLogger(LogFactory.getLog(DynamicCombinedConfiguration.class));
     }
 
     /**
@@ -99,6 +106,8 @@
     public DynamicCombinedConfiguration()
     {
         super();
+        setIgnoreReloadExceptions(false);
+        setLogger(LogFactory.getLog(DynamicCombinedConfiguration.class));
     }
 
     public void setKeyPattern(String pattern)
@@ -744,6 +753,7 @@
                         config.setLogger(log);
                     }
                 }
+                config.setIgnoreReloadExceptions(isIgnoreReloadExceptions());
                 config.setExpressionEngine(this.getExpressionEngine());
                 config.setDelimiterParsingDisabled(isDelimiterParsingDisabled());
                 config.setListDelimiter(getListDelimiter());
@@ -764,6 +774,10 @@
                 configs.put(key, config);
             }
         }
+        if (getLogger().isDebugEnabled())
+        {
+            getLogger().debug("Returning config for " + key + ": " + config);
+        }        
         return config;
     }
 

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/MultiFileHierarchicalConfiguration.java Sat Oct 10 22:17:01 2009
@@ -40,9 +40,12 @@
 import org.apache.commons.configuration2.reloading.ReloadingStrategy;
 import org.apache.commons.configuration2.resolver.EntityResolverSupport;
 import org.apache.commons.configuration2.tree.ConfigurationNode;
+import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.logging.Log;
+import org.apache.commons.lang.text.StrSubstitutor;
 import org.xml.sax.EntityResolver;
+import org.xml.sax.SAXParseException;
 
 /**
  * This class provides access to multiple configuration files that reside in a location that
@@ -93,7 +96,7 @@
     private boolean attributeSplittingDisabled;
 
     /** The Logger name to use */
-    private String loggerName = "";
+    private String loggerName = MultiFileHierarchicalConfiguration.class.getName();
 
     /** The Reloading strategy to use on created configurations */
     private ReloadingStrategy fileStrategy;
@@ -101,6 +104,9 @@
     /** The EntityResolver */
     private EntityResolver entityResolver;
 
+    /** Substitutor to use to resolve the pattern */
+    private StrSubstitutor localSubst = new StrSubstitutor(new ConfigurationInterpolator());
+
     /**
      * Default Constructor
      */
@@ -108,6 +114,7 @@
     {
         super();
         this.init = true;
+        setLogger(LogFactory.getLog(loggerName));
     }
 
     /**
@@ -119,6 +126,7 @@
         super();
         this.pattern = pathPattern;
         this.init = true;
+        setLogger(LogFactory.getLog(loggerName));
     }
 
     public void setLoggerName(String name)
@@ -641,6 +649,14 @@
                 listener.configurationError(event);
             }
         }
+
+        if (event.getType() == AbstractHierarchicalFileConfiguration.EVENT_RELOAD)
+        {
+            if (isThrowable(event.getCause()))
+            {
+                throw new ConfigurationRuntimeException(event.getCause());
+            }
+        }
     }
 
     /*
@@ -691,7 +707,7 @@
         {
             throw new ConfigurationRuntimeException("File pattern must be defined");
         }
-        String path = getSubstitutor().replace(pattern);
+        String path = localSubst.replace(pattern);
 
         if (configurationsMap.containsKey(path))
         {
@@ -747,7 +763,7 @@
         }
         catch (ConfigurationException ce)
         {
-            if (!ignoreException)
+            if (isThrowable(ce))
             {
                 throw new ConfigurationRuntimeException(ce);
             }
@@ -755,6 +771,20 @@
         configurationsMap.putIfAbsent(path, configuration);
         return configurationsMap.get(path);
     }
+    
+    private boolean isThrowable(Throwable throwable)
+    {
+        if (!ignoreException)
+        {
+            return true;
+        }
+        Throwable cause = throwable.getCause();
+        while (cause != null && !(cause instanceof SAXParseException))
+        {
+            cause = cause.getCause();
+        }
+        return cause != null;
+    }
 
     /**
      * Clone the FileReloadingStrategy since each file needs its own.

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/XMLConfiguration.java Sat Oct 10 22:17:01 2009
@@ -49,6 +49,7 @@
 import org.apache.commons.configuration2.resolver.EntityRegistry;
 import org.apache.commons.configuration2.tree.ConfigurationNode;
 import org.apache.commons.configuration2.tree.DefaultConfigurationNode;
+import org.apache.commons.logging.LogFactory;
 import org.w3c.dom.Attr;
 import org.w3c.dom.CDATASection;
 import org.w3c.dom.DOMException;
@@ -153,7 +154,7 @@
  * interface and thus provides full support for loading XML documents from
  * different sources like files, URLs, or streams. A full description of these
  * features can be found in the documentation of
- * <code>{@link AbstractFileConfiguration}</code>.</p>
+ * <code>{@link AbstractHierarchicalFileConfiguration}</code>.</p>
  *
  * <p><em>Note:</em>Configuration objects of this type can be read concurrently
  * by multiple threads. However if one of these threads modifies the object,
@@ -226,6 +227,7 @@
     public XMLConfiguration()
     {
         super();
+        setLogger(LogFactory.getLog(XMLConfiguration.class));
     }
 
     /**
@@ -243,6 +245,7 @@
         super(c);
         clearReferences(getRootNode());
         setRootElementName(getRootNode().getName());
+        setLogger(LogFactory.getLog(XMLConfiguration.class));
     }
 
     /**
@@ -255,6 +258,7 @@
     public XMLConfiguration(String fileName) throws ConfigurationException
     {
         super(fileName);
+        setLogger(LogFactory.getLog(XMLConfiguration.class));
     }
 
     /**
@@ -267,6 +271,7 @@
     public XMLConfiguration(File file) throws ConfigurationException
     {
         super(file);
+        setLogger(LogFactory.getLog(XMLConfiguration.class));
     }
 
     /**
@@ -279,6 +284,7 @@
     public XMLConfiguration(URL url) throws ConfigurationException
     {
         super(url);
+        setLogger(LogFactory.getLog(XMLConfiguration.class));
     }
 
     /**
@@ -566,6 +572,7 @@
     public void clear()
     {
         super.clear();
+        setRootNode(new DefaultConfigurationNode());
         document = null;
     }
 
@@ -955,6 +962,7 @@
         }
         catch (Exception e)
         {
+            this.getLogger().debug("Unable to load the configuraton", e);           
             throw new ConfigurationException("Unable to load the configuration", e);
         }
     }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/BeanHelper.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/BeanHelper.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/BeanHelper.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/beanutils/BeanHelper.java Sat Oct 10 22:17:01 2009
@@ -267,7 +267,7 @@
                 return;
             }
             throw new ConfigurationRuntimeException("Property " + propName
-                    + " cannot be set!");
+                    + " cannot be set on " + bean.getClass().getName());
         }
 
         try

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/fs/DefaultFileSystem.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/fs/DefaultFileSystem.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/fs/DefaultFileSystem.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/fs/DefaultFileSystem.java Sat Oct 10 22:17:01 2009
@@ -30,6 +30,8 @@
 import org.apache.commons.configuration2.ConfigurationException;
 import org.apache.commons.configuration2.ConfigurationUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * FileSystem that uses java.io.File or HttpClient
@@ -41,6 +43,10 @@
 {
     /** Constant for the file URL protocol */
     private static final String FILE_SCHEME = "file:";
+    /**
+     * The Log for diagnostic messages.
+     */
+    private Log log = LogFactory.getLog(DefaultFileSystem.class);
 
     @Override
     public InputStream getInputStream(String basePath, String fileName)
@@ -270,6 +276,10 @@
         }
         catch (IOException e)
         {
+            if (log.isDebugEnabled())
+            {
+                log.debug("Could not locate file " + fileName + " at " + basePath + ": " + e.getMessage());
+            }
             return null;
         }
     }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/FileChangedReloadingStrategy.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/FileChangedReloadingStrategy.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/FileChangedReloadingStrategy.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/reloading/FileChangedReloadingStrategy.java Sat Oct 10 22:17:01 2009
@@ -23,6 +23,8 @@
 
 import org.apache.commons.configuration2.ConfigurationUtils;
 import org.apache.commons.configuration2.FileConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * <p>A reloading strategy that will reload the configuration every time its
@@ -64,6 +66,10 @@
     /** A flag whether a reload is required.*/
     private boolean reloading;
 
+     /** The Log to use for diagnostic messages */
+    private Log logger = LogFactory.getLog(FileChangedReloadingStrategy.class);
+
+
     public void setConfiguration(FileConfiguration configuration)
     {
         this.configuration = configuration;
@@ -85,6 +91,10 @@
                 lastChecked = now;
                 if (hasChanged())
                 {
+                    if (logger.isDebugEnabled())
+                    {
+                        logger.debug("File change detected: " + getName());
+                    }
                     reloading = true;
                 }
             }
@@ -141,6 +151,11 @@
         File file = getFile();
         if (file == null || !file.exists())
         {
+            if (logger.isWarnEnabled() && lastModified != 0)
+            {
+                logger.warn("File was deleted: " + getName(file));
+                lastModified = 0;
+            }
             return false;
         }
 
@@ -186,4 +201,27 @@
             return ConfigurationUtils.fileFromURL(url);
         }
     }
+
+    private String getName()
+    {
+        return getName(getFile());
+    }
+
+    private String getName(File file)
+    {
+        String name = configuration.getURL().toString();
+        if (name == null)
+        {
+            if (file != null)
+            {
+                name = file.getAbsolutePath();
+            }
+            else
+            {
+                name = "base: " + configuration.getBasePath()
+                       + "file: " + configuration.getFileName();
+            }
+        }
+        return name;
+    }
 }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/main/java/org/apache/commons/configuration2/resolver/CatalogResolver.java Sat Oct 10 22:17:01 2009
@@ -183,7 +183,7 @@
             }
             catch (Exception e)
             {
-                log.debug("Failed to create InputSource for " + resolved, e);
+                log.warn("Failed to create InputSource for " + resolved + " (" + e.toString() + ")");
                 return null;
             }
         }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestMultiFileHierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestMultiFileHierarchicalConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestMultiFileHierarchicalConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestMultiFileHierarchicalConfiguration.java Sat Oct 10 22:17:01 2009
@@ -18,7 +18,16 @@
 package org.apache.commons.configuration2;
 
 import junit.framework.TestCase;
+//import org.apache.commons.configuration2.combined.CombinedConfiguration;
 import org.apache.commons.configuration2.reloading.FileChangedReloadingStrategy;
+import org.xml.sax.SAXParseException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.FileReader;
+import java.io.Writer;
+import java.io.FileWriter;
 
 /**
  * Unit test for simple MultiConfigurationTest.
@@ -27,6 +36,12 @@
 {
     private static String PATTERN1 = "target/test-classes/testMultiConfiguration_${sys:Id}.xml";
 
+    private static final File MULTI_TENENT_FILE = ConfigurationAssert
+            .getTestFile("testMultiTenentConfigurationBuilder2.xml");
+
+    private static final File MULTI_RELOAD_FILE = ConfigurationAssert
+            .getTestFile("testMultiTenentConfigurationBuilder3.xml");
+
     /**
      * Rigourous Test :-)
      */
@@ -35,7 +50,7 @@
         //set up a reloading strategy
         FileChangedReloadingStrategy strategy = new FileChangedReloadingStrategy();
         strategy.setRefreshDelay(10000);
-        
+
         MultiFileHierarchicalConfiguration config = new MultiFileHierarchicalConfiguration(PATTERN1);
         config.setReloadingStrategy(strategy);
 
@@ -48,4 +63,236 @@
         System.setProperty("Id", "1003");
         assertTrue(config.getInt("rowsPerPage") == 35);
     }
+
+    public void testSchemaValidationError() throws Exception
+    {
+        System.clearProperty("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_TENENT_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+        try
+        {
+            System.setProperty("Id", "2001");
+            config.getInt("rowsPerPage");
+            fail("No exception thrown");
+        }
+        catch (Exception ex)
+        {
+            Throwable cause = ex.getCause();
+            while (cause != null && !(cause instanceof SAXParseException))
+            {
+                cause = cause.getCause();
+            }
+            assertTrue("SAXParseException was not thrown", cause instanceof SAXParseException);
+        }
+    }
+
+    public void testSchemaValidation() throws Exception
+    {
+        System.clearProperty("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_TENENT_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+        System.setProperty("Id", "2002");
+        int rows = config.getInt("rowsPerPage");
+        assertTrue("expected: " + rows + " actual: " + "25", 25 == rows);
+    }
+
+    public void testMissingFile() throws Exception
+    {
+        System.clearProperty("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_TENENT_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+        System.setProperty("Id", "3099");
+        int rows = config.getInt("rowsPerPage");
+        assertTrue("expected: " + rows + " actual: " + "50", 50 == rows);
+
+    }
+
+    public void testFileReload1() throws Exception
+    {
+        System.getProperties().remove("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_RELOAD_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+
+        // create a new configuration
+        File input = new File("target/test-classes/testMultiConfiguration_3001.xml");
+        File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml");
+        output.delete();
+        output.getParentFile().mkdir();
+        copyFile(input, output);
+
+        assertNotNull(config);
+        verify("3001", config, 15);
+        Thread.sleep(1100);
+        XMLConfiguration x = new XMLConfiguration();
+        x.setFile(output);
+        x.setAttributeSplittingDisabled(true);
+        x.setDelimiterParsingDisabled(true);
+        x.load();
+        x.setProperty("rowsPerPage", "35");
+        //Insure orginal timestamp and new timestamp aren't the same second.
+        Thread.sleep(1100);
+        x.save();
+        verify("3001", config, 35);
+        output.delete();
+    }
+
+    public void testFileReload2() throws Exception
+    {
+        // create a new configuration
+        File input = new File("target/test-classes/testMultiConfiguration_3002.xml");
+        File output = new File("target/test-classes/testwrite/testMultiConfiguration_3002.xml");
+        output.delete();
+
+        System.getProperties().remove("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_RELOAD_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertNotNull(config);
+        // The file should not exist yet.
+        verify("3002", config, 50);
+
+        output.getParentFile().mkdir();
+        copyFile(input, output);
+        Thread.sleep(600);
+        verify("3002", config, 25);
+        output.delete();
+    }
+
+    public void testFileReload3() throws Exception
+    {
+        // create a new configuration
+        File input = new File("target/test-classes/testMultiConfiguration_3001.xml");
+        File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml");
+        output.delete();
+        output.getParentFile().mkdir();
+
+        System.getProperties().remove("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_RELOAD_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertNotNull(config);
+        //The file does not exist yet.
+        verify("3001", config, 50);
+        copyFile(input, output);
+        //Sleep so refreshDelay elapses
+        Thread.sleep(600);
+        verify("3001", config, 15);
+        Thread.sleep(500);
+        XMLConfiguration x = new XMLConfiguration();
+        x.setFile(output);
+        x.setAttributeSplittingDisabled(true);
+        x.setDelimiterParsingDisabled(true);
+        x.load();
+        x.setProperty("rowsPerPage", "35");
+        // Insure original timestamp and new timestamp are not the same second.
+        Thread.sleep(1100);
+        x.save();
+        verify("3001", config, 35);
+        output.delete();
+    }
+
+    public void testReloadDefault() throws Exception
+    {
+        // create a new configuration
+        String defaultName = "target/test-classes/testMultiConfiguration_default.xml";
+        File input = new File(defaultName);
+
+        System.getProperties().remove("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_TENENT_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+        assertNotNull(config);
+        verify("3001", config, 15);
+        verify("3002", config, 25);
+        System.setProperty("Id", "3002");
+        config.addProperty("/ TestProp", "Test");
+        assertTrue("Property not added", "Test".equals(config.getString("TestProp")));
+        System.getProperties().remove("Id");
+        //Sleep so refreshDelay elapses
+        Thread.sleep(600);
+        long time = System.currentTimeMillis();
+        long original = input.lastModified();
+        input.setLastModified(time);
+        File defaultFile = new File(defaultName);
+        long newTime = defaultFile.lastModified();
+        assertTrue("time mismatch", original != newTime);
+        Thread.sleep(600);
+        verify("3001", config, 15);
+        verify("3002", config, 25);
+        System.setProperty("Id", "3002");
+        String test = config.getString("TestProp");
+        assertNull("Property was not cleared by reload", test);
+    }
+
+    public void testFileReloadSchemaValidationError() throws Exception
+    {
+        System.getProperties().remove("Id");
+        DefaultConfigurationBuilder factory = new DefaultConfigurationBuilder();
+        factory.setFile(MULTI_RELOAD_FILE);
+        CombinedConfiguration config = factory.getConfiguration(true);
+
+        // create a new configuration
+        File input = new File("target/test-classes/testMultiConfiguration_3001.xml");
+        File output = new File("target/test-classes/testwrite/testMultiConfiguration_3001.xml");
+        output.delete();
+        output.getParentFile().mkdir();
+        copyFile(input, output);
+
+        assertNotNull(config);
+        verify("3001", config, 15);
+        Thread.sleep(1100);
+        XMLConfiguration x = new XMLConfiguration();
+        x.setFile(output);
+        x.setAttributeSplittingDisabled(true);
+        x.setDelimiterParsingDisabled(true);
+        x.load();
+        x.setProperty("rowsPerPage", "test");
+        //Insure orginal timestamp and new timestamp aren't the same second.
+        Thread.sleep(1100);
+        x.save();
+        System.setProperty("Id", "3001");
+        try
+        {
+            config.getInt("rowsPerPage");
+            fail("No exception was thrown");
+        }
+        catch (Exception ex)
+        {
+
+        }
+
+        output.delete();
+    }
+
+    private void copyFile(File input, File output) throws IOException
+    {
+        Reader reader = new FileReader(input);
+        Writer writer = new FileWriter(output);
+        char[] buffer = new char[4096];
+        int n = 0;
+        while (-1 != (n = reader.read(buffer)))
+        {
+            writer.write(buffer, 0, n);
+        }
+        reader.close();
+        writer.close();
+    }
+
+    private void verify(String key, CombinedConfiguration config, int rows)
+    {
+        if (key == null)
+        {
+            System.getProperties().remove("Id");
+        }
+        else
+        {
+            System.setProperty("Id", key);
+        }
+        int actual = config.getInt("rowsPerPage");
+        assertTrue("expected: " + rows + " actual: " + actual, actual == rows);
+    }
 }

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestXMLConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestXMLConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestXMLConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/TestXMLConfiguration.java Sat Oct 10 22:17:01 2009
@@ -640,6 +640,40 @@
         }
     }
 
+    /* This test is very slow.
+    public void testReloadingOOM() throws Exception
+    {
+        assertNotNull(conf.getReloadingStrategy());
+        assertTrue(conf.getReloadingStrategy() instanceof InvariantReloadingStrategy);
+        PrintWriter out = null;
+
+        try
+        {
+            out = new PrintWriter(new FileWriter(testSaveConf));
+            out.println("<?xml version=\"1.0\"?><config><test>1</test></config>");
+            out.close();
+            out = null;
+            conf.setFile(testSaveConf);
+            FileAlwaysReloadingStrategy strategy = new FileAlwaysReloadingStrategy();
+            strategy.setRefreshDelay(100);
+            conf.setReloadingStrategy(strategy);
+            conf.load();
+            assertEquals(1, conf.getInt("test"));
+
+            for (int i = 1; i < 50000; ++i)
+            {
+               assertEquals(1, conf.getInt("test"));
+            }
+        }
+        finally
+        {
+            if (out != null)
+            {
+                out.close();
+            }
+        }
+    } */
+    
     /**
      * Tests access to tag names with delimiter characters.
      */
@@ -1537,6 +1571,51 @@
         }
     }
 
+    /* Uncomment when reload locking is in place
+    public void testConcurrentGetAndReload() throws Exception
+    {
+        //final FileConfiguration config = new PropertiesConfiguration("test.properties");
+        final FileConfiguration config = new XMLConfiguration("test.xml");
+        config.setReloadingStrategy(new FileAlwaysReloadingStrategy());
+
+        assertTrue("Property not found", config.getProperty("test.short") != null);
+
+        Thread testThreads[] = new Thread[5];
+
+        for (int i = 0; i < testThreads.length; ++i)
+        {
+            testThreads[i] = new ReloadThread(config);
+            testThreads[i].start();
+        }
+
+        for (int i = 0; i < 2000; i++)
+        {
+            assertTrue("Property not found", config.getProperty("test.short") != null);
+        }
+
+        for (int i = 0; i < testThreads.length; ++i)
+        {
+            testThreads[i].join();
+        }
+    }
+
+    private class ReloadThread extends Thread
+    {
+        FileConfiguration config;
+
+        ReloadThread(FileConfiguration config)
+        {
+            this.config = config;
+        }
+        public void run()
+        {
+            for (int i = 0; i < 1000; i++)
+            {
+                config.reload();
+            }
+        }
+    } */
+
     /**
      * Prepares a configuration object for testing a reload operation.
      *

Modified: commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/combined/TestCombinedConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/combined/TestCombinedConfiguration.java?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/combined/TestCombinedConfiguration.java (original)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/java/org/apache/commons/configuration2/combined/TestCombinedConfiguration.java Sat Oct 10 22:17:01 2009
@@ -649,9 +649,9 @@
         engineInit.setIndexStart("{");
         engineInit.setIndexEnd("}");
         child.setExpressionEngine(engineInit);
-        
+
         child.addProperty("test(a)", "1,2,3");
-        
+
         config.addConfiguration(child);
         DefaultExpressionEngine engineQuery = new DefaultExpressionEngine();
         engineQuery.setIndexStart("<");
@@ -671,7 +671,7 @@
      * configuration is accessed concurrently. This test is related to
      * CONFIGURATION-344.
      */
-    /* todo test failing due to the lack of synchronization on the hierarchical configurations (CONFIGURATION-390) 
+    /* todo test failing due to the lack of synchronization on the hierarchical configurations (CONFIGURATION-390)
     public void testDeadlockWithReload() throws ConfigurationException,
             InterruptedException
     {
@@ -680,7 +680,7 @@
         child.setReloadingStrategy(new FileAlwaysReloadingStrategy());
         config.addConfiguration(child);
         final int count = 1000;
-        
+
         assertEquals("Wrong value of combined property", 8, config.getInt("test.short"));
 
         class ReloadThread extends Thread
@@ -769,7 +769,7 @@
         assertEquals("Reload of sub config 1 not detected", 1, config
                 .getInt("xmlReload1"));
     }
-    
+
     /**
      * Tests a combined configuration that is contained in another combined
      * configuration.
@@ -787,6 +787,76 @@
                 .getString("element3[@name]"));
     }
 
+    /* Uncomment when reload locking is in place
+    public void testConcurrentGetAndReload() throws Exception
+    {
+        final int threadCount = 5;
+        final int loopCount = 1000;
+        config.setForceReloadCheck(true);
+        config.setNodeCombiner(new MergeCombiner());
+        final XMLConfiguration xml = new XMLConfiguration("configA.xml");
+        xml.setReloadingStrategy(new FileRandomReloadingStrategy());
+        config.addConfiguration(xml);
+        final XMLConfiguration xml2 = new XMLConfiguration("configB.xml");
+        xml2.setReloadingStrategy(new FileRandomReloadingStrategy());
+        config.addConfiguration(xml2);
+        config.setExpressionEngine(new XPathExpressionEngine());
+
+        assertEquals(config.getString("/property[@name='config']/@value"), "100");
+
+        Thread testThreads[] = new Thread[threadCount];
+        int failures[] = new int[threadCount];
+
+        for (int i = 0; i < testThreads.length; ++i)
+        {
+            testThreads[i] = new ReloadThread(config, failures, i, loopCount);
+            testThreads[i].start();
+        }
+
+        int totalFailures = 0;
+        for (int i = 0; i < testThreads.length; ++i)
+        {
+            testThreads[i].join();
+            totalFailures += failures[i];
+        }
+        assertTrue(totalFailures + " failures Occurred", totalFailures == 0);
+    }
+
+    private class ReloadThread extends Thread
+    {
+        CombinedConfiguration combined;
+        int[] failures;
+        int index;
+        int count;
+
+        ReloadThread(CombinedConfiguration config, int[] failures, int index, int count)
+        {
+            combined = config;
+            this.failures = failures;
+            this.index = index;
+            this.count = count;
+        }
+        public void run()
+        {
+            failures[index] = 0;
+            for (int i = 0; i < count; i++)
+            {
+                try
+                {
+                    String value = combined.getString("/property[@name='config']/@value");
+                    if (value == null || !value.equals("100"))
+                    {
+                        ++failures[index];
+                    }
+                }
+                catch (Exception ex)
+                {
+                    ++failures[index];
+                }
+            }
+        }
+    } */
+
     /**
      * Helper method for writing a file. The file is also added to a list and
      * will be deleted in teadDown() automatically.
@@ -839,7 +909,6 @@
      * Writes a file for testing reload operations.
      *
      * @param name the name of the reload test file
-     * @param content the content of the file
      * @param value the value of the reload test property
      * @return the file that was written
      * @throws IOException if an error occurs

Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2001.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2001.xml?rev=823969&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2001.xml (added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2001.xml Sat Oct 10 22:17:01 2009
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<configuration
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:noNamespaceSchemaLocation="http://commons.apache.org/testMultiConfiguration.xsd">
+  <colors>
+    <undefined>This will throw a schema exception</undefined>
+  </colors>
+  <buttons>
+    <name>OK-1,Cancel-2,Help-3</name>
+  </buttons>
+  <numberFormat pattern="###\,###.##"/>
+</configuration>
\ No newline at end of file

Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2002.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2002.xml?rev=823969&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2002.xml (added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiConfiguration_2002.xml Sat Oct 10 22:17:01 2009
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<configuration
+           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+           xsi:noNamespaceSchemaLocation="http://commons.apache.org/testMultiConfiguration.xsd">
+  <colors>
+    <background>#2222222</background>
+    <text>#000000</text>
+    <header>#222222</header>
+    <link normal="#020202" visited="#202020"/>
+    <default>${colors.header3}</default>
+  </colors>
+  <rowsPerPage>25</rowsPerPage>
+  <buttons>
+    <name>OK-2,Cancel-2,Help-2</name>
+  </buttons>
+  <numberFormat pattern="###\,###.##"/>
+</configuration>
\ No newline at end of file

Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder2.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder2.xml?rev=823969&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder2.xml (added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder2.xml Sat Oct 10 22:17:01 2009
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!-- Test configuration definition file that demonstrates complex initialization -->
+<configuration>
+  <header>
+    <result delimiterParsingDisabled="true" forceReloadCheck="true" loggerName="TestLogger"
+            config-class="org.apache.commons.configuration2.DynamicCombinedConfiguration"
+            keyPattern="$${sys:Id}">
+      <nodeCombiner config-class="org.apache.commons.configuration2.tree.MergeCombiner"/>
+      <expressionEngine
+          config-class="org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine"/>
+    </result>
+    <entity-resolver catalogFiles="catalog.xml"/>
+    <providers>
+      <provider config-tag="multifile"
+         config-class="org.apache.commons.configuration2.DefaultConfigurationBuilder$FileConfigurationProvider"
+         configurationClass="org.apache.commons.configuration2.MultiFileHierarchicalConfiguration"/>
+    </providers>
+  </header>
+  <override>
+    <multifile filePattern="testMultiConfiguration_$$${sys:Id}.xml"
+               config-name="clientConfig" delimiterParsingDisabled="true" schemaValidation="true">
+       <expressionEngine
+          config-class="org.apache.commons.configuration2.expr.xpath.XPathExpressionEngine"/>
+       <reloadingStrategy refreshDelay="500"
+          config-class="org.apache.commons.configuration2.reloading.FileChangedReloadingStrategy"/>
+    </multifile>
+    <xml fileName="testMultiConfiguration_default.xml"
+         config-name="defaultConfig" delimiterParsingDisabled="true" schemaValidation="true">
+      <expressionEngine
+          config-class="org.apache.commons.configuration2.expr.xpath.XPathExpressionEngine"/>
+      <reloadingStrategy refreshDelay="500"
+          config-class="org.apache.commons.configuration2.reloading.FileChangedReloadingStrategy"/>
+    </xml>
+  </override>
+</configuration>
\ No newline at end of file

Added: commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder3.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder3.xml?rev=823969&view=auto
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder3.xml (added)
+++ commons/proper/configuration/branches/configuration2_experimental/src/test/resources/testMultiTenentConfigurationBuilder3.xml Sat Oct 10 22:17:01 2009
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!-- Test configuration definition file that demonstrates complex initialization -->
+<configuration>
+  <header>
+    <result delimiterParsingDisabled="true" forceReloadCheck="true" loggerName="TestLogger"
+            config-class="org.apache.commons.configuration2.DynamicCombinedConfiguration"
+            keyPattern="$${sys:Id}">
+      <nodeCombiner config-class="org.apache.commons.configuration2.tree.MergeCombiner"/>
+      <expressionEngine
+          config-class="org.apache.commons.configuration2.tree.xpath.XPathExpressionEngine"/>
+    </result>
+    <entity-resolver catalogFiles="catalog.xml"/>
+    <providers>
+      <provider config-tag="multifile"
+         config-class="org.apache.commons.configuration2.DefaultConfigurationBuilder$FileConfigurationProvider"
+         configurationClass="org.apache.commons.configuration2.MultiFileHierarchicalConfiguration"/>
+    </providers>
+  </header>
+  <override>
+    <multifile filePattern="testwrite/testMultiConfiguration_$$${sys:Id}.xml"
+               config-name="clientConfig" delimiterParsingDisabled="true" schemaValidation="true">
+       <expressionEngine
+          config-class="org.apache.commons.configuration2.expr.xpath.XPathExpressionEngine"/>
+       <reloadingStrategy refreshDelay="500"
+          config-class="org.apache.commons.configuration2.reloading.FileChangedReloadingStrategy"/>
+    </multifile>
+    <xml fileName="testMultiConfiguration_default.xml"
+         config-name="defaultConfig" delimiterParsingDisabled="true" schemaValidation="true">
+      <expressionEngine
+          config-class="org.apache.commons.configuration2.expr.xpath.XPathExpressionEngine"/>
+      <reloadingStrategy refreshDelay="500"
+          config-class="org.apache.commons.configuration2.reloading.FileChangedReloadingStrategy"/>
+    </xml>
+  </override>
+</configuration>
\ No newline at end of file

Modified: commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_filesystems.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_filesystems.xml?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_filesystems.xml (original)
+++ commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_filesystems.xml Sat Oct 10 22:17:01 2009
@@ -77,7 +77,7 @@
     </xml>
   </override>
 </configuration>
-]]></source>       
+]]></source>
       </subsection>
       <subsection name="File Options Provider">
         <p>
@@ -95,15 +95,11 @@
       </subsection>
       <subsection name="File Reloading Strategy">
         <p>
-          The <code><a href="../apidocs/org/apache/commons/configuration/reloading/VFSFileMonitorReloadingStrategy.html">VFSFileMonitorReloadingStrategy</a></code>
+          The <code><a href="../apidocs/org/apache/commons/configuration2/reloading/VFSFileChangedReloadingStrategy.html">VFSFileMonitorReloadingStrategy</a></code>
           can be used to cause Configurations accessed via the <code>VFSFileSystem</code> to be
           monitored and reloaded when the files are modified. The example below shows how
           <code>DefaultConfigurationBuilder</code> can be configured to use
-          <code>VFSFileMonitorReloadingStrategy</code>. While each declaration will result in
-          a new reloading strategy object, each instance will share a common <code>FileMonitor</code>.
-          The delay setting controls how often the <code>FileMonitor</code> checks for changes
-          and since there is only a single <code>FileMonitor</code>, only the largest value
-          specified on any <code>VFSFileMonitorReloadingStrategy</code> is used.
+          <code>VFSFileChangedReloadingStrategy</code>.
           In the example below both test.properties and settings.xml would be checked for changes
           once per minute.
         </p>
@@ -117,12 +113,12 @@
   </header>
   <override>
     <properties fileName="test.properties" throwExceptionOnMissing="true">
-      <reloadingStrategy delay="60000"
-        config-class="org.apache.commons.configuration2.reloading.VFSFileMonitorReloadingStrategy"/>
+      <reloadingStrategy refreshDelay="60000"
+        config-class="org.apache.commons.configuration2.reloading.VFSFileChangedReloadingStrategy"/>
     </properties>
     <xml fileName="settings.xml" config-name="xml">
-      <reloadingStrategy
-         config-class="org.apache.commons.configuration2.reloading.VFSFileMonitorReloadingStrategy"/>
+      <reloadingStrategy refreshDelay="60000"
+         config-class="org.apache.commons.configuration2.reloading.VFSFileChangedReloadingStrategy"/>
     </xml>
   </override>
 </configuration>

Modified: commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_multitenant.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_multitenant.xml?rev=823969&r1=823968&r2=823969&view=diff
==============================================================================
--- commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_multitenant.xml (original)
+++ commons/proper/configuration/branches/configuration2_experimental/xdocs/userguide/howto_multitenant.xml Sat Oct 10 22:17:01 2009
@@ -54,6 +54,14 @@
           ReloadingStrategy and listeners will be propogated to each of the
           created configurations.
         </p>
+        <p>
+          When used in a combined configuration it is often acceptable for a file
+          matching a particular pattern to be missing so, by default, most exceptions
+          encountered when loading files are ignored. To change this behavior
+          call setIgnoreException(false) or configure the attribute to false in
+          DefaultConfigurationBuilder's configuration file. If schema validation
+          is enabled validation exceptions will always cause a failure.
+        </p>          
       </subsection>
       <subsection name="DynamicCombinedConfiguration">
         <p>