org.greybird.xmliter
Class ThreadedSaxEventSource

java.lang.Object
  |
  +--org.greybird.xmliter.ThreadedSaxEventSource
All Implemented Interfaces:
java.lang.Runnable, SaxEventSource

public class ThreadedSaxEventSource
extends java.lang.Object
implements SaxEventSource, java.lang.Runnable

A SaxEventSource that uses a separate thread to run a SAX parser.

To allow any non-incremental XML parser to be used as a SaxEventSource, it can be run in a separate parser thread. The generateEvents() method is called by the user thread. It activates the parser thread, which then generates some number of SAX events and activates the user thread again. The threads are serialized and the parser thread doesn't run except when activated explicitly, so there are no thread-safety requirements.

The number of SAX events generated by the parser thread during a single activation determines its performance characteristics. If a larger number of events are generated, less CPU time is used overall because there are less thread context switches, but more memory is used because more events are queued. The DEFAULT_EVENT_THRESHOLD may be overridden using the setEventThreshold(int) method.

ThreadedSaxEventSource provides the run() method for the parser thread, and optionally creates the parser thread and a default parser. The simplest technique is to use the ThreadedSaxEventSource(InputSource) constructor, which is used automatically by SaxIterator.SaxIterator(InputSource) if a Xerces pull-parser is not available

 import org.greybird.xmliter.SaxEventSource;
 import org.greybird.xmliter.SaxIterator;
 import org.greybird.xmliter.XmlIterator;
 import org.greybird.xmliter.ThreadedSaxEventSource;
 import org.xml.sax.InputSource;
 ...
 //
 // Create a ThreadedSaxEventSource from a SAX InputSource.
 //
 InputSource input = new InputSource(...);
 SaxEventSource eventSource = new ThreadedSaxEventSource(input);
 //
 // Create a SaxIterator from a ThreadedSaxEventSource
 //
 XmlIterator iter = new SaxIterator(eventSource);
 while (iter.advance()) { ...
 

You may wish to provide a parser yourself to have control over its configuration or to reuse parsers for performance reasons.

 import javax.xml.parsers.SAXParserFactory;
 import org.greybird.xmliter.SaxEventSource;
 import org.greybird.xmliter.SaxIterator;
 import org.greybird.xmliter.XmlIterator;
 import org.greybird.xmliter.ThreadedSaxEventSource;
 import org.xml.sax.InputSource;
 import org.xml.sax.XMLReader;
 ...
 //
 // Create a ThreadedSaxEventSource from a SAX InputSource and SAX parser.
 //
 XMLReader parser =
      SAXParserFactory.newInstance().newSAXParser().getXMLReader();
 InputSource input = new InputSource(...);
 SaxEventSource eventSource = new ThreadedSaxEventSource(input, parser);
 //
 // Create a SaxIterator from a ThreadedSaxEventSource
 //
 XmlIterator iter = new SaxIterator(eventSource);
 while (iter.advance()) { ...
 

As an advanced option, you may create the parser thread yourself in order to use a thread pool. In this case you must follow the protocol documented with the ThreadedSaxEventSource(InputSource,XMLReader,Object) constructor and shown in the following example.

 import org.greybird.xmliter.SaxEventSource;
 import org.greybird.xmliter.SaxIterator;
 import org.greybird.xmliter.XmlIterator;
 import org.greybird.xmliter.ThreadedSaxEventSource;
 import org.xml.sax.InputSource;
 ...
 //
 // Create a ThreadedSaxEventSource from a SAX InputSource and lock object.
 //
 Object lock = new Object();
 InputSource input = new InputSource(...);
 SaxEventSource eventSource = new ThreadedSaxEventSource(input, null, lock);
 //
 // Activate the parser thread and wait for the run() method to call notify()
 //
 synchronized (lock) {
     ... // allocate a parser thread from a thread pool and associate it
     ... // with the eventSource so it calls the eventSource.run() method
     lock.wait(); // wait for the run() method to notify this thread
 }
 //
 // Create a SaxIterator from a ThreadedSaxEventSource
 //
 XmlIterator iter = new SaxIterator(eventSource);
 while (iter.advance()) { ...
 


Field Summary
static int DEFAULT_EVENT_THRESHOLD
          The default number of SAX events to generate between thread activations is 50.
 
Fields inherited from interface org.greybird.xmliter.SaxEventSource
NAMESPACES_FEATURE
 
Constructor Summary
ThreadedSaxEventSource(org.xml.sax.InputSource inputSource)
          Creates a threaded SAX event source, using a default parser.
ThreadedSaxEventSource(org.xml.sax.InputSource inputSource, org.xml.sax.XMLReader parser)
          Creates a threaded SAX event source, optionally specifying a parser.
ThreadedSaxEventSource(org.xml.sax.InputSource inputSource, org.xml.sax.XMLReader parser, java.lang.Object lock)
          Creates a threaded SAX event source, optionally specifying a parser and a lock object for coordination of a caller-supplied parser thread.
 
Method Summary
 void close(boolean completeParsing)
          Closes the event source to free up resources and stops generating events.
 boolean generateEvents()
          Generates a subset of SAX events and returns true if more events are still available.
 void run()
          Run the parser operation from the parser thread.
 void setContentHandler(org.xml.sax.ContentHandler contentHandler)
          Sets the content handler to receive SAX events.
 void setEventThreshold(int eventThreshold)
          Changes the number of SAX events to generate between thread activations.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

DEFAULT_EVENT_THRESHOLD

public static final int DEFAULT_EVENT_THRESHOLD
The default number of SAX events to generate between thread activations is 50.
Constructor Detail

ThreadedSaxEventSource

public ThreadedSaxEventSource(org.xml.sax.InputSource inputSource)
                       throws org.xml.sax.SAXException,
                              javax.xml.parsers.ParserConfigurationException
Creates a threaded SAX event source, using a default parser.

javax.xml.parsers.SAXParserFactory will be used to create a default SAX parser.

The parser thread will be created by the constructor.

Parameters:
inputSource - is the input document to be parsed.

ThreadedSaxEventSource

public ThreadedSaxEventSource(org.xml.sax.InputSource inputSource,
                              org.xml.sax.XMLReader parser)
                       throws org.xml.sax.SAXException,
                              javax.xml.parsers.ParserConfigurationException
Creates a threaded SAX event source, optionally specifying a parser.

If the parser parameter is null, javax.xml.parsers.SAXParserFactory will be used to create a default SAX parser.

The parser's http://xml.org/sax/features/namespaces feature will be set to true by the constructor.

The parser thread will be created by the constructor.

Parameters:
inputSource - is the input document to be parsed.
parser - is a SAX parser to use, or null if a default parser should be created by the constructor.

ThreadedSaxEventSource

public ThreadedSaxEventSource(org.xml.sax.InputSource inputSource,
                              org.xml.sax.XMLReader parser,
                              java.lang.Object lock)
                       throws org.xml.sax.SAXException,
                              javax.xml.parsers.ParserConfigurationException
Creates a threaded SAX event source, optionally specifying a parser and a lock object for coordination of a caller-supplied parser thread.

If the parser parameter is null, javax.xml.parsers.SAXParserFactory will be used to create a default SAX parser.

The parser's http://xml.org/sax/features/namespaces feature will be set to true by the constructor.

If the lock parameter is null, the parser thread will be created by the constructor.

If the lock parameter is non-null, the caller is responsible for the parser thread and must follow the protocol below.

  1. Create the ThreadedSaxEventSource specifying a non-null lock object.
  2. While synchronized on the lock object:
    • Obtain a parser thread and associate it with the ThreadedSaxEventSource object.
    • Cause the parser thread to call the run() method of the ThreadedSaxEventSource.
    • Call the wait() method of the lock object, which will wait until the run() method of the ThreadedSaxEventSource calls the notify() method of the lock object.
  3. The parser thread is now waiting to proceed with parsing. Use the ThreadedSaxEventSource to create a SaxIterator and begin iterating.
Parameters:
inputSource - is the input document to be parsed.
parser - is a SAX parser to use, or null if a default parser should be created.
lock - is a lock object if the user will manage the parser thread, or null if the parser thread should be created by the constructor.
Method Detail

setEventThreshold

public void setEventThreshold(int eventThreshold)
Changes the number of SAX events to generate between thread activations.

The default value is DEFAULT_EVENT_THRESHOLD.


run

public void run()
Run the parser operation from the parser thread.

This method is called automatically if the parser thread is created by this class. For a user-managed parser thread, this method must be called from the parser thread while syncrhonized on the lock object.

When this method is called it will synchronize on the lock object and call notify() and then wait() on the lock object. This notifies the user thread that the parser thread is ready and waiting.

When generateEvents() is called the first time, this method will be notified and will begin parsing. Each time generateEvents() is called this method will continue parsing within the parser thread until one of the following occurs.

Specified by:
run in interface java.lang.Runnable

setContentHandler

public void setContentHandler(org.xml.sax.ContentHandler contentHandler)
Description copied from interface: SaxEventSource
Sets the content handler to receive SAX events.

This method is called by SaxIterator before it calls generateEvents().

Not all handler methods need be called by a generator. The methods used are as follows and all other method calls are ignored.

Specified by:
setContentHandler in interface SaxEventSource

close

public void close(boolean completeParsing)
           throws java.io.IOException,
                  XmlIteratorException
Description copied from interface: SaxEventSource
Closes the event source to free up resources and stops generating events.

Even when completeParsing is true, no events should be generated by this method or by subsequent calls to generateEvents().

Specified by:
close in interface SaxEventSource
Following copied from interface: org.greybird.xmliter.SaxEventSource
Parameters:
completeParsing - is true if parsing and reading of the input source should be completed during close, or false to abort parsing and reading.
Throws:
java.io.IOException - if an error occurs retrieving input data.
XmlIteratorException - if an error occurs processing input data.

generateEvents

public boolean generateEvents()
                       throws java.io.IOException,
                              XmlIteratorException
Description copied from interface: SaxEventSource
Generates a subset of SAX events and returns true if more events are still available.
Specified by:
generateEvents in interface SaxEventSource
Following copied from interface: org.greybird.xmliter.SaxEventSource
Throws:
java.io.IOException - if an error occurs retrieving input data.
XmlIteratorException - if an error occurs processing input data.

Copyright (c) 2003 Mark T. Hayes; All Rights Reserved