incrementalsaxsource_filter.java

来自「JAVA 所有包」· Java 代码 · 共 806 行 · 第 1/2 页

JAVA
806
字号
/* * Copyright 1999-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: IncrementalSAXSource_Filter.java,v 1.2.4.1 2005/09/15 08:15:07 suresh_emailid Exp $ */package com.sun.org.apache.xml.internal.dtm.ref;import java.io.IOException;import com.sun.org.apache.xml.internal.res.XMLErrorResources;import com.sun.org.apache.xml.internal.res.XMLMessages;import com.sun.org.apache.xml.internal.utils.ThreadControllerWrapper;import org.xml.sax.Attributes;import org.xml.sax.ContentHandler;import org.xml.sax.DTDHandler;import org.xml.sax.ErrorHandler;import org.xml.sax.InputSource;import org.xml.sax.Locator;import org.xml.sax.SAXException;import org.xml.sax.SAXNotRecognizedException;import org.xml.sax.SAXNotSupportedException;import org.xml.sax.SAXParseException;import org.xml.sax.XMLReader;import org.xml.sax.ext.LexicalHandler;/** <p>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. * </p> * * <p>%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.</p> * * <p>For a brief usage example, see the unit-test main() method.</p> * * <p>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. * */public class IncrementalSAXSource_Filterimplements IncrementalSAXSource, ContentHandler, DTDHandler, LexicalHandler, ErrorHandler, Runnable{  boolean DEBUG=false; //Internal status report  //  // Data  //  private CoroutineManager fCoroutineManager = null;  private int fControllerCoroutineID = -1;  private int fSourceCoroutineID = -1;  private ContentHandler clientContentHandler=null; // %REVIEW% support multiple?  private LexicalHandler clientLexicalHandler=null; // %REVIEW% support multiple?  private DTDHandler clientDTDHandler=null; // %REVIEW% support multiple?  private ErrorHandler clientErrorHandler=null; // %REVIEW% support multiple?  private int eventcounter;  private int frequency=5;  // Flag indicating that no more events should be delivered -- either  // because input stream ran to completion (endDocument), or because  // the user requested an early stop via deliverMoreNodes(false).  private boolean fNoMoreEvents=false;  // Support for startParse()  private XMLReader fXMLReader=null;  private InputSource fXMLReaderInputSource=null;  //  // Constructors  //  public IncrementalSAXSource_Filter() {    this.init( new CoroutineManager(), -1, -1);  }    /** Create a IncrementalSAXSource_Filter which is not yet bound to a specific   * SAX event source.   * */  public IncrementalSAXSource_Filter(CoroutineManager co, int controllerCoroutineID)  {    this.init( co, controllerCoroutineID, -1 );  }  //  // Factories  //  static public IncrementalSAXSource createIncrementalSAXSource(CoroutineManager co, int controllerCoroutineID) {    return new IncrementalSAXSource_Filter(co, controllerCoroutineID);  }  //  // Public methods  //  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;  }      /** 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 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)  }  // Register a content handler for us to output to  public void setContentHandler(ContentHandler handler)  {    clientContentHandler=handler;  }  // Register a DTD handler for us to output to  public void setDTDHandler(DTDHandler handler)  {    clientDTDHandler=handler;  }  // Register a lexical handler for us to output to  // Not all filters support this...  // ??? Should we register directly on the filter?  // NOTE NAME -- subclassing issue in the Xerces version  public void setLexicalHandler(LexicalHandler handler)  {    clientLexicalHandler=handler;  }  // Register an error handler for us to output to  // NOTE NAME -- subclassing issue in the Xerces version  public void setErrHandler(ErrorHandler handler)  {    clientErrorHandler=handler;  }  // Set the number of events between resumes of our coroutine  // Immediately resets number of events before _next_ resume as well.  public void setReturnFrequency(int events)  {    if(events<1) events=1;    frequency=eventcounter=events;  }    //  // ContentHandler methods  // These  pass the data to our client ContentHandler...  // but they also count the number of events passing through,  // and resume our coroutine each time that counter hits zero and  // is reset.  //  // Note that for everything except endDocument and fatalError, we do the count-and-yield  // BEFORE passing the call along. I'm hoping that this will encourage JIT  // compilers to realize that these are tail-calls, reducing the expense of  // the additional layer of data flow.  //  // %REVIEW% Glenn suggests that pausing after endElement, endDocument,  // and characters may be sufficient. I actually may not want to  // stop after characters, since in our application these wind up being  // concatenated before they're processed... but that risks huge blocks of  // text causing greater than usual readahead. (Unlikely? Consider the  // possibility of a large base-64 block in a SOAP stream.)  //  public void characters(char[] ch, int start, int length)       throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.characters(ch,start,length);  }  public void endDocument()        throws org.xml.sax.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(java.lang.String namespaceURI, java.lang.String localName,      java.lang.String qName)        throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.endElement(namespaceURI,localName,qName);  }  public void endPrefixMapping(java.lang.String prefix)        throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.endPrefixMapping(prefix);  }  public void ignorableWhitespace(char[] ch, int start, int length)        throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.ignorableWhitespace(ch,start,length);  }  public void processingInstruction(java.lang.String target, java.lang.String data)        throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.processingInstruction(target,data);  }  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 skippedEntity(java.lang.String name)        throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.skippedEntity(name);  }  public void startDocument()        throws org.xml.sax.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(java.lang.String namespaceURI, java.lang.String localName,      java.lang.String qName, Attributes atts)        throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.startElement(namespaceURI, localName, qName, atts);  }  public void startPrefixMapping(java.lang.String prefix, java.lang.String uri)        throws org.xml.sax.SAXException  {    if(--eventcounter<=0)      {        co_yield(true);        eventcounter=frequency;      }    if(clientContentHandler!=null)      clientContentHandler.startPrefixMapping(prefix,uri);  }  //  // LexicalHandler support. Not all SAX2 filters support these events  // but we may want to pass them through when they exist...  //  // %REVIEW% These do NOT currently affect the eventcounter; I'm asserting  // that they're rare enough that it makes little or no sense to  // pause after them. As such, it may make more sense for folks who  // actually want to use them to register directly with the filter.  // But I want 'em here for now, to remind us to recheck this assertion!  //  public void comment(char[] ch, int start, int length)        throws org.xml.sax.SAXException  {    if(null!=clientLexicalHandler)      clientLexicalHandler.comment(ch,start,length);  }  public void endCDATA()        throws org.xml.sax.SAXException  {    if(null!=clientLexicalHandler)      clientLexicalHandler.endCDATA();  }  public void endDTD()        throws org.xml.sax.SAXException  {    if(null!=clientLexicalHandler)      clientLexicalHandler.endDTD();  }  public void endEntity(java.lang.String name)        throws org.xml.sax.SAXException  {    if(null!=clientLexicalHandler)      clientLexicalHandler.endEntity(name);  }  public void startCDATA()        throws org.xml.sax.SAXException  {    if(null!=clientLexicalHandler)      clientLexicalHandler.startCDATA();  }  public void startDTD(java.lang.String name, java.lang.String publicId,      java.lang.String systemId)        throws org.xml.sax.SAXException  {    if(null!=clientLexicalHandler)      clientLexicalHandler. startDTD(name, publicId, systemId);  }  public void startEntity(java.lang.String name)        throws org.xml.sax.SAXException  {    if(null!=clientLexicalHandler)      clientLexicalHandler.startEntity(name);  }  //  // DTDHandler support.    public void notationDecl(String a, String b, String c) throws SAXException  {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?