/*
 * 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.xml;

import org.apache.commons.chain2.CatalogFactory;
import org.apache.commons.chain2.config.ChainConfigurationException;
import org.apache.commons.chain2.config.ConfigParser;
import org.apache.commons.digester3.Digester;
import org.apache.commons.digester3.RuleSet;

import java.net.URL;
import java.util.Map;

/**
 * <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 XmlConfigParser implements 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 XmlConfigParser() {
    }

    public XmlConfigParser(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 <K> the type of keys maintained by the context associated with this command
     * @param <V> the type of mapped values
     * @param <C> Type of the context associated with this command
     * @param url <code>URL</code> of the XML document to be parsed
     * @return a CatalogFactory instance parsed from the given location
     * @exception ChainConfigurationException if a parsing error occurs
     */
    public <K, V, C extends Map<K, V>> CatalogFactory<K, V, C> parse(URL url) {
        // 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 digester configuration at url: %s",
                    url);
            throw new ChainConfigurationException(msg, e);
        }
        // FIXME get rid of singleton pattern and create a new instance here
        return CatalogFactory.getInstance();
    }

}
