/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 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) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xalan.transformer;

import java.io.IOException;

import org.xml.sax.XMLReader;
import org.xml.sax.XMLFilter;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
import org.xml.sax.EntityResolver;
import org.xml.sax.DTDHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.ext.LexicalHandler;

import org.apache.xpath.objects.XString;

// import org.xml.sax.ext.DeclHandler;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.Transformer;
import javax.xml.transform.Result;

import org.apache.xpath.XPathContext;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMManager;
import org.apache.xml.dtm.ref.IncrementalSAXSource;
import org.apache.xml.dtm.ref.IncrementalSAXSource_Filter;
import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;

import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.res.XSLMessages;


/**
 * A TransformerHandler
 * listens for SAX ContentHandler parse events and transforms
 * them to a Result.
 */
public class TransformerHandlerImpl
        implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler,
                   LexicalHandler, TransformerHandler, DeclHandler
{
  
  private boolean m_insideParse = false;

  ////////////////////////////////////////////////////////////////////
  // Constructors.
  ////////////////////////////////////////////////////////////////////

  /**
   * Construct a TransformerHandlerImpl.
   *
   * @param transformer Non-null reference to the Xalan transformer impl.
   * @param doFragment True if the result should be a document fragement.
   * @param baseSystemID  The system ID to use as the base for relative URLs.
   */
  public TransformerHandlerImpl(TransformerImpl transformer,
                                boolean doFragment, String baseSystemID)
  {

    super();

    m_transformer = transformer;
    m_baseSystemID = baseSystemID;

    XPathContext xctxt = transformer.getXPathContext();
    DTM dtm = xctxt.getDTM(null, true, transformer, true, true);
    
    m_dtm = dtm;
    dtm.setDocumentBaseURI(baseSystemID);

    m_contentHandler = dtm.getContentHandler();
    m_dtdHandler = dtm.getDTDHandler();
    m_entityResolver = dtm.getEntityResolver();
    m_errorHandler = dtm.getErrorHandler();
    m_lexicalHandler = dtm.getLexicalHandler();
  }
  
  /** 
   * Do what needs to be done to shut down the CoRoutine management.
   */
  protected void clearCoRoutine()
  {
    clearCoRoutine(null);
  }
  
  /** 
   * Do what needs to be done to shut down the CoRoutine management.
   */
  protected void clearCoRoutine(SAXException ex)
  {
    if(null != ex)
      m_transformer.setExceptionThrown(ex);
    
    if(m_dtm instanceof SAX2DTM)
    {
      if(DEBUG)
        System.err.println("In clearCoRoutine...");
      try
      {
        SAX2DTM sax2dtm = ((SAX2DTM)m_dtm);          
        if(null != m_contentHandler 
           && m_contentHandler instanceof IncrementalSAXSource_Filter)
        {
          IncrementalSAXSource_Filter sp =
            (IncrementalSAXSource_Filter)m_contentHandler;
          // This should now be all that's needed.
          sp.deliverMoreNodes(false);
        }
        
        sax2dtm.clearCoRoutine(true);
        m_contentHandler = null;
        m_dtdHandler = null;
        m_entityResolver = null;
        m_errorHandler = null;
        m_lexicalHandler = null;
      }
      catch(Throwable throwable)
      {
        throwable.printStackTrace();
      }
      
      if(DEBUG)
        System.err.println("...exiting clearCoRoutine");
    }
  }
  
  ////////////////////////////////////////////////////////////////////
  // Implementation of javax.xml.transform.sax.TransformerHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Enables the user of the TransformerHandler to set the
   * to set the Result for the transformation.
   *
   * @param result A Result instance, should not be null.
   *
   * @throws IllegalArgumentException if result is invalid for some reason.
   */
  public void setResult(Result result) throws IllegalArgumentException
  {

    if (null == result)
      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_NULL, null)); //"result should not be null");

    try
    {
      ContentHandler handler =
        m_transformer.createResultContentHandler(result);

      m_transformer.setContentHandler(handler);
    }
    catch (javax.xml.transform.TransformerException te)
    {
      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_COULD_NOT_BE_SET, null)); //"result could not be set");
    }

    m_result = result;
  }

  /**
   * Set the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @param systemID Base URI for the source tree.
   */
  public void setSystemId(String systemID)
  {
    m_baseSystemID = systemID;
    m_dtm.setDocumentBaseURI(systemID);
  }

  /**
   * Get the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @return The systemID that was set with {@link #setSystemId}.
   */
  public String getSystemId()
  {
    return m_baseSystemID;
  }

  /**
   * Get the Transformer associated with this handler, which
   * is needed in order to set parameters and output properties.
   *
   * @return The Transformer associated with this handler
   */
  public Transformer getTransformer()
  {
    return m_transformer;
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.EntityResolver.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter an external entity resolution.
   *
   * @param publicId The entity's public identifier, or null.
   * @param systemId The entity's system identifier.
   * @return A new InputSource or null for the default.
   *
   * @throws IOException
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @throws java.io.IOException The client may throw an
   *            I/O-related exception while obtaining the
   *            new InputSource.
   * @see org.xml.sax.EntityResolver#resolveEntity
   */
  public InputSource resolveEntity(String publicId, String systemId)
          throws SAXException, IOException
  {

    if (m_entityResolver != null)
    {
      return m_entityResolver.resolveEntity(publicId, systemId);
    }
    else
    {
      return null;
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.DTDHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter a notation declaration event.
   *
   * @param name The notation name.
   * @param publicId The notation's public identifier, or null.
   * @param systemId The notation's system identifier, or null.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.DTDHandler#notationDecl
   */
  public void notationDecl(String name, String publicId, String systemId)
          throws SAXException
  {

    if (m_dtdHandler != null)
    {
      m_dtdHandler.notationDecl(name, publicId, systemId);
    }
  }

  /**
   * Filter an unparsed entity declaration event.
   *
   * @param name The entity name.
   * @param publicId The entity's public identifier, or null.
   * @param systemId The entity's system identifier, or null.
   * @param notationName The name of the associated notation.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void unparsedEntityDecl(
          String name, String publicId, String systemId, String notationName)
            throws SAXException
  {

    if (m_dtdHandler != null)
    {
      m_dtdHandler.unparsedEntityDecl(name, publicId, systemId, notationName);
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ContentHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter a new document locator event.
   *
   * @param locator The document locator.
   * @see org.xml.sax.ContentHandler#setDocumentLocator
   */
  public void setDocumentLocator(Locator locator)
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#setDocumentLocator: "
                         + locator.getSystemId());

    this.m_locator = locator;
    
    if(null == m_baseSystemID)
    {
      setSystemId(locator.getSystemId());
    }

    if (m_contentHandler != null)
    {
      m_contentHandler.setDocumentLocator(locator);
    }
  }

  /**
   * Filter a start document event.
   *
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startDocument
   */
  public void startDocument() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startDocument");
      
    m_insideParse = true;

   // Thread listener = new Thread(m_transformer);

    if (m_contentHandler != null)
    {
      //m_transformer.setTransformThread(listener);
      if(DTMManager.getIncremental())
      {
        m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());
            
        int cpriority = Thread.currentThread().getPriority();
    
        // runTransformThread is equivalent with the 2.0.1 code,
        // except that the Thread may come from a pool.
        m_transformer.runTransformThread( cpriority );
      }

      // This is now done _last_, because IncrementalSAXSource_Filter
      // will immediately go into a "wait until events are requested"
      // pause. I believe that will close our timing window.
      // %REVIEW%
      m_contentHandler.startDocument();
   }
        
   //listener.setDaemon(false);
   //listener.start();

  }

  /**
   * Filter an end document event.
   *
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endDocument
   */
  public void endDocument() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endDocument");

    m_insideParse = false;
    
    if (m_contentHandler != null)
    {
      m_contentHandler.endDocument();
    }
    
    if(DTMManager.getIncremental())
    {
      m_transformer.waitTransformThread();
    }
    else
    {
      m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());
      m_transformer.run();
    }
   /* Thread transformThread = m_transformer.getTransformThread();

    if (null != transformThread)
    {
      try
      {

        // This should wait until the transformThread is considered not alive.
        transformThread.join();

        if (!m_transformer.hasTransformThreadErrorCatcher())
        {
          Exception e = m_transformer.getExceptionThrown();

          if (null != e)
            throw new org.xml.sax.SAXException(e);
        }

        m_transformer.setTransformThread(null);
      }
      catch (InterruptedException ie){}
    }*/
  }

  /**
   * Filter a start Namespace prefix mapping event.
   *
   * @param prefix The Namespace prefix.
   * @param uri The Namespace URI.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startPrefixMapping
   */
  public void startPrefixMapping(String prefix, String uri)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startPrefixMapping: "
                         + prefix + ", " + uri);

    if (m_contentHandler != null)
    {
      m_contentHandler.startPrefixMapping(prefix, uri);
    }
  }

  /**
   * Filter an end Namespace prefix mapping event.
   *
   * @param prefix The Namespace prefix.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endPrefixMapping
   */
  public void endPrefixMapping(String prefix) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endPrefixMapping: "
                         + prefix);

    if (m_contentHandler != null)
    {
      m_contentHandler.endPrefixMapping(prefix);
    }
  }

  /**
   * Filter a start element event.
   *
   * @param uri The element's Namespace URI, or the empty string.
   * @param localName The element's local name, or the empty string.
   * @param qName The element's qualified (prefixed) name, or the empty
   *        string.
   * @param atts The element's attributes.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startElement
   */
  public void startElement(
          String uri, String localName, String qName, Attributes atts)
            throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startElement: " + qName);

    if (m_contentHandler != null)
    {
      m_contentHandler.startElement(uri, localName, qName, atts);
    }
  }

  /**
   * Filter an end element event.
   *
   * @param uri The element's Namespace URI, or the empty string.
   * @param localName The element's local name, or the empty string.
   * @param qName The element's qualified (prefixed) name, or the empty
   *        string.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endElement
   */
  public void endElement(String uri, String localName, String qName)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endElement: " + qName);

    if (m_contentHandler != null)
    {
      m_contentHandler.endElement(uri, localName, qName);
    }
  }

  /**
   * Filter a character data event.
   *
   * @param ch An array of characters.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#characters
   */
  public void characters(char ch[], int start, int length) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#characters: " + start + ", "
                         + length);

    if (m_contentHandler != null)
    {
      m_contentHandler.characters(ch, start, length);
    }
  }

  /**
   * Filter an ignorable whitespace event.
   *
   * @param ch An array of characters.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#ignorableWhitespace
   */
  public void ignorableWhitespace(char ch[], int start, int length)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#ignorableWhitespace: "
                         + start + ", " + length);

    if (m_contentHandler != null)
    {
      m_contentHandler.ignorableWhitespace(ch, start, length);
    }
  }

  /**
   * Filter a processing instruction event.
   *
   * @param target The processing instruction target.
   * @param data The text following the target.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#processingInstruction
   */
  public void processingInstruction(String target, String data)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#processingInstruction: "
                         + target + ", " + data);

    if (m_contentHandler != null)
    {
      m_contentHandler.processingInstruction(target, data);
    }
  }

  /**
   * Filter a skipped entity event.
   *
   * @param name The name of the skipped entity.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#skippedEntity
   */
  public void skippedEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#skippedEntity: " + name);

    if (m_contentHandler != null)
    {
      m_contentHandler.skippedEntity(name);
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ErrorHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter a warning event.
   *
   * @param e The nwarning as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#warning
   */
  public void warning(SAXParseException e) throws SAXException
  {
    // This is not great, but we really would rather have the error 
    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
    // can't really be configured, so I think this is the best thing right now 
    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).warning(e);
    }
    else
    {
      try
      {
        errorListener.warning(new javax.xml.transform.TransformerException(e));
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  /**
   * Filter an error event.
   *
   * @param e The error as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#error
   */
  public void error(SAXParseException e) throws SAXException
  {
    // %REVIEW% I don't think this should be called.  -sb
    // clearCoRoutine(e);

    // This is not great, but we really would rather have the error 
    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
    // can't really be configured, so I think this is the best thing right now 
    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).error(e);
      if(null != m_errorHandler)
        m_errorHandler.error(e); // may not be called.
    }
    else
    {
      try
      {
        errorListener.error(new javax.xml.transform.TransformerException(e));
        if(null != m_errorHandler)
          m_errorHandler.error(e); // may not be called.
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  /**
   * Filter a fatal error event.
   *
   * @param e The error as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#fatalError
   */
  public void fatalError(SAXParseException e) throws SAXException
  {
    if(null != m_errorHandler)
    {
      try
      {
        m_errorHandler.fatalError(e);
      }
      catch(SAXParseException se)
      {
        // ignore
      }
      // clearCoRoutine(e);
    }

    // This is not great, but we really would rather have the error 
    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
    // can't really be configured, so I think this is the best thing right now 
    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).fatalError(e);
      if(null != m_errorHandler)
        m_errorHandler.fatalError(e); // may not be called.
    }
    else
    {
      try
      {
        errorListener.fatalError(new javax.xml.transform.TransformerException(e));
        if(null != m_errorHandler)
          m_errorHandler.fatalError(e); // may not be called.
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ext.LexicalHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Report the start of DTD declarations, if any.
   *
   * <p>Any declarations are assumed to be in the internal subset
   * unless otherwise indicated by a {@link #startEntity startEntity}
   * event.</p>
   *
   * <p>Note that the start/endDTD events will appear within
   * the start/endDocument events from ContentHandler and
   * before the first startElement event.</p>
   *
   * @param name The document type name.
   * @param publicId The declared public identifier for the
   *        external DTD subset, or null if none was declared.
   * @param systemId The declared system identifier for the
   *        external DTD subset, or null if none was declared.
   * @throws SAXException The application may raise an
   *            exception.
   * @see #endDTD
   * @see #startEntity
   */
  public void startDTD(String name, String publicId, String systemId)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startDTD: " + name + ", "
                         + publicId + ", " + systemId);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startDTD(name, publicId, systemId);
    }
  }

  /**
   * Report the end of DTD declarations.
   *
   * @throws SAXException The application may raise an exception.
   * @see #startDTD
   */
  public void endDTD() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endDTD");

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endDTD();
    }
  }

  /**
   * Report the beginning of an entity in content.
   *
   * <p><strong>NOTE:</entity> entity references in attribute
   * values -- and the start and end of the document entity --
   * are never reported.</p>
   *
   * <p>The start and end of the external DTD subset are reported
   * using the pseudo-name "[dtd]".  All other events must be
   * properly nested within start/end entity events.</p>
   *
   * <p>Note that skipped entities will be reported through the
   * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
   * event, which is part of the ContentHandler interface.</p>
   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @throws SAXException The application may raise an exception.
   * @see #endEntity
   * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
   * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
   */
  public void startEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startEntity: " + name);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startEntity(name);
    }
  }

  /**
   * Report the end of an entity.
   *
   * @param name The name of the entity that is ending.
   * @throws SAXException The application may raise an exception.
   * @see #startEntity
   */
  public void endEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endEntity: " + name);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endEntity(name);
    }
  }

  /**
   * Report the start of a CDATA section.
   *
   * <p>The contents of the CDATA section will be reported through
   * the regular {@link org.xml.sax.ContentHandler#characters
   * characters} event.</p>
   *
   * @throws SAXException The application may raise an exception.
   * @see #endCDATA
   */
  public void startCDATA() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startCDATA");

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startCDATA();
    }
  }

  /**
   * Report the end of a CDATA section.
   *
   * @throws SAXException The application may raise an exception.
   * @see #startCDATA
   */
  public void endCDATA() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endCDATA");

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endCDATA();
    }
  }

  /**
   * Report an XML comment anywhere in the document.
   *
   * <p>This callback will be used for comments inside or outside the
   * document element, including comments in the external DTD
   * subset (if read).</p>
   *
   * @param ch An array holding the characters in the comment.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The application may raise an exception.
   */
  public void comment(char ch[], int start, int length) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#comment: " + start + ", "
                         + length);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.comment(ch, start, length);
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ext.DeclHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Report an element type declaration.
   *
   * <p>The content model will consist of the string "EMPTY", the
   * string "ANY", or a parenthesised group, optionally followed
   * by an occurrence indicator.  The model will be normalized so
   * that all whitespace is removed,and will include the enclosing
   * parentheses.</p>
   *
   * @param name The element type name.
   * @param model The content model as a normalized string.
   * @throws SAXException The application may raise an exception.
   */
  public void elementDecl(String name, String model) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#elementDecl: " + name + ", "
                         + model);

    if (null != m_declHandler)
    {
      m_declHandler.elementDecl(name, model);
    }
  }

  /**
   * Report an attribute type declaration.
   *
   * <p>Only the effective (first) declaration for an attribute will
   * be reported.  The type will be one of the strings "CDATA",
   * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
   * "ENTITIES", or "NOTATION", or a parenthesized token group with
   * the separator "|" and all whitespace removed.</p>
   *
   * @param eName The name of the associated element.
   * @param aName The name of the attribute.
   * @param type A string representing the attribute type.
   * @param valueDefault A string representing the attribute default
   *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
   *        none of these applies.
   * @param value A string representing the attribute's default value,
   *        or null if there is none.
   * @throws SAXException The application may raise an exception.
   */
  public void attributeDecl(
          String eName, String aName, String type, String valueDefault, String value)
            throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#attributeDecl: " + eName
                         + ", " + aName + ", etc...");

    if (null != m_declHandler)
    {
      m_declHandler.attributeDecl(eName, aName, type, valueDefault, value);
    }
  }

  /**
   * Report an internal entity declaration.
   *
   * <p>Only the effective (first) declaration for each entity
   * will be reported.</p>
   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @param value The replacement text of the entity.
   * @throws SAXException The application may raise an exception.
   * @see #externalEntityDecl
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void internalEntityDecl(String name, String value)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#internalEntityDecl: " + name
                         + ", " + value);

    if (null != m_declHandler)
    {
      m_declHandler.internalEntityDecl(name, value);
    }
  }

  /**
   * Report a parsed external entity declaration.
   *
   * <p>Only the effective (first) declaration for each entity
   * will be reported.</p>
   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @param publicId The declared public identifier of the entity, or
   *        null if none was declared.
   * @param systemId The declared system identifier of the entity.
   * @throws SAXException The application may raise an exception.
   * @see #internalEntityDecl
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void externalEntityDecl(
          String name, String publicId, String systemId) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#externalEntityDecl: " + name
                         + ", " + publicId + ", " + systemId);

    if (null != m_declHandler)
    {
      m_declHandler.externalEntityDecl(name, publicId, systemId);
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Internal state.
  ////////////////////////////////////////////////////////////////////

  /** Set to true for diagnostics output.         */
  private static boolean DEBUG = false;

  /**
   * The transformer this will use to transform a
   * source tree into a result tree.
   */
  private TransformerImpl m_transformer;

  /** The system ID to use as a base for relative URLs. */
  private String m_baseSystemID;

  /** The result for the transformation. */
  private Result m_result = null;

  /** The locator for this TransformerHandler. */
  private Locator m_locator = null;

  /** The entity resolver to aggregate to. */
  private EntityResolver m_entityResolver = null;

  /** The DTD handler to aggregate to. */
  private DTDHandler m_dtdHandler = null;

  /** The content handler to aggregate to. */
  private ContentHandler m_contentHandler = null;

  /** The error handler to aggregate to. */
  private ErrorHandler m_errorHandler = null;

  /** The lexical handler to aggregate to. */
  private LexicalHandler m_lexicalHandler = null;

  /** The decl handler to aggregate to. */
  private DeclHandler m_declHandler = null;
  
  /** The Document Table Instance we are transforming. */
  DTM m_dtm;
}
