blob: 6ded15a454ec31b51f62219727b4e3cd47aebcbd [file] [log] [blame]
/*
* 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;
}