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

import org.apache.commons.configuration2.tree.ConfigurationNodeVisitorAdapter;
import org.apache.commons.configuration2.tree.NodeHandler;
import org.apache.commons.configuration2.tree.NodeTreeWalker;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;

/**
 * <p>
 * A specialized SAX2 XML parser that "parses" hierarchical configuration
 * objects.
 * </p>
 * <p>
 * This class mimics to be a SAX conform XML parser. Instead of parsing XML
 * documents it processes a {@code Configuration} object and generates SAX
 * events for the single properties defined there. This enables the whole world
 * of XML processing for configuration objects.
 * </p>
 * <p>
 * The {@code HierarchicalConfiguration} object to be parsed can be specified
 * using a constructor or the {@code setConfiguration()} method. This object
 * will be processed by the {@code parse()} methods. Note that these methods
 * ignore their argument.
 * </p>
 *
 * @version $Id$
 * @param <T> the type of the nodes supported by this reader
 */
public class HierarchicalConfigurationXMLReader<T> extends
        ConfigurationXMLReader
{
    /** Stores the configuration object to be parsed. */
    private HierarchicalConfiguration<T> configuration;

    /**
     * Creates a new instance of {@code HierarchicalConfigurationXMLReader}.
     */
    public HierarchicalConfigurationXMLReader()
    {
        super();
    }

    /**
     * Creates a new instance of {@code HierarchicalConfigurationXMLReader} and
     * sets the configuration to be parsed.
     *
     * @param config the configuration object
     */
    public HierarchicalConfigurationXMLReader(
            HierarchicalConfiguration<T> config)
    {
        this();
        setConfiguration(config);
    }

    /**
     * Returns the configuration object to be parsed.
     *
     * @return the configuration object to be parsed
     */
    public HierarchicalConfiguration<T> getConfiguration()
    {
        return configuration;
    }

    /**
     * Sets the configuration object to be parsed.
     *
     * @param config the configuration object to be parsed
     */
    public void setConfiguration(HierarchicalConfiguration<T> config)
    {
        configuration = config;
    }

    /**
     * Returns the configuration object to be processed.
     *
     * @return the actual configuration object
     */
    @Override
    public Configuration getParsedConfiguration()
    {
        return getConfiguration();
    }

    /**
     * Processes the actual configuration object to generate SAX parsing events.
     */
    @Override
    protected void processKeys()
    {
        NodeHandler<T> nodeHandler =
                getConfiguration().getNodeModel().getNodeHandler();
        NodeTreeWalker.INSTANCE.walkDFS(nodeHandler.getRootNode(),
                new SAXVisitor(), nodeHandler);
    }

    /**
     * A specialized visitor class for generating SAX events for a hierarchical
     * node structure.
     */
    private class SAXVisitor extends ConfigurationNodeVisitorAdapter<T>
    {
        /** Constant for the attribute type. */
        private static final String ATTR_TYPE = "CDATA";

        /**
         * Visits the specified node after its children have been processed.
         *
         * @param node the actual node
         * @param handler the node handler
         */
        @Override
        public void visitAfterChildren(T node, NodeHandler<T> handler)
        {
            fireElementEnd(nodeName(node, handler));
        }

        /**
         * Visits the specified node.
         *
         * @param node the actual node
         * @param handler the node handler
         */
        @Override
        public void visitBeforeChildren(T node, NodeHandler<T> handler)
        {
            fireElementStart(nodeName(node, handler),
                    fetchAttributes(node, handler));

            Object value = handler.getValue(node);
            if (value != null)
            {
                fireCharacters(value.toString());
            }
        }

        /**
         * Checks if iteration should be terminated. This implementation stops
         * iteration after an exception has occurred.
         *
         * @return a flag if iteration should be stopped
         */
        @Override
        public boolean terminate()
        {
            return getException() != null;
        }

        /**
         * Returns an object with all attributes for the specified node.
         *
         * @param node the current node
         * @param handler the node handler
         * @return an object with all attributes of this node
         */
        protected Attributes fetchAttributes(T node, NodeHandler<T> handler)
        {
            AttributesImpl attrs = new AttributesImpl();

            for (String attr : handler.getAttributes(node))
            {
                Object value = handler.getAttributeValue(node, attr);
                if (value != null)
                {
                    attrs.addAttribute(NS_URI, attr, attr, ATTR_TYPE,
                            value.toString());
                }
            }

            return attrs;
        }

        /**
         * Helper method for determining the name of a node. If a node has no
         * name (which is true for the root node), the specified default name
         * will be used.
         *
         * @param node the node to be checked
         * @param handler the node handler
         * @return the name for this node
         */
        private String nodeName(T node, NodeHandler<T> handler)
        {
            String nodeName = handler.nodeName(node);
            return (nodeName == null) ? getRootName() : nodeName;
        }
    }
}
