incrementalsaxsource_filter.java

来自「java jdk 1.4的源码」· Java 代码 · 共 841 行 · 第 1/2 页

JAVA
841
字号
/* * The Apache Software License, Version 1.1 * * * Copyright (c) 1999,2000 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 "Xerces" 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, International * Business Machines, Inc., http://www.apache.org.  For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */package org.apache.xml.dtm.ref;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import org.xml.sax.SAXNotRecognizedException;import org.xml.sax.SAXNotSupportedException;import org.xml.sax.ext.LexicalHandler;import org.xml.sax.ContentHandler;import org.xml.sax.DTDHandler;import org.xml.sax.ErrorHandler;import org.xml.sax.Locator;import org.xml.sax.Attributes;import org.xml.sax.XMLReader;import java.io.IOException;import org.apache.xml.dtm.ref.IncrementalSAXSource;import org.apache.xalan.res.XSLTErrorResources;import org.apache.xalan.res.XSLMessages;/** <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(XSLMessages.createMessage(XSLTErrorResources.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();  }

⌨️ 快捷键说明

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