/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2002 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Ant", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.ant.antcore.xml;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.ant.common.util.Location;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.ant.common.util.PropertyUtils;

/**
 * An Element Handler is a handler which handles a single element by
 * becoming the handler for the parser while processing the element. Any sub
 * elements must be delegated to separate handlers. When this element is
 * finished, control returns to the parent handler.
 *
 * @author Conor MacNeill
 * @created 9 January 2002
 */
public abstract class ElementHandler extends DefaultHandler {
    /** The parsing context for parsing this element */
    private ParseContext context;

    /**
     * Locator used to identify where in the build source particular
     * elements occur.
     */
    private Locator locator;

    /** The actual XML parser used to parse the build source */
    private XMLReader reader;

    /** The parent element handler */
    private ContentHandler parent;

    /** The URL from which we are reading source */
    private URL source;

    /** The name of this element */
    private String elementName;

    /** The attributes read from this element */
    private Map elementAttributes;

    /** The aspect attributes read from the element definition */
    private Map aspects;

    /** The content of this element */
    private String content;

    /**
     * Get the source which contains this element
     *
     * @return the URL from which this element is being read
     */
    public URL getElementSource() {
        return source;
    }

    /**
     * Gets the attributeValue attribute of the ElementHandler object
     *
     * @param attributeName th name of the attribute
     * @return The corresponding attribute value or null if the attribute wa
     *      snot defined.
     */
    public String getAttribute(String attributeName) {
        return (String) elementAttributes.get(attributeName);
    }

    /**
     * Get an attribute as a boolean value
     *
     * @param attributeName the name of the attribute
     * @return the attribute value as a boolean
     */
    protected boolean getBooleanAttribute(String attributeName) {
        return PropertyUtils.toBoolean(getAttribute(attributeName));
    }
    
    /**
     * Get an iterator to this elements attributes
     *
     * @return an iterator over the attribute names
     */
    public Iterator getAttributes() {
        return elementAttributes.keySet().iterator();
    }

    /**
     * Get the aspect attributes of this element.
     *
     * @return The aspect attributes.
     */
    public Map getAspects() {
        return aspects;
    }

    /**
     * Gets the content of the element
     *
     * @return The content value
     */
    public String getContent() {
        return content;
    }


    /**
     * Start this element handler.
     *
     * @param parent the element handler for the element which contains this
     *      one.
     * @param locator the locator is used to get location information from
     *      elements.
     * @param attributes the element's attributes.
     * @param source the URL from which the XML source is being parsed.
     * @param xmlReader the parser being used
     * @param context the parser context for this element
     * @param elementName the actual element Name for this element in the
     *      XML
     * @exception SAXParseException if there is a problem parsing the
     *      element
     */
    public final void start(ParseContext context, XMLReader xmlReader,
                            ContentHandler parent, Locator locator,
                            Attributes attributes, URL source,
                            String elementName)
         throws SAXParseException {
        this.context = context;
        this.reader = xmlReader;
        this.parent = parent;
        this.locator = locator;
        this.source = source;
        this.elementName = elementName;
        processAttributes(attributes);
        processElement(elementName);
        reader.setContentHandler(this);
    }


    /**
     * By default an element handler does not support nested elements. This
     * method will always throw an exception. Subclasses should override
     * this method to support their own nested elements
     *
     * @param uri The Namespace URI.
     * @param localName The local name (without prefix).
     * @param qualifiedName The qualified name (with prefix)
     * @param attributes The attributes attached to the element.
     * @throws SAXParseException if there is a problem parsng the subelement
     */
    public void startElement(String uri, String localName, String qualifiedName,
                             Attributes attributes)
         throws SAXParseException {
        // everything is a task
        throw new SAXParseException("<" + elementName + "> does not support a <"
             + qualifiedName + "> nested element", getLocator());
    }


    /**
     * Handle the end of this element by making the parent element handler
     * the current content handler
     *
     * @param localName The local name (without prefix).
     * @param namespaceURI The Namespace URI.
     * @param qName the qualified name of the element
     */
    public final void endElement(String namespaceURI, String localName,
                                 String qName) {
        finish();
        reader.setContentHandler(parent);
    }

    /**
     * Record content of this element
     *
     * @param buf the buffer containing the content to be added
     * @param start start position in the buffer
     * @param end end position in the buffer
     * @exception SAXParseException if there is a parsing error.
     * @see org.xml.sax.ContentHandler.characters()
     */
    public void characters(char[] buf, int start, int end)
         throws SAXParseException {
        if (content == null) {
            content = "";
        }
        content += new String(buf, start, end);
    }


    /**
     * Get the current parsing location
     *
     * @return a location instance representing the current parse position
     */
    protected Location getLocation() {
        return new Location(locator.getSystemId(), locator.getLineNumber(),
            locator.getColumnNumber());
    }


    /**
     * Get the XML Reader being used to parse the XML.
     *
     * @return the XML Reader.
     */
    protected XMLReader getXMLReader() {
        return reader;
    }


    /**
     * Get the parsing context
     *
     * @return the parsing context of this element
     */
    protected ParseContext getParseContext() {
        return context;
    }


    /**
     * Get the locator used to locate elements in the XML source as they are
     * parsed.
     *
     * @return the locator object which can be used to determine an elements
     *      location within the XML source
     */
    protected Locator getLocator() {
        return locator;
    }


    /**
     * Process the element.
     *
     * @param elementName the name of the element
     * @exception SAXParseException if there is a problem parsing the
     *      element
     */
    protected abstract void processElement(String elementName)
         throws SAXParseException;


    /**
     * Process all of the attributes of the element into maps, one for
     * aspects and one for other attributes
     *
     * @param attributes The SAX attributes collection for the element
     * @exception SAXParseException if there is a problem reading the
     *      attributes
     */
    protected final void processAttributes(Attributes attributes)
         throws SAXParseException {
        aspects = new HashMap();
        elementAttributes = new HashMap();
        int length = attributes.getLength(); 
        for (int i = 0; i < length; ++i) {
            String attributeName = attributes.getQName(i);
            String attributeValue = attributes.getValue(i);
            if (attributeName.indexOf(":") != -1) {
                aspects.put(attributeName, attributeValue);
            } else {
                validateAttribute(attributeName, attributeValue);
                elementAttributes.put(attributeName, attributeValue);
            }
        }
    }

    /**
     * Validate that the given attribute and value are valid. By default all
     * attributes are considered invalid. This method should be overrider by
     * subclasses to allow specific attributes
     *
     * @param attributeName The name of the attributes
     * @param attributeValue The value of the attributes
     * @exception SAXParseException if the attribute is not allowed on the
     *      element.
     */
    protected void validateAttribute(String attributeName,
                                     String attributeValue)
         throws SAXParseException {
        throwInvalidAttribute(attributeName);
    }

    /**
     * Throws an invalid attribute exception
     *
     * @param attributeName The name of the invalid attribute
     * @exception SAXParseException always - indicating attribute is invalid
     */
    protected final void throwInvalidAttribute(String attributeName)
         throws SAXParseException {
        throw new SAXParseException("The attribute '" + attributeName
             + "' is not " + "supported by the <" + elementName
             + "> element", getLocator());
    }


    /**
     * This method is called when this element is finished being processed.
     * This is a template method allowing subclasses to complete any
     * necessary processing.
     */
    protected void finish() {
    }
}

