/*
 * 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.
 */
/*
 * $Id: ToSAXHandler.java 468654 2006-10-28 07:09:23Z minchau $
 */
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;

/**
 * This class is used to provide a base behavior to be inherited
 * by other To...SAXHandler serializers.
 * 
 * This class is not a public API.
 * 
 * @xsl.usage internal
 */
public abstract 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 characters The string of characters to process.
     *
     * @throws org.xml.sax.SAXException
     *
     * @see 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 ExtendedLexicalHandler#comment(String)
     */
    public void comment(String comment) throws SAXException
    {
        flushPending();

        // 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.
     *
     * @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 _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 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 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 qName the element name, with prefix (if any).

     * @see 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 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); 
    }
}
