commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From eli...@apache.org
Subject svn commit: r1366118 [1/2] - in /commons/proper/chain/trunk: ./ apps/cookbook-examples/ apps/cookbook-examples/src/main/java/org/apache/commons/chain2/cookbook/mailreader/ apps/cookbook-examples/src/main/webapp/WEB-INF/ configuration-api/ configuration...
Date Thu, 26 Jul 2012 18:04:59 GMT
Author: elijah
Date: Thu Jul 26 18:04:57 2012
New Revision: 1366118

URL: http://svn.apache.org/viewvc?rev=1366118&view=rev
Log:
CHAIN-72

Refactored configuration module into a facade. We now have two modules - configuration-api which is the
facade that is compiled against and configuration-xml which is an implementation that allows xml based
configuration.

Added:
    commons/proper/chain/trunk/configuration-api/
      - copied from r1365692, commons/proper/chain/trunk/configuration/
    commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/ChainConfigurationException.java
    commons/proper/chain/trunk/xml-configuration/
    commons/proper/chain/trunk/xml-configuration/pom.xml
    commons/proper/chain/trunk/xml-configuration/src/
    commons/proper/chain/trunk/xml-configuration/src/main/
    commons/proper/chain/trunk/xml-configuration/src/main/java/
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigCatalogRule.java
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigDefineRule.java
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigParser.java
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRegisterRule.java
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRuleSet.java
    commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/package-info.java
    commons/proper/chain/trunk/xml-configuration/src/main/resources/
    commons/proper/chain/trunk/xml-configuration/src/test/
    commons/proper/chain/trunk/xml-configuration/src/test/java/
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java   (contents, props changed)
      - copied, changed from r1365692, commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java   (contents, props changed)
      - copied, changed from r1365692, commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/TestChain.java   (props changed)
      - copied unchanged from r1365692, commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/TestChain.java
    commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/TestCommand.java   (props changed)
      - copied unchanged from r1365692, commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/TestCommand.java
    commons/proper/chain/trunk/xml-configuration/src/test/resources/
    commons/proper/chain/trunk/xml-configuration/src/test/resources/org/
    commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/
    commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/
    commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/
    commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/config/
    commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/config/test-config-2.xml
    commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/config/test-config.xml
Removed:
    commons/proper/chain/trunk/configuration/
    commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigCatalogRule.java
    commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigDefineRule.java
    commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigRegisterRule.java
    commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigRuleSet.java
    commons/proper/chain/trunk/configuration-api/src/test/java/org/
    commons/proper/chain/trunk/configuration-api/src/test/resources/org/
Modified:
    commons/proper/chain/trunk/apps/cookbook-examples/pom.xml
    commons/proper/chain/trunk/apps/cookbook-examples/src/main/java/org/apache/commons/chain2/cookbook/mailreader/MailReaderServlet.java
    commons/proper/chain/trunk/apps/cookbook-examples/src/main/webapp/WEB-INF/web.xml
    commons/proper/chain/trunk/configuration-api/pom.xml
    commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigParser.java
    commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/package-info.java
    commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/CatalogFactory.java
    commons/proper/chain/trunk/pom.xml
    commons/proper/chain/trunk/src/changes/changes.xml
    commons/proper/chain/trunk/web/pom.xml
    commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainListener.java
    commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainResources.java
    commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainServlet.java
    commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/WebContext.java   (contents, props changed)
    commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/servlet/ServletWebContext.java   (props changed)

Modified: commons/proper/chain/trunk/apps/cookbook-examples/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/apps/cookbook-examples/pom.xml?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/apps/cookbook-examples/pom.xml (original)
+++ commons/proper/chain/trunk/apps/cookbook-examples/pom.xml Thu Jul 26 18:04:57 2012
@@ -45,6 +45,12 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-chain2-xml-configuration</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-all</artifactId>
       <version>1.8.5</version>
@@ -63,7 +69,7 @@
     <resources>
       <resource>
         <directory>${basedir}/src/main/resources/chain</directory>
-        <targetPath>resources</targetPath>
+        <targetPath>resources/chain</targetPath>
         <includes>
           <include>catalog.xml</include>
         </includes>

Modified: commons/proper/chain/trunk/apps/cookbook-examples/src/main/java/org/apache/commons/chain2/cookbook/mailreader/MailReaderServlet.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/apps/cookbook-examples/src/main/java/org/apache/commons/chain2/cookbook/mailreader/MailReaderServlet.java?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/apps/cookbook-examples/src/main/java/org/apache/commons/chain2/cookbook/mailreader/MailReaderServlet.java (original)
+++ commons/proper/chain/trunk/apps/cookbook-examples/src/main/java/org/apache/commons/chain2/cookbook/mailreader/MailReaderServlet.java Thu Jul 26 18:04:57 2012
@@ -49,8 +49,14 @@ public class MailReaderServlet extends H
         Catalog<String, Object, MailReader> catalog =
                 catalogFactory.getCatalog();
 
+        if (catalog == null) {
+            String msg = String.format("No catalog returned from factory: %s",
+                    catalogFactory.getClass().getName());
+            throw new IllegalArgumentException(msg);
+        }
+
         Command<String, Object, MailReader> profileCheckCmd =
-                catalog.getCommand("LocaleChange");
+                catalog.<Command<String, Object, MailReader>>getCommand("LocaleChange");
 
         profileCheckCmd.execute(context);
     }

Modified: commons/proper/chain/trunk/apps/cookbook-examples/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/apps/cookbook-examples/src/main/webapp/WEB-INF/web.xml?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/apps/cookbook-examples/src/main/webapp/WEB-INF/web.xml (original)
+++ commons/proper/chain/trunk/apps/cookbook-examples/src/main/webapp/WEB-INF/web.xml Thu Jul 26 18:04:57 2012
@@ -24,7 +24,7 @@
   <!-- Commons Chain listener to load catalogs  -->
   <context-param>
     <param-name>org.apache.commons.chain2.CONFIG_CLASS_RESOURCE</param-name>
-    <param-value>chain/catalog.xml</param-value>
+    <param-value>resources/chain/catalog.xml</param-value>
   </context-param>
   <listener>
     <listener-class>org.apache.commons.chain2.web.ChainListener</listener-class>

Modified: commons/proper/chain/trunk/configuration-api/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/configuration-api/pom.xml?rev=1366118&r1=1365692&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/configuration-api/pom.xml (original)
+++ commons/proper/chain/trunk/configuration-api/pom.xml Thu Jul 26 18:04:57 2012
@@ -28,9 +28,9 @@
     <relativePath>../</relativePath>
   </parent>
 
-  <artifactId>commons-chain2-configuration</artifactId>
+  <artifactId>commons-chain2-configuration-api</artifactId>
 
-  <name>Apache Commons Chain :: Configuration</name>
+  <name>Apache Commons Chain :: Configuration API</name>
 
   <dependencies>
     <dependency>
@@ -41,16 +41,17 @@
 
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>commons-digester3</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>${project.groupId}</groupId>
       <artifactId>commons-chain2-core</artifactId>
       <version>${project.parent.version}</version>
       <type>test-jar</type>
       <scope>test</scope>
     </dependency>
+
+  <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+  </dependency>
+
   </dependencies>
 
   <build>

Modified: commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigParser.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigParser.java?rev=1366118&r1=1365692&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigParser.java (original)
+++ commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/ConfigParser.java Thu Jul 26 18:04:57 2012
@@ -17,112 +17,54 @@
 package org.apache.commons.chain2.config;
 
 import org.apache.commons.chain2.Catalog;
-import org.apache.commons.digester3.Digester;
-import org.apache.commons.digester3.RuleSet;
+import org.apache.commons.chain2.ChainConfigurationException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import java.net.URL;
 
 /**
- * <p>Class to parse the contents of an XML configuration file (using
- * Commons Digester) that defines and configures commands and command chains
- * to be registered in a {@link Catalog}.  Advanced users can configure the
- * detailed parsing behavior by configuring the properties of an instance
- * of this class prior to calling the <code>parse()</code> method.  It
- * is legal to call the <code>parse()</code> method more than once, in order
+ * <p>Facade class to abstract the functionality of parsing an arbitrary
+ * configuration file that defines and configures commands and command chains
+ * to be registered in a {@link Catalog}. It is legal to call the
+ * <code>parse()</code> method more than once, in order
  * to parse more than one configuration document.</p>
  *
  * @version $Id$
  */
 public class ConfigParser {
-
-    // ----------------------------------------------------- Instance Variables
-
-    /**
-     * <p>The <code>RuleSet</code> to be used for configuring our Digester
-     * parsing rules.</p>
-     */
-    private RuleSet ruleSet = new ConfigRuleSet();
+    private Log logger = LogFactory.getLog(getClass());
 
     /**
-     * <p>Should Digester use the context class loader?
+     * Constructor for loading a configuration parser with the default settings.
      */
-    private boolean useContextClassLoader = true;
-
-    // ------------------------------------------------------------- Properties
-
-    /**
-     * <p>Return the <code>Digester</code> instance to be used for
-     * parsing, creating one if necessary.</p>
-     * @return A Digester instance.
-     */
-    public Digester getDigester() {
-        Digester digester = new Digester();
-        RuleSet ruleSet = getRuleSet();
-        digester.setNamespaceAware(ruleSet.getNamespaceURI() != null);
-        digester.setUseContextClassLoader(getUseContextClassLoader());
-        digester.setValidating(false);
-        digester.addRuleSet(ruleSet);
-        return (digester);
-    }
-
-    /**
-     * <p>Return the <code>RuleSet</code> to be used for configuring
-     * our <code>Digester</code> parsing rules, creating one if necessary.</p>
-     * @return The RuleSet for configuring a Digester instance.
-     */
-    public RuleSet getRuleSet() {
-        return (ruleSet);
+    public ConfigParser() {
+        logger.info("ConfigParser() instantiated");
     }
 
     /**
-     * <p>Set the <code>RuleSet</code> to be used for configuring
-     * our <code>Digester</code> parsing rules.</p>
-     *
-     * @param ruleSet The new RuleSet to use
+     * Constructor for loading a configuration parser with a specified rule
+     * set class.
+     * @param ruleSet class name as string of the rule set
+     * @param loader class loader to use to create instance of rule set class
      */
-    public void setRuleSet(RuleSet ruleSet) {
-        this.ruleSet = ruleSet;
-    }
-
-    /**
-     * <p>Return the "use context class loader" flag.  If set to
-     * <code>true</code>, Digester will attempt to instantiate new
-     * command and chain instances from the context class loader.</p>
-     * @return <code>true</code> if Digester should use the context class loader.
-     */
-    public boolean getUseContextClassLoader() {
-        return (this.useContextClassLoader);
-    }
-
-    /**
-     * <p>Set the "use context class loader" flag.</p>
-     *
-     * @param useContextClassLoader The new flag value
-     */
-    public void setUseContextClassLoader(boolean useContextClassLoader) {
-        this.useContextClassLoader = useContextClassLoader;
+    public ConfigParser(String ruleSet, ClassLoader loader) {
+        logger.info("ConfigParser(ruleSet, loader) instantiated");
     }
 
     // --------------------------------------------------------- Public Methods
 
     /**
-     * <p>Parse the XML document at the specified URL using the configured
-     * <code>RuleSet</code>, registering catalogs with nested chains and
+     * <p>Parse the configuration at the specified URL using the configured
+     * rule set, registering catalogs with nested chains and
      * commands as they are encountered.  Use this method <strong>only</strong>
      * if you have included one or more <code>factory</code> elements in your
      * configuration resource.</p>
      *
-     * @param url <code>URL</code> of the XML document to be parsed
-     *
-     * @exception Exception if a parsing error occurs
+     * @param url <code>URL</code> of the configuration document to be parsed
+     * @exception ChainConfigurationException if a parsing error occurs
      */
-    public void parse(URL url) throws Exception {
-        // Prepare our Digester instance
-        Digester digester = getDigester();
-        digester.clear();
-
-        // Parse the configuration document
-        digester.parse(url);
+    public void parse(URL url) throws ChainConfigurationException {
+        logger.info("Parsing configuration - doing nothing");
     }
-
 }

Modified: commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/package-info.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/package-info.java?rev=1366118&r1=1365692&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/package-info.java (original)
+++ commons/proper/chain/trunk/configuration-api/src/main/java/org/apache/commons/chain2/config/package-info.java Thu Jul 26 18:04:57 2012
@@ -16,7 +16,7 @@
  */
 
 /**
- * Optional package for configuring command chains in a catalog
- * (using Digester) from an XML configuration file.
+ * Compile-time only API package that acts as a facade. This package provides
+ * an implementation used for compile only that provides no functionality.
  */
 package org.apache.commons.chain2.config;

Modified: commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/CatalogFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/CatalogFactory.java?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/CatalogFactory.java (original)
+++ commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/CatalogFactory.java Thu Jul 26 18:04:57 2012
@@ -120,14 +120,14 @@ public abstract class CatalogFactory<K, 
     public <CMD extends Command<K, V, C>> CMD getCommand(String commandID) {
         String commandName = commandID;
         String catalogName = null;
-        Catalog<K, V, C> catalog = null;
+        Catalog<K, V, C> catalog;
 
         if (commandID != null) {
             int splitPos = commandID.indexOf(DELIMITER);
             if (splitPos != -1) {
                 catalogName = commandID.substring(0, splitPos);
                 commandName = commandID.substring(splitPos + DELIMITER.length());
-                if (commandName.indexOf(DELIMITER) != -1) {
+                if (commandName.contains(DELIMITER)) {
                     throw new IllegalArgumentException("commandID [" +
                                                        commandID +
                                                        "] has too many delimiters (reserved for future use)");
@@ -179,7 +179,7 @@ public abstract class CatalogFactory<K, 
      * @return the per-application singleton instance of {@link CatalogFactory}
      */
     public static <K, V, C extends Map<K, V>> CatalogFactory<K, V, C> getInstance() {
-        CatalogFactory<?, ?, ? extends Map<?, ?>> factory = null;
+        CatalogFactory<?, ?, ? extends Map<?, ?>> factory;
         ClassLoader cl = getClassLoader();
         synchronized (factories) {
             factory = factories.get(cl);
@@ -224,4 +224,20 @@ public abstract class CatalogFactory<K, 
         return cl;
     }
 
+    /**
+     * Check to see if we have an implementation of a valid configuration
+     * parsing class loaded at runtime. If not, we throw a
+     * ChainConfigurationException.
+     */
+    public static void checkForValidConfigurationModule() {
+        try {
+            ClassLoader cl = getClassLoader();
+            cl.loadClass("org.apache.commons.chain2.config.ConfigParser");
+        } catch (ClassNotFoundException e) {
+            String msg = "Couldn't not find a configuration implementation. " +
+                    "Load a chain configuration module such as xml-configuration " +
+                    "into the classpath and try again.";
+            throw new ChainConfigurationException(msg, e);
+        }
+    }
 }

Added: commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/ChainConfigurationException.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/ChainConfigurationException.java?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/ChainConfigurationException.java (added)
+++ commons/proper/chain/trunk/core/src/main/java/org/apache/commons/chain2/ChainConfigurationException.java Thu Jul 26 18:04:57 2012
@@ -0,0 +1,45 @@
+/*
+ * 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.chain2;
+
+/**
+ * Runtime exception representing an exception that occurred during a
+ * configuration phase within a chain component.
+ *
+ * @version $Id:  $
+ */
+public class ChainConfigurationException extends RuntimeException {
+    public ChainConfigurationException() {
+    }
+
+    public ChainConfigurationException(String message) {
+        super(message);
+    }
+
+    public ChainConfigurationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ChainConfigurationException(Throwable cause) {
+        super(cause);
+    }
+
+    public ChainConfigurationException(String message, Throwable cause,
+            boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}

Modified: commons/proper/chain/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/pom.xml?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/pom.xml (original)
+++ commons/proper/chain/trunk/pom.xml Thu Jul 26 18:04:57 2012
@@ -41,7 +41,8 @@
   <modules>
     <module>build-tools</module>
     <module>core</module>
-    <module>configuration</module>
+    <module>configuration-api</module>
+    <module>xml-configuration</module>
     <module>web</module>
     <module>apps</module>
     <module>dist</module>

Modified: commons/proper/chain/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/src/changes/changes.xml?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/src/changes/changes.xml (original)
+++ commons/proper/chain/trunk/src/changes/changes.xml Thu Jul 26 18:04:57 2012
@@ -41,6 +41,9 @@ The <action> type attribute can be add,u
 
   <body>
     <release version="2.0" description="Major release">
+        <action dev="elijah" type="update" issue="CHAIN-72">
+            Refactored configuration module to a facade that supports multiple implementations.
+        </action>
       <action dev="elijah" type="fix" issue="CHAIN-47">
           WebContext, ServletWebContext are now interfaces
       </action>

Modified: commons/proper/chain/trunk/web/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/web/pom.xml?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/web/pom.xml (original)
+++ commons/proper/chain/trunk/web/pom.xml Thu Jul 26 18:04:57 2012
@@ -46,14 +46,16 @@
 
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>commons-chain2-configuration</artifactId>
+      <artifactId>commons-chain2-configuration-api</artifactId>
       <version>${project.parent.version}</version>
+      <scope>provided</scope>
     </dependency>
 
     <dependency>
       <groupId>${project.groupId}</groupId>
-      <artifactId>commons-digester3</artifactId>
-      <scope>provided</scope>
+      <artifactId>commons-chain2-xml-configuration</artifactId>
+      <version>${project.parent.version}</version>
+      <scope>test</scope>
     </dependency>
 
     <dependency>

Modified: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainListener.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainListener.java?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainListener.java (original)
+++ commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainListener.java Thu Jul 26 18:04:57 2012
@@ -21,7 +21,6 @@ import org.apache.commons.chain2.Catalog
 import org.apache.commons.chain2.config.ConfigParser;
 import org.apache.commons.chain2.impl.CatalogBase;
 import org.apache.commons.chain2.web.servlet.ServletWebContext;
-import org.apache.commons.digester3.RuleSet;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -93,6 +92,9 @@ import java.util.Set;
  * @version $Id$
  */
 public class ChainListener implements ServletContextListener {
+    {
+        CatalogFactory.checkForValidConfigurationModule();
+    }
 
     // ------------------------------------------------------ Manifest Constants
 
@@ -179,22 +181,12 @@ public class ChainListener implements Se
         }
 
         // Construct the configuration resource parser we will use
-        ConfigParser parser = new ConfigParser();
-        if (ruleSet != null) {
-            try {
-                ClassLoader loader =
-                    Thread.currentThread().getContextClassLoader();
-                if (loader == null) {
-                    loader = this.getClass().getClassLoader();
-                }
-                Class<?> clazz = loader.loadClass(ruleSet);
-                parser.setRuleSet((RuleSet) clazz.newInstance());
-            } catch (Exception e) {
-                throw new RuntimeException("Exception initalizing RuleSet '"
-                                           + ruleSet + "' instance: "
-                                           + e.getMessage());
-            }
-        }
+        ClassLoader cl = Thread.currentThread().getContextClassLoader() == null ?
+                this.getClass().getClassLoader() :
+                Thread.currentThread().getContextClassLoader();
+
+        ConfigParser parser = ruleSet == null ?
+                new ConfigParser() : new ConfigParser(ruleSet, cl);
 
         // Parse the resources specified in our init parameters (if any)
         if (attr == null) {

Modified: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainResources.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainResources.java?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainResources.java (original)
+++ commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainResources.java Thu Jul 26 18:04:57 2012
@@ -64,12 +64,12 @@ final class ChainResources {
         String[] paths = getResourcePaths(resources);
         String path = null;
         try {
-            for (int i = 0; i < paths.length; i++) {
-                path = paths[i];
+            for (String path1 : paths) {
+                path = path1;
                 URL url = loader.getResource(path);
                 if (url == null) {
                     throw new IllegalStateException
-                        ("Missing chain config resource '" + path + "'");
+                            ("Missing chain config resource '" + path + "'");
                 }
                 if (log.isDebugEnabled()) {
                     log.debug("Loading chain config resource '" + path + "'");
@@ -100,12 +100,12 @@ final class ChainResources {
         String[] paths = getResourcePaths(resources);
         String path = null;
         try {
-            for (int i = 0; i < paths.length; i++) {
-                path = paths[i];
+            for (String path1 : paths) {
+                path = path1;
                 URL url = context.getResource(path);
                 if (url == null) {
                     throw new IllegalStateException
-                        ("Missing chain config resource '" + path + "'");
+                            ("Missing chain config resource '" + path + "'");
                 }
                 if (log.isDebugEnabled()) {
                     log.debug("Loading chain config resource '" + path + "'");

Modified: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainServlet.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainServlet.java?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainServlet.java (original)
+++ commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/ChainServlet.java Thu Jul 26 18:04:57 2012
@@ -21,7 +21,6 @@ import org.apache.commons.chain2.Catalog
 import org.apache.commons.chain2.config.ConfigParser;
 import org.apache.commons.chain2.impl.CatalogBase;
 import org.apache.commons.chain2.web.servlet.ServletWebContext;
-import org.apache.commons.digester3.RuleSet;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -91,6 +90,9 @@ import java.io.IOException;
  * @version $Id$
  */
 public class ChainServlet extends HttpServlet {
+    {
+        CatalogFactory.checkForValidConfigurationModule();
+    }
 
     // ------------------------------------------------------ Manifest Constants
 
@@ -179,21 +181,12 @@ public class ChainServlet extends HttpSe
         }
 
         // Construct the configuration resource parser we will use
-        ConfigParser parser = new ConfigParser();
-        if (ruleSet != null) {
-            try {
-                ClassLoader loader =
-                    Thread.currentThread().getContextClassLoader();
-                if (loader == null) {
-                    loader = this.getClass().getClassLoader();
-                }
-                Class<?> clazz = loader.loadClass(ruleSet);
-                parser.setRuleSet((RuleSet) clazz.newInstance());
-            } catch (Exception e) {
-                throw new ServletException("Exception initalizing RuleSet '"
-                                           + ruleSet + "' instance", e);
-            }
-        }
+        ClassLoader cl = Thread.currentThread().getContextClassLoader() == null ?
+                this.getClass().getClassLoader() :
+                Thread.currentThread().getContextClassLoader();
+
+        ConfigParser parser = ruleSet == null ?
+                new ConfigParser() : new ConfigParser(ruleSet, cl);
 
         // Parse the resources specified in our init parameters (if any)
         if (attr == null) {

Modified: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/WebContext.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/WebContext.java?rev=1366118&r1=1366117&r2=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/WebContext.java (original)
+++ commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/WebContext.java Thu Jul 26 18:04:57 2012
@@ -25,7 +25,7 @@ import java.util.Map;
 
 /**
  *
- * @version $Id: $
+ * @version $Id$
  */
 public interface WebContext<K, V> extends Context<K, V>, Serializable {
     /**

Propchange: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/WebContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/WebContext.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/servlet/ServletWebContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/chain/trunk/web/src/main/java/org/apache/commons/chain2/web/servlet/ServletWebContext.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: commons/proper/chain/trunk/xml-configuration/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/pom.xml?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/pom.xml (added)
+++ commons/proper/chain/trunk/xml-configuration/pom.xml Thu Jul 26 18:04:57 2012
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>commons-chain-parent</artifactId>
+        <groupId>org.apache.commons</groupId>
+        <version>2.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.commons</groupId>
+    <artifactId>commons-chain2-xml-configuration</artifactId>
+    <name>Apache Commons Chain :: XML Configuration</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>commons-chain2-core</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>commons-digester3</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>commons-chain2-core</artifactId>
+            <version>${project.parent.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${basedir}/../</directory>
+                <targetPath>META-INF</targetPath>
+                <includes>
+                    <include>NOTICE.txt</include>
+                    <include>LICENSE.txt</include>
+                </includes>
+            </resource>
+        </resources>
+    </build>
+</project>
\ No newline at end of file

Added: commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigCatalogRule.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigCatalogRule.java?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigCatalogRule.java (added)
+++ commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigCatalogRule.java Thu Jul 26 18:04:57 2012
@@ -0,0 +1,121 @@
+/*
+ * 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.chain2.config;
+
+import org.apache.commons.chain2.Catalog;
+import org.apache.commons.chain2.CatalogFactory;
+import org.apache.commons.digester3.Rule;
+import org.xml.sax.Attributes;
+
+import java.util.Map;
+
+/**
+ * <p>Digester rule that will cause the top-most element on the Digester
+ * stack (if it is a {@link org.apache.commons.chain2.Catalog} to be registered with the
+ * {@link org.apache.commons.chain2.CatalogFactory} instance for our application.  If the attribute
+ * specified to our constructor has a value, that will be used as the name
+ * under which to register this {@link org.apache.commons.chain2.Catalog}.  Otherwise, this will
+ * become the default {@link org.apache.commons.chain2.Catalog} for this application.</p>
+ *
+ * @version $Id: ConfigCatalogRule.java 1363305 2012-07-19 11:42:53Z simonetripodi $
+ */
+class ConfigCatalogRule extends Rule {
+
+    // ----------------------------------------------------------- Constructors
+
+    /**
+     * <p>Construct a new instance of this rule that looks for an attribute
+     * with the specified name.</p>
+     *
+     * @param nameAttribute Name of the attribute containing the name under
+     *  which this command should be registered
+     * @param catalogClass Name of the implementation class for newly
+     *  created {@link org.apache.commons.chain2.Catalog} instances
+     */
+    public ConfigCatalogRule(String nameAttribute, String catalogClass) {
+        super();
+        this.nameAttribute = nameAttribute;
+        this.catalogClass = catalogClass;
+    }
+
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * <p>The fully qualified class name of a {@link org.apache.commons.chain2.Catalog} class to use for
+     * instantiating new instances.</p>
+     */
+    private String catalogClass = null;
+
+    /**
+     * <p>The name of the attribute under which we can retrieve the name
+     * this catalog should be registered with (if any).</p>
+     */
+    private String nameAttribute = null;
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * <p>Retrieve or create a {@link org.apache.commons.chain2.Catalog} with the name specified by
+     * the <code>nameAttribute</code> attribute, or the default {@link org.apache.commons.chain2.Catalog}
+     * if there is no such attribute defined.  Push it onto the top of the
+     * stack.</p>
+     *
+     * @param namespace the namespace URI of the matching element, or an
+     *   empty string if the parser is not namespace aware or the element has
+     *   no namespace
+     * @param name the local name if the parser is namespace aware, or just
+     *   the element name otherwise
+     * @param attributes The attribute list of this element
+     */
+    @Override
+    public void begin(String namespace, String name, Attributes attributes) throws Exception {
+        // Retrieve any current Catalog with the specified name
+        Catalog<Object, Object, Map<Object, Object>> catalog;
+        CatalogFactory<Object, Object, Map<Object, Object>> factory = CatalogFactory.getInstance();
+        String nameValue = attributes.getValue(nameAttribute);
+        if (nameValue == null) {
+            catalog = factory.getCatalog();
+        } else {
+            catalog = factory.getCatalog(nameValue);
+        }
+
+        // Create and register a new Catalog instance if necessary
+        if (catalog == null) {
+            Class<?> clazz = getDigester().getClassLoader().loadClass(catalogClass);
+
+            /* Convert catalog pulled from digester to default generic signature
+             * with the assumption that the Catalog returned from digester will
+             * comply with the the historic chain contract. */
+            @SuppressWarnings("unchecked")
+            Catalog<Object, Object, Map<Object, Object>> digesterCatalog =
+                    (Catalog<Object, Object, Map<Object, Object>>) clazz.newInstance();
+
+            catalog = digesterCatalog;
+
+            if (nameValue == null) {
+
+                factory.setCatalog(catalog);
+            } else {
+                factory.addCatalog(nameValue, catalog);
+            }
+        }
+
+        // Push this Catalog onto the top of the stack
+        getDigester().push(catalog);
+    }
+
+}

Added: commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigDefineRule.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigDefineRule.java?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigDefineRule.java (added)
+++ commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigDefineRule.java Thu Jul 26 18:04:57 2012
@@ -0,0 +1,90 @@
+/*
+ * 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.chain2.config;
+
+import org.apache.commons.digester3.Rule;
+import org.xml.sax.Attributes;
+
+/**
+ * <p>Digester rule that will dynamically register a new set of rules
+ * for a specified element name and default implementation class.  This
+ * allows "alias" elements to be created for {@link org.apache.commons.chain2.Chain}
+ * and {@link org.apache.commons.chain2.Command}
+ * implementation classes that are commonly used.  Besides factoring out
+ * the class names to make changes easier, this also makes configuration
+ * files <strong>much</strong> easier to read and write.</p>
+ *
+ * @version $Id: ConfigDefineRule.java 1363305 2012-07-19 11:42:53Z simonetripodi $
+ */
+class ConfigDefineRule extends Rule {
+
+    // ----------------------------------------------------------- Constructors
+
+    /**
+     * <p>Construct a new instance of this rule that will in turn
+     * dynamically register appropriate rules for a new alias element.</p>
+     *
+     * @param nameAttribute Name of the attribute containing the name
+     *  of the new element for which rules should generated
+     * @param classAttribute Name of the attribute containing the
+     *  implementation class for the new chain or command
+     */
+    public ConfigDefineRule(String nameAttribute, String classAttribute) {
+        super();
+        this.nameAttribute = nameAttribute;
+        this.classAttribute = classAttribute;
+    }
+
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * <p>The name of the attribute under which we can retrieve the
+     * fully qualified class name of the implementation class for this
+     * new element.</p>
+     */
+    private String classAttribute = null;
+
+    /**
+     * <p>The name of the attribute under which we can retrieve the name
+     * this element for which rules should be created.</p>
+     */
+    private String nameAttribute = null;
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * <p>Register new rules for the specified name and class.</p>
+     *
+     * @param namespace the namespace URI of the matching element, or an
+     *   empty string if the parser is not namespace aware or the element has
+     *   no namespace
+     * @param name the local name if the parser is namespace aware, or just
+     *   the element name otherwise
+     * @param attributes The attribute list of this element
+     */
+    public void begin(String namespace, String name, Attributes attributes) throws Exception {
+        // Extract the actual name and implementation class to use
+        String nameValue = attributes.getValue(nameAttribute);
+        String classValue = attributes.getValue(classAttribute);
+
+        // Add rules for this new element
+        getDigester().addObjectCreate("*/" + nameValue, classValue);
+        getDigester().addSetProperties("*/" + nameValue);
+        getDigester().addRule("*/" + nameValue, new ConfigRegisterRule(nameAttribute));
+    }
+
+}

Added: commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigParser.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigParser.java?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigParser.java (added)
+++ commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigParser.java Thu Jul 26 18:04:57 2012
@@ -0,0 +1,159 @@
+/*
+ * 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.chain2.config;
+
+import org.apache.commons.chain2.ChainConfigurationException;
+import org.apache.commons.digester3.Digester;
+import org.apache.commons.digester3.RuleSet;
+
+import java.net.URL;
+
+/**
+ * <p>Class to parse the contents of an XML configuration file (using
+ * Commons Digester) that defines and configures commands and command chains
+ * to be registered in a {@link org.apache.commons.chain2.Catalog}.  Advanced users can configure the
+ * detailed parsing behavior by configuring the properties of an instance
+ * of this class prior to calling the <code>parse()</code> method.  It
+ * is legal to call the <code>parse()</code> method more than once, in order
+ * to parse more than one configuration document.</p>
+ *
+ * @version $Id: ConfigParser.java 1364104 2012-07-21 14:25:54Z elijah $
+ */
+public class ConfigParser {
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * <p>The <code>RuleSet</code> to be used for configuring our Digester
+     * parsing rules.</p>
+     */
+    private RuleSet ruleSet = new ConfigRuleSet();
+
+    /**
+     * <p>Should Digester use the context class loader?
+     */
+    private boolean useContextClassLoader = true;
+
+    // ------------------------------------------------------------- Constructor
+
+    public ConfigParser() {
+    }
+
+    public ConfigParser(String ruleSet, ClassLoader loader) {
+        if (ruleSet == null) {
+            throw new IllegalArgumentException("ConfigParser can't be " +
+                    "instantiated with a null ruleSet class name");
+        }
+        if (loader == null) {
+            throw new IllegalArgumentException("ConfigParser can't be " +
+                    "instantiated with a null class loader reference");
+        }
+
+        try {
+            Class<?> clazz = loader.loadClass(ruleSet);
+            setRuleSet((RuleSet) clazz.newInstance());
+        } catch (Exception e) {
+            throw new RuntimeException("Exception initializing RuleSet '"
+                    + ruleSet + "' instance: "
+                    + e.getMessage());
+        }
+    }
+
+    // ------------------------------------------------------------- Properties
+
+    /**
+     * <p>Return the <code>Digester</code> instance to be used for
+     * parsing, creating one if necessary.</p>
+     * @return A Digester instance.
+     */
+    public Digester getDigester() {
+        Digester digester = new Digester();
+        RuleSet ruleSet = getRuleSet();
+        digester.setNamespaceAware(ruleSet.getNamespaceURI() != null);
+        digester.setUseContextClassLoader(getUseContextClassLoader());
+        digester.setValidating(false);
+        digester.addRuleSet(ruleSet);
+        return (digester);
+    }
+
+    /**
+     * <p>Return the <code>RuleSet</code> to be used for configuring
+     * our <code>Digester</code> parsing rules, creating one if necessary.</p>
+     * @return The RuleSet for configuring a Digester instance.
+     */
+    public RuleSet getRuleSet() {
+        return (ruleSet);
+    }
+
+    /**
+     * <p>Set the <code>RuleSet</code> to be used for configuring
+     * our <code>Digester</code> parsing rules.</p>
+     *
+     * @param ruleSet The new RuleSet to use
+     */
+    public void setRuleSet(RuleSet ruleSet) {
+        this.ruleSet = ruleSet;
+    }
+
+    /**
+     * <p>Return the "use context class loader" flag.  If set to
+     * <code>true</code>, Digester will attempt to instantiate new
+     * command and chain instances from the context class loader.</p>
+     * @return <code>true</code> if Digester should use the context class loader.
+     */
+    public boolean getUseContextClassLoader() {
+        return (this.useContextClassLoader);
+    }
+
+    /**
+     * <p>Set the "use context class loader" flag.</p>
+     *
+     * @param useContextClassLoader The new flag value
+     */
+    public void setUseContextClassLoader(boolean useContextClassLoader) {
+        this.useContextClassLoader = useContextClassLoader;
+    }
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * <p>Parse the XML document at the specified URL using the configured
+     * <code>RuleSet</code>, registering catalogs with nested chains and
+     * commands as they are encountered.  Use this method <strong>only</strong>
+     * if you have included one or more <code>factory</code> elements in your
+     * configuration resource.</p>
+     *
+     * @param url <code>URL</code> of the XML document to be parsed
+     *
+     * @exception ChainConfigurationException if a parsing error occurs
+     */
+    public void parse(URL url) throws ChainConfigurationException {
+        // Prepare our Digester instance
+        Digester digester = getDigester();
+        digester.clear();
+
+        // Parse the configuration document
+        try {
+            digester.parse(url);
+        } catch (Exception e) {
+            String msg = String.format(
+                    "Error parsing digestor configuration at url: %s",
+                    url);
+            throw new ChainConfigurationException(msg, e);
+        }
+    }
+
+}

Added: commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRegisterRule.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRegisterRule.java?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRegisterRule.java (added)
+++ commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRegisterRule.java Thu Jul 26 18:04:57 2012
@@ -0,0 +1,112 @@
+/*
+ * 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.chain2.config;
+
+import org.apache.commons.chain2.Catalog;
+import org.apache.commons.chain2.Chain;
+import org.apache.commons.chain2.Command;
+import org.apache.commons.digester3.Rule;
+import org.xml.sax.Attributes;
+
+import java.util.Map;
+
+/**
+ * <p>Digester rule that will cause the top-most element on the Digester
+ * stack (if it is a {@link org.apache.commons.chain2.Command} to be registered with the next-to-top
+ * element on the Digester stack (if it is a {@link org.apache.commons.chain2.Catalog} or {@link org.apache.commons.chain2.Chain}).
+ * To be registered with a {@link org.apache.commons.chain2.Catalog}, the top-most element must contain
+ * a value for the specified attribute that contains the name under which
+ * it should be registered.</p>
+ *
+ * @version $Id: ConfigRegisterRule.java 1363305 2012-07-19 11:42:53Z simonetripodi $
+ */
+class ConfigRegisterRule extends Rule {
+
+    // ----------------------------------------------------------- Constructors
+
+    /**
+     * <p>Construct a new instance of this rule that looks for an attribute
+     * with the specified name.</p>
+     *
+     * @param nameAttribute Name of the attribute containing the name under
+     *  which this command should be registered
+     */
+    public ConfigRegisterRule(String nameAttribute) {
+        super();
+        this.nameAttribute = nameAttribute;
+    }
+
+    // ----------------------------------------------------- Instance Variables
+
+    /**
+     * <p>The name of the attribute under which we can retrieve the name
+     * this command should be registered with.</p>
+     */
+    private String nameAttribute = null;
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * <p>Register the top {@link org.apache.commons.chain2.Command} if appropriate.</p>
+     *
+     * @param namespace the namespace URI of the matching element, or an
+     *   empty string if the parser is not namespace aware or the element has
+     *   no namespace
+     * @param name the local name if the parser is namespace aware, or just
+     *   the element name otherwise
+     * @param attributes The attribute list of this element
+     */
+    @Override
+    public void begin(String namespace, String name, Attributes attributes) throws Exception {
+        // Is the top object a Command?
+        Object top = getDigester().peek(0);
+        if ((top == null)
+            || !(top instanceof Command)) {
+            return;
+        }
+
+        /* All commands can consume a generic context. Here we depend on
+         * the configuration being correct because the rule binding is
+         * dynamic. */
+        Command<Object, Object, Map<Object, Object>> command =
+                (Command<Object, Object, Map<Object, Object>>) top;
+
+        // Is the next object a Catalog or a Chain?
+        Object next = getDigester().peek(1);
+        if (next == null) {
+            return;
+        }
+
+        // Register the top element appropriately
+        if (next instanceof Catalog) {
+            String nameValue = attributes.getValue(nameAttribute);
+            if (nameValue != null) {
+                /* We are dynamically building a catalog and assigning
+                 * generics to the most base types possible. */
+                Catalog<Object, Object, Map<Object, Object>> catalog =
+                        (Catalog<Object, Object, Map<Object, Object>>) next;
+                catalog.addCommand(nameValue, command);
+            }
+        } else if (next instanceof Chain) {
+            /* Like above - the chain is being dynamically generated,
+             * so we can add a generic context signature at compile-time. */
+            Chain<Object, Object, Map<Object, Object>> chain = (Chain<Object, Object, Map<Object, Object>>) next;
+            chain.addCommand(command);
+        }
+    }
+
+}

Added: commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRuleSet.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRuleSet.java?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRuleSet.java (added)
+++ commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/ConfigRuleSet.java Thu Jul 26 18:04:57 2012
@@ -0,0 +1,279 @@
+/*
+ * 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.chain2.config;
+
+import org.apache.commons.digester3.Digester;
+import org.apache.commons.digester3.RuleSetBase;
+
+/**
+ * <p>Digester <code>RuleSet</code> for configuring <em>Chain of
+ * Responsibility</em> command chains, and adding them to an appropriate
+ * {@link org.apache.commons.chain2.Catalog}.  The following properties
+ * may be configured prior to executing the <code>addRuleInstance()</code>
+ * method in order to influence the rules that get added, with default
+ * values in square brackets:</p>
+ * <ul>
+ * <li><strong>catalogClass</strong> -- Fully qualified name of the
+ *     implementation class used to create new
+ *     {@link org.apache.commons.chain2.Catalog} instances.
+ *     If not specified, the default value is
+ *     <code>org.apache.commons.chain2.impl.CatalogBsae</code>.</li>
+ * <li><strong>catalogElement</strong> -- Name of the XML element representing
+ *     the addition of a {@link org.apache.commons.chain2.Catalog}.
+ *     Any such catalog that is created will be registered with the
+ *     {@link org.apache.commons.chain2.CatalogFactory} instance for our
+ *     application, under the name specified by the <code>nameAttribute</code>
+ *     attribute (if present), or as the default {@link org.apache.commons.chain2.Catalog}.
+ *     If not specified, the default value is <code>catalog</code>.</li>
+ * <li><strong>chainClass</strong> -- Fully qualified name of the implementation
+ *     class used to create new {@link org.apache.commons.chain2.Chain} instances.
+ *     If not specified, the default value is
+ *     <code>org.apache.commons.chain2.impl.ChainBase</code>.
+ *     </li>
+ * <li><strong>chainElement</strong> -- Name of the XML element representing
+ *     the addition of a {@link org.apache.commons.chain2.Chain}.  A chain
+ *     element has the same functionality as a command element, except that
+ *     it defaults the implementation class to
+ *     <code>org.apache.commons.chain2.impl.ChainBase</code>.  [chain]</li>
+ * <li><strong>classAttribute</strong> -- Attribute on a chain (optional) or
+ *     command (required) element that specifies the fully qualified class
+ *     name of the implementation class that should be instantiated.
+ *     [className]</li>
+ * <li><strong>commandElement</strong> -- Name of the XML element
+ *     representing the addition of a {@link org.apache.commons.chain2.Command}.
+ *     An implementation class name must be provided on the attribute named by the
+ *     <code>classAttribute</code> property.  [command]</li>
+ * <li><strong>defineElement</strong> -- Name of the XML element
+ *     that associates the element specified by the <code>nameAttribute</code>
+ *     attributes with a {@link org.apache.commons.chain2.Command} or
+ *     {@link org.apache.commons.chain2.Chain} implementation class
+ *     named by the <code>classAttribute</code> attribute.  [define]</li>
+ * <li><strong>nameAttribute</strong> -- Attribute on an outermost chain or
+ *     command element that will be used to register this command with the
+ *     associated {@link org.apache.commons.chain2.Catalog} instance on the stack.
+ *     [name]</li>
+ * <li><strong>namespaceURI</strong> -- The XML namespace URI with which these
+ *     rules will be associated, or <code>null</code> for no namespace.
+ *     [null]</li>
+ * </ul>
+ *
+ * @version $Id: ConfigRuleSet.java 1363305 2012-07-19 11:42:53Z simonetripodi $
+ */
+public class ConfigRuleSet extends RuleSetBase {
+
+    // ----------------------------------------------------- Instance Variables
+
+    private String catalogClass = "org.apache.commons.chain2.impl.CatalogBase";
+
+    private String catalogElement = "catalog";
+
+    private String chainClass = "org.apache.commons.chain2.impl.ChainBase";
+
+    private String chainElement = "chain";
+
+    private String classAttribute = "className";
+
+    private String commandElement = "command";
+
+    private String defineElement = "define";
+
+    private String nameAttribute = "name";
+
+    // ------------------------------------------------------------- Properties
+
+    /**
+     * <p>Return the fully qualified {@link org.apache.commons.chain2.Catalog}
+     *  implementation class.</p>
+     * @return The Catalog's class name.
+     */
+    public String getCatalogClass() {
+        return (this.catalogClass);
+    }
+
+    /**
+     * <p>Set the fully qualified {@link org.apache.commons.chain2.Catalog}
+     * implementation class.</p>
+     *
+     * @param catalogClass The new {@link org.apache.commons.chain2.Catalog}
+     *  implementation class
+     */
+    public void setCatalogClass(String catalogClass) {
+        this.catalogClass = catalogClass;
+    }
+
+    /**
+     * <p>Return the element name of a catalog element.</p>
+     * @return The element name of a catalog element.
+     */
+    public String getCatalogElement() {
+        return (this.catalogElement);
+    }
+
+    /**
+     * <p>Set the element name of a catalog element.</p>
+     *
+     * @param catalogElement The new element name
+     */
+    public void setCatalogElement(String catalogElement) {
+        this.catalogElement = catalogElement;
+    }
+
+    /**
+     * <p>Return the fully qualified {@link org.apache.commons.chain2.Chain}
+     * implementation class.</p>
+     * @return The Chain's class name.
+     */
+    public String getChainClass() {
+        return (this.chainClass);
+    }
+
+    /**
+     * <p>Set the fully qualified {@link org.apache.commons.chain2.Chain}
+     * implementation class.</p>
+     *
+     * @param chainClass The new {@link org.apache.commons.chain2.Chain}
+     * implementation class
+     */
+    public void setChainClass(String chainClass) {
+        this.chainClass = chainClass;
+    }
+
+    /**
+     * <p>Return the element name of a chain element.</p>
+     * @return The element name of a catalog element.
+     */
+    public String getChainElement() {
+        return (this.chainElement);
+    }
+
+    /**
+     * <p>Set the element name of a chain element.</p>
+     *
+     * @param chainElement The new element name
+     */
+    public void setChainElement(String chainElement) {
+        this.chainElement = chainElement;
+    }
+
+    /**
+     * <p>Return the attribute name of a class attribute.</p>
+     * @return The attribute name of a class attribute.
+     */
+    public String getClassAttribute() {
+        return (this.classAttribute);
+    }
+
+    /**
+     * <p>Set the attribute name of a class attribute.</p>
+     *
+     * @param classAttribute The new attribute name
+     */
+    public void setClassAttribute(String classAttribute) {
+        this.classAttribute = classAttribute;
+    }
+
+    /**
+     * <p>Return the element name of a command element.</p>
+     * @return The element name of a command element.
+     */
+    public String getCommandElement() {
+        return (this.commandElement);
+    }
+
+    /**
+     * <p>Set the element name of a command element.</p>
+     *
+     * @param commandElement The new element name
+     */
+    public void setCommandElement(String commandElement) {
+        this.commandElement = commandElement;
+    }
+
+    /**
+     * <p>Return the element name of a define element.</p>
+     * @return The element name of a define element.
+     */
+    public String getDefineElement() {
+        return (this.defineElement);
+    }
+
+    /**
+     * <p>Set the element name of a define element.</p>
+     *
+     * @param defineElement The new element name
+     */
+    public void setDefineElement(String defineElement) {
+        this.defineElement = defineElement;
+    }
+
+    /**
+     * <p>Return the attribute name of a name attribute.</p>
+     * @return The attribute name of an attribute element.
+     */
+    public String getNameAttribute() {
+        return (this.nameAttribute);
+    }
+
+    /**
+     * <p>Set the attribute name of a name attribute.</p>
+     *
+     * @param nameAttribute The new attribute name
+     */
+    public void setNameAttribute(String nameAttribute) {
+        this.nameAttribute = nameAttribute;
+    }
+
+    // --------------------------------------------------------- Public Methods
+
+    /**
+     * <p>Add the set of Rule instances defined in this RuleSet to the
+     * specified <code>Digester</code> instance, associating them with
+     * our namespace URI (if any).  This method should only be called
+     * by a Digester instance.</p>
+     *
+     * @param digester Digester instance to which the new Rule instances
+     *  should be added.
+     */
+    public void addRuleInstances(Digester digester) {
+        // Add rules for a catalog element
+        digester.addRule("*/" + getCatalogElement(),
+                         new ConfigCatalogRule(nameAttribute, catalogClass));
+        digester.addSetProperties("*/" + getCatalogElement());
+
+        // Add rules for a chain element
+        digester.addObjectCreate("*/" + getChainElement(),
+                                 getChainClass(),
+                                 getClassAttribute());
+        digester.addSetProperties("*/" + getChainElement());
+        digester.addRule("*/" + getChainElement(),
+                         new ConfigRegisterRule(nameAttribute));
+
+        // Add rules for a command element
+        digester.addObjectCreate("*/" + getCommandElement(),
+                                 null,
+                                 getClassAttribute());
+        digester.addSetProperties("*/" + getCommandElement());
+        digester.addRule("*/" + getCommandElement(),
+                         new ConfigRegisterRule(nameAttribute));
+
+        // Add rules for a define element
+        digester.addRule("*/" + getDefineElement(),
+                         new ConfigDefineRule(getNameAttribute(),
+                                              getClassAttribute()));
+    }
+
+}

Added: commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/package-info.java
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/package-info.java?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/package-info.java (added)
+++ commons/proper/chain/trunk/xml-configuration/src/main/java/org/apache/commons/chain2/config/package-info.java Thu Jul 26 18:04:57 2012
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+/**
+ * Optional package for configuring command chains in a catalog
+ * (using Digester) from an XML configuration file.
+ */
+package org.apache.commons.chain2.config;

Copied: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java (from r1365692, commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java)
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java?p2=commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java&p1=commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java&r1=1365692&r2=1366118&rev=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java (original)
+++ commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java Thu Jul 26 18:04:57 2012
@@ -19,7 +19,6 @@ package org.apache.commons.chain2.config
 
 import org.apache.commons.chain2.Catalog;
 import org.apache.commons.chain2.CatalogFactory;
-import org.apache.commons.chain2.Command;
 import org.apache.commons.chain2.Context;
 import org.apache.commons.chain2.impl.*;
 import org.apache.commons.digester3.Digester;

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParser2TestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Copied: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java (from r1365692, commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java)
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java?p2=commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java&p1=commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java&r1=1365692&r2=1366118&rev=1366118&view=diff
==============================================================================
--- commons/proper/chain/trunk/configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java (original)
+++ commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java Thu Jul 26 18:04:57 2012
@@ -17,33 +17,20 @@
 
 package org.apache.commons.chain2.config;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Iterator;
-
 import org.apache.commons.chain2.Catalog;
 import org.apache.commons.chain2.CatalogFactory;
-import org.apache.commons.chain2.Command;
 import org.apache.commons.chain2.Context;
-import org.apache.commons.chain2.impl.AddingCommand;
-import org.apache.commons.chain2.impl.CatalogBase;
-import org.apache.commons.chain2.impl.CatalogFactoryBase;
-import org.apache.commons.chain2.impl.ChainBase;
-import org.apache.commons.chain2.impl.ContextBase;
-import org.apache.commons.chain2.impl.DelegatingCommand;
-import org.apache.commons.chain2.impl.DelegatingFilter;
-import org.apache.commons.chain2.impl.ExceptionCommand;
-import org.apache.commons.chain2.impl.ExceptionFilter;
-import org.apache.commons.chain2.impl.NonDelegatingCommand;
-import org.apache.commons.chain2.impl.NonDelegatingFilter;
+import org.apache.commons.chain2.impl.*;
 import org.apache.commons.digester3.Digester;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.net.URL;
+import java.util.Iterator;
+
+import static org.junit.Assert.*;
+
 
 /**
  * <p>Test Case for <code>org.apache.commons.chain2.config.ConfigParser</code>.</p>
@@ -340,7 +327,14 @@ public class ConfigParserTestCase {
 
     // Load the specified catalog from the specified resource path
     protected void load(String path) throws Exception {
-        parser.parse(this.getClass().getResource(path));
+        URL url = this.getClass().getResource(path);
+
+        if (url == null) {
+            String msg = String.format("Can't find resource for path: %s", path);
+            throw new IllegalArgumentException(msg);
+        }
+
+        parser.parse(url);
         CatalogFactory<String, Object, Context<String, Object>> catalogFactory
             = CatalogFactoryBase.getInstance();
         catalog = catalogFactory.getCatalog();

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/ConfigParserTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/TestChain.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/TestChain.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/TestCommand.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/chain/trunk/xml-configuration/src/test/java/org/apache/commons/chain2/config/TestCommand.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Added: commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/config/test-config-2.xml
URL: http://svn.apache.org/viewvc/commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/config/test-config-2.xml?rev=1366118&view=auto
==============================================================================
--- commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/config/test-config-2.xml (added)
+++ commons/proper/chain/trunk/xml-configuration/src/test/resources/org/apache/commons/chain2/config/test-config-2.xml Thu Jul 26 18:04:57 2012
@@ -0,0 +1,114 @@
+<!--
+   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.
+-->
+<catalog name="foo">
+
+  <!-- Define command and chain aliases -->
+  <define    name="adding-command"
+        className="org.apache.commons.chain2.impl.AddingCommand"/>
+  <define    name="delegating-command"
+        className="org.apache.commons.chain2.impl.DelegatingCommand"/>
+  <define    name="delegating-filter"
+        className="org.apache.commons.chain2.impl.DelegatingFilter"/>
+  <define    name="exception-command"
+        className="org.apache.commons.chain2.impl.ExceptionCommand"/>
+  <define    name="exception-filter"
+        className="org.apache.commons.chain2.impl.ExceptionFilter"/>
+  <define    name="non-delegating-command"
+        className="org.apache.commons.chain2.impl.NonDelegatingCommand"/>
+  <define    name="non-delegating-filter"
+        className="org.apache.commons.chain2.impl.NonDelegatingFilter"/>
+  <define    name="test-chain"
+        className="org.apache.commons.chain2.config.TestChain"/>
+  <define    name="test-command"
+        className="org.apache.commons.chain2.config.TestCommand"/>
+
+  <!-- Single command "chains" from CatalogBaseTestCase -->
+  <adding-command
+             name="AddingCommand"/>
+  <delegating-command
+             name="DelegatingCommand"/>
+  <delegating-filter
+             name="DelegatingFilter"/>
+  <exception-command
+             name="ExceptionCommand"/>
+  <exception-filter
+             name="ExceptionFilter"/>
+  <non-delegating-command
+             name="NonDelegatingCommand"/>
+  <non-delegating-filter
+             name="NonDelegatingFilter"/>
+  <test-chain
+             name="ChainBase"/>
+
+  <!-- Configurable command with settable properties -->
+  <test-command
+             name="Configurable"
+              foo="Foo Value"
+              bar="Bar Value"/>
+
+  <!-- Chains with nested commands -->
+  <test-chain                       name="Execute2a">
+    <delegating-command               id="1"/>
+    <delegating-command               id="2"/>
+    <non-delegating-command           id="3"/>
+  </test-chain>
+  <test-chain                       name="Execute2b">
+    <delegating-command               id="1"/>
+    <delegating-command               id="2"/>
+    <delegating-command               id="3"/>
+  </test-chain>
+  <test-chain                       name="Execute2c">
+    <delegating-command               id="1"/>
+    <delegating-command               id="2"/>
+    <exception-command                id="3"/>
+  </test-chain>
+  <test-chain                       name="Execute2d">
+    <delegating-command               id="1"/>
+    <exception-command                id="2"/>
+    <non-delegating-command           id="3"/>
+  </test-chain>
+  <test-chain                       name="Execute4a">
+    <delegating-filter                id="1"
+                                     id2="a"/>
+    <delegating-command               id="2"/>
+    <non-delegating-filter            id="3"
+                                     id2="c"/>
+  </test-chain>
+  <test-chain                       name="Execute4b">
+    <delegating-command               id="1"/>
+    <delegating-filter                id="2"
+                                     id2="b"/>
+    <delegating-command               id="3"/>
+  </test-chain>
+  <test-chain                       name="Execute4c">
+    <delegating-filter                id="1"
+                                     id2="a"/>
+    <delegating-filter                id="2"
+                                     id2="b"/>
+    <exception-filter                 id="3"
+                                     id2="c"/>
+  </test-chain>
+  <test-chain                       name="Execute4d">
+    <delegating-filter                id="1"
+                                     id2="a"/>
+    <exception-filter                 id="2"
+                                     id2="b"/>
+    <non-delegating-filter            id="3"
+                                     id3="c"/>
+  </test-chain>
+
+</catalog>



Mime
View raw message