| Method from com.sun.org.apache.xml.internal.dtm.ref.IncrementalSAXSource_Filter Detail: |
public void characters(char[] ch,
int start,
int length) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.characters(ch,start,length);
}
|
public void comment(char[] ch,
int start,
int length) throws SAXException {
if(null!=clientLexicalHandler)
clientLexicalHandler.comment(ch,start,length);
}
|
protected void count_and_yield(boolean moreExpected) throws SAXException {
if(!moreExpected) eventcounter=0;
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
}
In the SAX delegation code, I've inlined the count-down in
the hope of encouraging compilers to deliver better
performance. However, if we subclass (eg to directly connect the
output to a DTM builder), that would require calling super in
order to run that logic... which seems inelegant. Hence this
routine for the convenience of subclasses: every [frequency]
invocations, issue a co_yield.
|
public static IncrementalSAXSource createIncrementalSAXSource(CoroutineManager co,
int controllerCoroutineID) {
return new IncrementalSAXSource_Filter(co, controllerCoroutineID);
}
|
public Object deliverMoreNodes(boolean parsemore) {
// If parsing is already done, we can immediately say so
if(fNoMoreEvents)
return Boolean.FALSE;
try
{
Object result =
fCoroutineManager.co_resume(parsemore?Boolean.TRUE:Boolean.FALSE,
fControllerCoroutineID, fSourceCoroutineID);
if(result==Boolean.FALSE)
fCoroutineManager.co_exit(fControllerCoroutineID);
return result;
}
// SHOULD NEVER OCCUR, since the coroutine number and coroutine manager
// are those previously established for this IncrementalSAXSource_Filter...
// So I'm just going to return it as a parsing exception, for now.
catch(NoSuchMethodException e)
{
return e;
}
}
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. |
public void endCDATA() throws SAXException {
if(null!=clientLexicalHandler)
clientLexicalHandler.endCDATA();
}
|
public void endDTD() throws SAXException {
if(null!=clientLexicalHandler)
clientLexicalHandler.endDTD();
}
|
public void endDocument() throws SAXException {
// EXCEPTION: In this case we need to run the event BEFORE we yield.
if(clientContentHandler!=null)
clientContentHandler.endDocument();
eventcounter=0;
co_yield(false);
}
|
public void endElement(String namespaceURI,
String localName,
String qName) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.endElement(namespaceURI,localName,qName);
}
|
public void endEntity(String name) throws SAXException {
if(null!=clientLexicalHandler)
clientLexicalHandler.endEntity(name);
}
|
public void endPrefixMapping(String prefix) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.endPrefixMapping(prefix);
}
|
public void error(SAXParseException exception) throws SAXException {
if(null!=clientErrorHandler)
clientErrorHandler.error(exception);
}
|
public void fatalError(SAXParseException exception) throws SAXException {
// EXCEPTION: In this case we need to run the event BEFORE we yield --
// just as with endDocument, this terminates the event stream.
if(null!=clientErrorHandler)
clientErrorHandler.error(exception);
eventcounter=0;
co_yield(false);
}
|
public int getControllerCoroutineID() {
return fControllerCoroutineID;
}
|
public CoroutineManager getCoroutineManager() {
return fCoroutineManager;
}
|
public int getSourceCoroutineID() {
return fSourceCoroutineID;
}
|
public void ignorableWhitespace(char[] ch,
int start,
int length) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.ignorableWhitespace(ch,start,length);
}
|
public void init(CoroutineManager co,
int controllerCoroutineID,
int sourceCoroutineID) {
if(co==null)
co = new CoroutineManager();
fCoroutineManager = co;
fControllerCoroutineID = co.co_joinCoroutineSet(controllerCoroutineID);
fSourceCoroutineID = co.co_joinCoroutineSet(sourceCoroutineID);
if (fControllerCoroutineID == -1 || fSourceCoroutineID == -1)
throw new RuntimeException(XMLMessages.createXMLMessage(XMLErrorResources.ER_COJOINROUTINESET_FAILED, null)); //"co_joinCoroutineSet() failed");
fNoMoreEvents=false;
eventcounter=frequency;
}
|
public void notationDecl(String a,
String b,
String c) throws SAXException {
if(null!=clientDTDHandler)
clientDTDHandler.notationDecl(a,b,c);
}
|
public void processingInstruction(String target,
String data) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.processingInstruction(target,data);
}
|
public void run() {
// Guard against direct invocation of start().
if(fXMLReader==null) return;
if(DEBUG)System.out.println("IncrementalSAXSource_Filter parse thread launched");
// Initially assume we'll run successfully.
Object arg=Boolean.FALSE;
// For the duration of this operation, all coroutine handshaking
// will occur in the co_yield method. That's the nice thing about
// coroutines; they give us a way to hand off control from the
// middle of a synchronous method.
try
{
fXMLReader.parse(fXMLReaderInputSource);
}
catch(IOException ex)
{
arg=ex;
}
catch(StopException ex)
{
// Expected and harmless
if(DEBUG)System.out.println("Active IncrementalSAXSource_Filter normal stop exception");
}
catch (SAXException ex)
{
Exception inner=ex.getException();
if(inner instanceof StopException){
// Expected and harmless
if(DEBUG)System.out.println("Active IncrementalSAXSource_Filter normal stop exception");
}
else
{
// Unexpected malfunction
if(DEBUG)
{
System.out.println("Active IncrementalSAXSource_Filter UNEXPECTED SAX exception: "+inner);
inner.printStackTrace();
}
arg=ex;
}
} // end parse
// Mark as no longer running in thread.
fXMLReader=null;
try
{
// Mark as done and yield control to the controller coroutine
fNoMoreEvents=true;
fCoroutineManager.co_exit_to(arg, fSourceCoroutineID,
fControllerCoroutineID);
}
catch(java.lang.NoSuchMethodException e)
{
// Shouldn't happen unless we've miscoded our coroutine logic
// "CPO, shut down the garbage smashers on the detention level!"
e.printStackTrace(System.err);
fCoroutineManager.co_exit(fSourceCoroutineID);
}
}
|
public void setContentHandler(ContentHandler handler) {
clientContentHandler=handler;
}
|
public void setDTDHandler(DTDHandler handler) {
clientDTDHandler=handler;
}
|
public void setDocumentLocator(Locator locator) {
if(--eventcounter< =0)
{
// This can cause a hang. -sb
// co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.setDocumentLocator(locator);
}
|
public void setErrHandler(ErrorHandler handler) {
clientErrorHandler=handler;
}
|
public void setLexicalHandler(LexicalHandler handler) {
clientLexicalHandler=handler;
}
|
public void setReturnFrequency(int events) {
if(events< 1) events=1;
frequency=eventcounter=events;
}
|
public void setXMLReader(XMLReader eventsource) {
fXMLReader=eventsource;
eventsource.setContentHandler(this);
eventsource.setDTDHandler(this);
eventsource.setErrorHandler(this); // to report fatal errors in filtering mode
// Not supported by all SAX2 filters:
try
{
eventsource.
setProperty("http://xml.org/sax/properties/lexical-handler",
this);
}
catch(SAXNotRecognizedException e)
{
// Nothing we can do about it
}
catch(SAXNotSupportedException e)
{
// Nothing we can do about it
}
// Should we also bind as other varieties of handler?
// (DTDHandler and so on)
}
Bind our input streams to an XMLReader.
Just a convenience routine; obviously you can explicitly register
this as a listener with the same effect. |
public void skippedEntity(String name) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.skippedEntity(name);
}
|
public void startCDATA() throws SAXException {
if(null!=clientLexicalHandler)
clientLexicalHandler.startCDATA();
}
|
public void startDTD(String name,
String publicId,
String systemId) throws SAXException {
if(null!=clientLexicalHandler)
clientLexicalHandler. startDTD(name, publicId, systemId);
}
|
public void startDocument() throws SAXException {
co_entry_pause();
// Otherwise, begin normal event delivery
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.startDocument();
}
|
public void startElement(String namespaceURI,
String localName,
String qName,
Attributes atts) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.startElement(namespaceURI, localName, qName, atts);
}
|
public void startEntity(String name) throws SAXException {
if(null!=clientLexicalHandler)
clientLexicalHandler.startEntity(name);
}
|
public void startParse(InputSource source) throws SAXException {
if(fNoMoreEvents)
throw new SAXException(XMLMessages.createXMLMessage(XMLErrorResources.ER_INCRSAXSRCFILTER_NOT_RESTARTABLE, null)); //"IncrmentalSAXSource_Filter not currently restartable.");
if(fXMLReader==null)
throw new SAXException(XMLMessages.createXMLMessage(XMLErrorResources.ER_XMLRDR_NOT_BEFORE_STARTPARSE, null)); //"XMLReader not before startParse request");
fXMLReaderInputSource=source;
// Xalan thread pooling...
// com.sun.org.apache.xalan.internal.transformer.TransformerImpl.runTransformThread(this);
ThreadControllerWrapper.runThread(this, -1);
}
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. |
public void startPrefixMapping(String prefix,
String uri) throws SAXException {
if(--eventcounter< =0)
{
co_yield(true);
eventcounter=frequency;
}
if(clientContentHandler!=null)
clientContentHandler.startPrefixMapping(prefix,uri);
}
|
public void unparsedEntityDecl(String a,
String b,
String c,
String d) throws SAXException {
if(null!=clientDTDHandler)
clientDTDHandler.unparsedEntityDecl(a,b,c,d);
}
|
public void warning(SAXParseException exception) throws SAXException {
if(null!=clientErrorHandler)
clientErrorHandler.error(exception);
}
|