/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 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 acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" 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 name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * 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 and was
 * originally based on software copyright (c) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * @author Santiago Pericas-Geertsen
 * @author G. Todd Miller 
 *
 */
package org.apache.xml.serializer;

import java.util.Vector;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.LexicalHandler;

abstract public class ToSAXHandler extends SerializerBase 
{
    public ToSAXHandler()
    {
    }

    public ToSAXHandler(
        ContentHandler hdlr,
        LexicalHandler lex,
        String encoding)
    {
        setContentHandler(hdlr);
        setLexHandler(lex);
        setEncoding(encoding);
    }
    public ToSAXHandler(ContentHandler handler, String encoding)
    {
        setContentHandler(handler);
        setEncoding(encoding);
    }

    /**
     * Underlying SAX handler. Taken from XSLTC
     */
    protected ContentHandler m_saxHandler;

    /**
     * Underlying LexicalHandler. Taken from XSLTC
     */
    protected LexicalHandler m_lexHandler;

    /**
     * A startPrefixMapping() call on a ToSAXHandler will pass that call
     * on to the wrapped ContentHandler, but should we also mirror these calls
     * with matching attributes, if so this field is true.
     * For example if this field is true then a call such as
     * startPrefixMapping("prefix1","uri1") will also cause the additional
     * internally generated attribute xmlns:prefix1="uri1" to be effectively added
     * to the attributes passed to the wrapped ContentHandler.
     */ 
    private boolean m_shouldGenerateNSAttribute = true;
    
    /** If this is true, then the content handler wrapped by this
     * serializer implements the TransformState interface which
     * will give the content handler access to the state of
     * the transform. */
    protected TransformStateSetter m_state = null;

    /**
     * Pass callback to the SAX Handler
     */
    protected void startDocumentInternal() throws SAXException
    {
        if (m_needToCallStartDocument)  
        {
            super.startDocumentInternal();

            m_saxHandler.startDocument();
            m_needToCallStartDocument = false;
        }
    }
    /**
     * Do nothing.
     * @see org.xml.sax.ext.LexicalHandler#startDTD(String, String, String)
     */
    public void startDTD(String arg0, String arg1, String arg2)
        throws SAXException
    {
        // do nothing for now
    }

    /**
     * Receive notification of character data.
     *
     * @param chars The string of characters to process.
     *
     * @throws org.xml.sax.SAXException
     *
     * @see org.apache.xml.serializer.ExtendedContentHandler#characters(String)
     */
    public void characters(String characters) throws SAXException
    {
        final int len = characters.length();
        if (len > m_charsBuff.length)
        {
           m_charsBuff = new char[len*2 + 1];             
        }
        characters.getChars(0,len, m_charsBuff, 0);   
        characters(m_charsBuff, 0, len);
    }

    /**
     * Receive notification of a comment.
     *
     * @see org.apache.xml.serializer.ExtendedLexicalHandler#comment(String)
     */
    public void comment(String comment) throws SAXException
    {

        // Close any open element before emitting comment
        if (m_elemContext.m_startTagOpen)
        {
            closeStartTag();
        }
        else if (m_cdataTagOpen)
        {
            closeCDATA();
        }

        // Ignore if a lexical handler has not been set
        if (m_lexHandler != null)
        {
            final int len = comment.length();
            if (len > m_charsBuff.length)
            {
               m_charsBuff = new char[len*2 + 1];              
            }
            comment.getChars(0,len, m_charsBuff, 0);            
            m_lexHandler.comment(m_charsBuff, 0, len);
            // time to fire off comment event
            if (m_tracer != null)
                super.fireCommentEvent(m_charsBuff, 0, len);
        }

    }

    /**
     * Do nothing as this is an abstract class. All subclasses will need to
     * define their behavior if it is different.
     * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
     */
    public void processingInstruction(String target, String data)
        throws SAXException
    {
        // Redefined in SAXXMLOutput
    }

    protected void closeStartTag() throws SAXException
    {
    }

    protected void closeCDATA() throws SAXException
    {
        // Redefined in SAXXMLOutput
    }
    
    /**
     * Receive notification of the beginning of an element, although this is a
     * SAX method additional namespace or attribute information can occur before
     * or after this call, that is associated with this element.
     *
     *
     * @param namespaceURI The Namespace URI, or the empty string if the
     *        element has no Namespace URI or if Namespace
     *        processing is not being performed.
     * @param localName The local name (without prefix), or the
     *        empty string if Namespace processing is not being
     *        performed.
     * @param name The element type name.
     * @param atts The attributes attached to the element, if any.
     * @throws org.xml.sax.SAXException Any SAX exception, possibly
     *            wrapping another exception.
     * @see org.xml.sax.ContentHandler#startElement
     * @see org.xml.sax.ContentHandler#endElement
     * @see org.xml.sax.AttributeList
     *
     * @throws org.xml.sax.SAXException
     *
     * @see org.xml.sax.ContentHandler#startElement(String,String,String,Attributes)
     */
    public void startElement(
        String arg0,
        String arg1,
        String arg2,
        Attributes arg3)
        throws SAXException
    {
        if (m_state != null) {
            m_state.resetState(getTransformer());
        }

        // fire off the start element event
        if (m_tracer != null)
            super.fireStartElem(arg2);
    }

    /**
     * Sets the LexicalHandler.
     * @param _lexHandler The LexicalHandler to set
     */
    public void setLexHandler(LexicalHandler _lexHandler)
    {
        this.m_lexHandler = _lexHandler;
    }

    /**
     * Sets the SAX ContentHandler.
     * @param m_saxHandler The ContentHandler to set
     */
    public void setContentHandler(ContentHandler _saxHandler)
    {
        this.m_saxHandler = _saxHandler;
        if (m_lexHandler == null && _saxHandler instanceof LexicalHandler)
        {
            // we are not overwriting an existing LexicalHandler, and _saxHandler
            // is also implements LexicalHandler, so lets use it
            m_lexHandler = (LexicalHandler) _saxHandler;
        }
    }

    /**
     * Does nothing. The setting of CDATA section elements has an impact on
     * stream serializers.
     * @see org.apache.xml.serializer.SerializationHandler#setCdataSectionElements(java.util.Vector)
     */
    public void setCdataSectionElements(Vector URI_and_localNames)
    {
        // do nothing
    }
    
    /** Set whether or not namespace declarations (e.g. 
     * xmlns:foo) should appear as attributes of 
     * elements
     * @param doOutputNSAttr whether or not namespace declarations
     * should appear as attributes
     */
    public void setShouldOutputNSAttr(boolean doOutputNSAttr)
    {
        m_shouldGenerateNSAttribute = doOutputNSAttr;
    }
 
    /** 
     * Returns true if namespace declarations from calls such as
     * startPrefixMapping("prefix1","uri1") should
     * also be mirrored with self generated additional attributes of elements 
     * that declare the namespace, for example the attribute xmlns:prefix1="uri1"
     */
    boolean getShouldOutputNSAttr()
    {
        return m_shouldGenerateNSAttribute;
    }

    /**
     * This method flushes any pending events, which can be startDocument()
     * closing the opening tag of an element, or closing an open CDATA section.
     */
    public void flushPending() throws SAXException
    {
    
            if (m_needToCallStartDocument)
            {
                startDocumentInternal();
                m_needToCallStartDocument = false;
            }

            if (m_elemContext.m_startTagOpen)
            {
                closeStartTag();
                m_elemContext.m_startTagOpen = false;
            }
            
            if (m_cdataTagOpen)
            {
                closeCDATA();
                m_cdataTagOpen = false;
            }

    }

    /**
     * Pass in a reference to a TransformState object, which
     * can be used during SAX ContentHandler events to obtain
     * information about he state of the transformation. This
     * method will be called  before each startDocument event.
     *
     * @param ts A reference to a TransformState object
     */
    public void setTransformState(TransformStateSetter ts) {
        this.m_state = ts;
    }
    
    /**
     * Receives notification that an element starts, but attributes are not
     * fully known yet.
     *
     * @param uri the URI of the namespace of the element (optional)
     * @param localName the element name, but without prefix (optional)
     * @param qName the element name, with prefix, if any (required)
     *
     * @see org.apache.xml.serializer.ExtendedContentHandler#startElement(String, String, String)
     */
    public void startElement(String uri, String localName, String qName)
        throws SAXException {
            
        if (m_state != null) {
            m_state.resetState(getTransformer());
        }

        // fire off the start element event
        if (m_tracer != null)
            super.fireStartElem(qName);         
    }

    /**
     * An element starts, but attributes are not fully known yet.
     *
     * @param elementName the element name, with prefix (if any).

     * @see org.apache.xml.serializer.ExtendedContentHandler#startElement(String)
     */
    public void startElement(String qName) throws SAXException {
        if (m_state != null) {
            m_state.resetState(getTransformer());
        }        
        // fire off the start element event
        if (m_tracer != null)
            super.fireStartElem(qName);              
    }
    
    /**
     * This method gets the node's value as a String and uses that String as if
     * it were an input character notification.
     * @param node the Node to serialize
     * @throws org.xml.sax.SAXException
     */    
    public void characters(org.w3c.dom.Node node)
        throws org.xml.sax.SAXException
    {
        // remember the current node
        if (m_state != null)
        {
            m_state.setCurrentNode(node);
        }
        
        // Get the node's value as a String and use that String as if
        // it were an input character notification.
        String data = node.getNodeValue();
        if (data != null) {
            this.characters(data);
        }
    }    

    /**
     * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
     */
    public void fatalError(SAXParseException exc) throws SAXException {
        super.fatalError(exc);
        
        m_needToCallStartDocument = false;
        
        if (m_saxHandler instanceof ErrorHandler) {
            ((ErrorHandler)m_saxHandler).fatalError(exc);            
        }
    }

    /**
     * @see org.xml.sax.ErrorHandler#error(SAXParseException)
     */
    public void error(SAXParseException exc) throws SAXException {
        super.error(exc);
        
        if (m_saxHandler instanceof ErrorHandler)
            ((ErrorHandler)m_saxHandler).error(exc);        
        
    }

    /**
     * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
     */
    public void warning(SAXParseException exc) throws SAXException {
        super.warning(exc);
        
        if (m_saxHandler instanceof ErrorHandler)
            ((ErrorHandler)m_saxHandler).warning(exc);        
    }
    
       
    /**
     * Try's to reset the super class and reset this class for 
     * re-use, so that you don't need to create a new serializer 
     * (mostly for performance reasons).
     * 
     * @return true if the class was successfuly reset.
     * @see org.apache.xml.serializer.Serializer#reset()
     */
    public boolean reset()
    {
        boolean wasReset = false;
        if (super.reset())
        {
            resetToSAXHandler();
            wasReset = true;
        }
        return wasReset;
    }
    
    /**
     * Reset all of the fields owned by ToSAXHandler class
     *
     */
    private void resetToSAXHandler()
    {
        this.m_lexHandler = null;
        this.m_saxHandler = null;
        this.m_state = null;
        this.m_shouldGenerateNSAttribute = false;
    }  

    /**
     * Add a unique attribute
     */
    public void addUniqueAttribute(String qName, String value, int flags)
        throws SAXException
    {
        addAttribute(qName, value); 
    }
}
