org.apache.xml.dtm.ref

Class IncrementalSAXSource_Filter

Implemented Interfaces:
ContentHandler, DTDHandler, ErrorHandler, IncrementalSAXSource, LexicalHandler, Runnable

public class IncrementalSAXSource_Filter
extends java.lang.Object
implements IncrementalSAXSource, ContentHandler, DTDHandler, LexicalHandler, ErrorHandler, Runnable

IncrementalSAXSource_Filter implements IncrementalSAXSource, using a standard SAX2 event source as its input and parcelling out those events gradually in reponse to deliverMoreNodes() requests. Output from the filter will be passed along to a SAX handler registered as our listener, but those callbacks will pass through a counting stage which periodically yields control back to the controller coroutine.

%REVIEW%: This filter is not currenly intended to be reusable for parsing additional streams/documents. We may want to consider making it resettable at some point in the future. But it's a small object, so that'd be mostly a convenience issue; the cost of allocating each time is trivial compared to the cost of processing any nontrival stream.

For a brief usage example, see the unit-test main() method.

This is a simplification of the old CoroutineSAXParser, focusing specifically on filtering. The resulting controller protocol is _far_ simpler and less error-prone; the only controller operation is deliverMoreNodes(), and the only requirement is that deliverMoreNodes(false) be called if you want to discard the rest of the stream and the previous deliverMoreNodes() didn't return false.

Nested Class Summary

Constructor Summary

IncrementalSAXSource_Filter()
IncrementalSAXSource_Filter(CoroutineManager co, int controllerCoroutineID)
Create a IncrementalSAXSource_Filter which is not yet bound to a specific SAX event source.

Method Summary

void
characters(char[] ch, int start, int length)
void
comment(char[] ch, int start, int length)
static IncrementalSAXSource
createIncrementalSAXSource(CoroutineManager co, int controllerCoroutineID)
Object
deliverMoreNodes(boolean parsemore)
deliverMoreNodes() is a simple API which tells the coroutine parser that we need more nodes.
void
endCDATA()
Report the end of a CDATA section.
void
endDTD()
Report the end of DTD declarations.
void
endDocument()
Receive notification of the end of a document.
void
endElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String qName)
void
endEntity(java.lang.String name)
void
endPrefixMapping(java.lang.String prefix)
void
error(SAXParseException exception)
Receive notification of a recoverable error.
void
fatalError(SAXParseException exception)
Receive notification of a non-recoverable error.
int
getControllerCoroutineID()
CoroutineManager
getCoroutineManager()
int
getSourceCoroutineID()
void
ignorableWhitespace(char[] ch, int start, int length)
void
init(CoroutineManager co, int controllerCoroutineID, int sourceCoroutineID)
void
notationDecl(String a, String b, String c)
void
processingInstruction(java.lang.String target, java.lang.String data)
void
run()
void
setContentHandler(ContentHandler handler)
Register a SAX-style content handler for us to output to
void
setDTDHandler(DTDHandler handler)
Register a SAX-style DTD handler for us to output to
void
setDocumentLocator(Locator locator)
Receive an object for locating the origin of SAX document events.
void
setErrHandler(ErrorHandler handler)
void
setLexicalHandler(LexicalHandler handler)
Register a SAX-style lexical handler for us to output to
void
setReturnFrequency(int events)
void
setXMLReader(XMLReader eventsource)
Bind our input streams to an XMLReader.
void
skippedEntity(java.lang.String name)
void
startCDATA()
Report the start of a CDATA section.
void
startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId)
void
startDocument()
Receive notification of the beginning of a document.
void
startElement(java.lang.String namespaceURI, java.lang.String localName, java.lang.String qName, Attributes atts)
void
startEntity(java.lang.String name)
void
startParse(InputSource source)
Launch a thread that will run an XMLReader's parse() operation within a thread, feeding events to this IncrementalSAXSource_Filter.
void
startPrefixMapping(java.lang.String prefix, java.lang.String uri)
void
unparsedEntityDecl(String a, String b, String c, String d)
void
warning(SAXParseException exception)
Receive notification of a warning.

Constructor Details

IncrementalSAXSource_Filter

public IncrementalSAXSource_Filter()


IncrementalSAXSource_Filter

public IncrementalSAXSource_Filter(CoroutineManager co,
                                   int controllerCoroutineID)
Create a IncrementalSAXSource_Filter which is not yet bound to a specific SAX event source.

Method Details

characters

public void characters(char[] ch,
                       int start,
                       int length)
            throws SAXException


comment

public void comment(char[] ch,
                    int start,
                    int length)
            throws SAXException


createIncrementalSAXSource

public static IncrementalSAXSource createIncrementalSAXSource(CoroutineManager co,
                                                              int controllerCoroutineID)


deliverMoreNodes

public Object deliverMoreNodes(boolean parsemore)
deliverMoreNodes() is a simple API which tells the coroutine parser that we need more nodes. This is intended to be called from one of our partner routines, and serves to encapsulate the details of how incremental parsing has been achieved.
Specified by:
deliverMoreNodes in interface IncrementalSAXSource

Parameters:
parsemore - If true, tells the incremental filter to generate another chunk of output. If false, tells the filter that we're satisfied and it can terminate parsing of this document.

Returns:
Boolean.TRUE if there may be more events available by invoking deliverMoreNodes() again. Boolean.FALSE if parsing has run to completion (or been terminated by deliverMoreNodes(false). Or an exception object if something malfunctioned. %REVIEW% We _could_ actually throw the exception, but that would require runinng deliverMoreNodes() in a try/catch... and for many applications, exception will be simply be treated as "not TRUE" in any case.


endCDATA

public void endCDATA()
            throws SAXException
Report the end of a CDATA section.
Specified by:
endCDATA in interface LexicalHandler

Throws:
SAXException - The application may raise an exception.

See Also:
LexicalHandler.startCDATA()


endDTD

public void endDTD()
            throws SAXException
Report the end of DTD declarations.

This method is intended to report the end of the DOCTYPE declaration; if the document has no DOCTYPE declaration, this method will not be invoked.

Specified by:
endDTD in interface LexicalHandler

Throws:
SAXException - The application may raise an exception.

See Also:
LexicalHandler.startDTD(String,String,String)


endDocument

public void endDocument()
            throws SAXException
Receive notification of the end of a document.

The SAX parser will invoke this method only once, and it will be the last method invoked during the parse. The parser shall not invoke this method until it has either abandoned parsing (because of an unrecoverable error) or reached the end of input.

Specified by:
endDocument in interface ContentHandler

Throws:
SAXException - Any SAX exception, possibly wrapping another exception.

See Also:
ContentHandler.startDocument()


endElement

public void endElement(java.lang.String namespaceURI,
                       java.lang.String localName,
                       java.lang.String qName)
            throws SAXException


endEntity

public void endEntity(java.lang.String name)
            throws SAXException


endPrefixMapping

public void endPrefixMapping(java.lang.String prefix)
            throws SAXException


error

public void error(SAXParseException exception)
            throws SAXException
Receive notification of a recoverable error.

This corresponds to the definition of "error" in section 1.2 of the W3C XML 1.0 Recommendation. For example, a validating parser would use this callback to report the violation of a validity constraint. The default behaviour is to take no action.

The SAX parser must continue to provide normal parsing events after invoking this method: it should still be possible for the application to process the document through to the end. If the application cannot do so, then the parser should report a fatal error even if the XML 1.0 recommendation does not require it to do so.

Filters may use this method to report other, non-XML errors as well.

Specified by:
error in interface ErrorHandler

Parameters:
exception - The error information encapsulated in a SAX parse exception.

Throws:
SAXException - Any SAX exception, possibly wrapping another exception.

See Also:
SAXParseException


fatalError

public void fatalError(SAXParseException exception)
            throws SAXException
Receive notification of a non-recoverable error.

This corresponds to the definition of "fatal error" in section 1.2 of the W3C XML 1.0 Recommendation. For example, a parser would use this callback to report the violation of a well-formedness constraint.

The application must assume that the document is unusable after the parser has invoked this method, and should continue (if at all) only for the sake of collecting addition error messages: in fact, SAX parsers are free to stop reporting any other events once this method has been invoked.

Specified by:
fatalError in interface ErrorHandler

Parameters:
exception - The error information encapsulated in a SAX parse exception.

Throws:
SAXException - Any SAX exception, possibly wrapping another exception.

See Also:
SAXParseException


getControllerCoroutineID

public int getControllerCoroutineID()


getCoroutineManager

public CoroutineManager getCoroutineManager()

Returns:
the CoroutineManager this CoroutineFilter object is bound to. If you're using the do...() methods, applications should only need to talk to the CoroutineManager once, to obtain the application's Coroutine ID.


getSourceCoroutineID

public int getSourceCoroutineID()


ignorableWhitespace

public void ignorableWhitespace(char[] ch,
                                int start,
                                int length)
            throws SAXException


init

public void init(CoroutineManager co,
                 int controllerCoroutineID,
                 int sourceCoroutineID)


notationDecl

public void notationDecl(String a,
                         String b,
                         String c)
            throws SAXException
Specified by:
notationDecl in interface DTDHandler


processingInstruction

public void processingInstruction(java.lang.String target,
                                  java.lang.String data)
            throws SAXException


run

public void run()


setContentHandler

public void setContentHandler(ContentHandler handler)
Register a SAX-style content handler for us to output to
Specified by:
setContentHandler in interface IncrementalSAXSource


setDTDHandler

public void setDTDHandler(DTDHandler handler)
Register a SAX-style DTD handler for us to output to
Specified by:
setDTDHandler in interface IncrementalSAXSource


setDocumentLocator

public void setDocumentLocator(Locator locator)
Receive an object for locating the origin of SAX document events.

SAX parsers are strongly encouraged (though not absolutely required) to supply a locator: if it does so, it must supply the locator to the application by invoking this method before invoking any of the other methods in the ContentHandler interface.

The locator allows the application to determine the end position of any document-related event, even if the parser is not reporting an error. Typically, the application will use this information for reporting its own errors (such as character content that does not match an application's business rules). The information returned by the locator is probably not sufficient for use with a search engine.

Note that the locator will return correct information only during the invocation of the events in this interface. The application should not attempt to use it at any other time.

Specified by:
setDocumentLocator in interface ContentHandler

Parameters:
locator - An object that can return the location of any SAX document event.

See Also:
Locator


setErrHandler

public void setErrHandler(ErrorHandler handler)


setLexicalHandler

public void setLexicalHandler(LexicalHandler handler)
Register a SAX-style lexical handler for us to output to
Specified by:
setLexicalHandler in interface IncrementalSAXSource


setReturnFrequency

public void setReturnFrequency(int events)


setXMLReader

public void setXMLReader(XMLReader eventsource)
Bind our input streams to an XMLReader. Just a convenience routine; obviously you can explicitly register this as a listener with the same effect.


skippedEntity

public void skippedEntity(java.lang.String name)
            throws SAXException


startCDATA

public void startCDATA()
            throws SAXException
Report the start of a CDATA section.

The contents of the CDATA section will be reported through the regular characters event; this event is intended only to report the boundary.

Specified by:
startCDATA in interface LexicalHandler

Throws:
SAXException - The application may raise an exception.

See Also:
LexicalHandler.endCDATA()


startDTD

public void startDTD(java.lang.String name,
                     java.lang.String publicId,
                     java.lang.String systemId)
            throws SAXException


startDocument

public void startDocument()
            throws SAXException
Receive notification of the beginning of a document.

The SAX parser will invoke this method only once, before any other event callbacks (except for setDocumentLocator).

Specified by:
startDocument in interface ContentHandler

Throws:
SAXException - Any SAX exception, possibly wrapping another exception.

See Also:
ContentHandler.endDocument()


startElement

public void startElement(java.lang.String namespaceURI,
                         java.lang.String localName,
                         java.lang.String qName,
                         Attributes atts)
            throws SAXException


startEntity

public void startEntity(java.lang.String name)
            throws SAXException


startParse

public void startParse(InputSource source)
            throws SAXException
Launch a thread that will run an XMLReader's parse() operation within a thread, feeding events to this IncrementalSAXSource_Filter. Mostly a convenience routine, but has the advantage that -- since we invoked parse() -- we can halt parsing quickly via a StopException rather than waiting for the SAX stream to end by itself.
Specified by:
startParse in interface IncrementalSAXSource

Throws:
SAXException - is parse thread is already in progress or parsing can not be started.


startPrefixMapping

public void startPrefixMapping(java.lang.String prefix,
                               java.lang.String uri)
            throws SAXException


unparsedEntityDecl

public void unparsedEntityDecl(String a,
                               String b,
                               String c,
                               String d)
            throws SAXException
Specified by:
unparsedEntityDecl in interface DTDHandler


warning

public void warning(SAXParseException exception)
            throws SAXException
Receive notification of a warning.

SAX parsers will use this method to report conditions that are not errors or fatal errors as defined by the XML 1.0 recommendation. The default behaviour is to take no action.

The SAX parser must continue to provide normal parsing events after invoking this method: it should still be possible for the application to process the document through to the end.

Filters may use this method to report other, non-XML warnings as well.

Specified by:
warning in interface ErrorHandler

Parameters:
exception - The warning information encapsulated in a SAX parse exception.

Throws:
SAXException - Any SAX exception, possibly wrapping another exception.

See Also:
SAXParseException


Copyright B) 2004 Apache XML Project. All Rights Reserved.