19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License. 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License. 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: IncrementalSAXSource_Filter.java 468653 2006-10-28 07:07:05Z minchau $ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xml.dtm.ref; 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.io.IOException; 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLErrorResources; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.res.XMLMessages; 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.ThreadControllerWrapper; 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Attributes; 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.ContentHandler; 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.DTDHandler; 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.ErrorHandler; 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.InputSource; 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.Locator; 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXException; 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXNotRecognizedException; 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXNotSupportedException; 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXParseException; 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.XMLReader; 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.ext.LexicalHandler; 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** <p>IncrementalSAXSource_Filter implements IncrementalSAXSource, using a 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * standard SAX2 event source as its input and parcelling out those 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * events gradually in reponse to deliverMoreNodes() requests. Output from the 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * filter will be passed along to a SAX handler registered as our 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * listener, but those callbacks will pass through a counting stage 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * which periodically yields control back to the controller coroutine. 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </p> 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>%REVIEW%: This filter is not currenly intended to be reusable 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for parsing additional streams/documents. We may want to consider 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * making it resettable at some point in the future. But it's a 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * small object, so that'd be mostly a convenience issue; the cost 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of allocating each time is trivial compared to the cost of processing 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * any nontrival stream.</p> 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>For a brief usage example, see the unit-test main() method.</p> 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>This is a simplification of the old CoroutineSAXParser, focusing 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * specifically on filtering. The resulting controller protocol is _far_ 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * simpler and less error-prone; the only controller operation is deliverMoreNodes(), 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * and the only requirement is that deliverMoreNodes(false) be called if you want to 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * discard the rest of the stream and the previous deliverMoreNodes() didn't return 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * false. 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class IncrementalSAXSource_Filter 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimplements IncrementalSAXSource, ContentHandler, DTDHandler, LexicalHandler, ErrorHandler, Runnable 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean DEBUG=false; //Internal status report 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Data 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private CoroutineManager fCoroutineManager = null; 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int fControllerCoroutineID = -1; 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int fSourceCoroutineID = -1; 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private ContentHandler clientContentHandler=null; // %REVIEW% support multiple? 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private LexicalHandler clientLexicalHandler=null; // %REVIEW% support multiple? 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private DTDHandler clientDTDHandler=null; // %REVIEW% support multiple? 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private ErrorHandler clientErrorHandler=null; // %REVIEW% support multiple? 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int eventcounter; 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int frequency=5; 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Flag indicating that no more events should be delivered -- either 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // because input stream ran to completion (endDocument), or because 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the user requested an early stop via deliverMoreNodes(false). 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private boolean fNoMoreEvents=false; 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Support for startParse() 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private XMLReader fXMLReader=null; 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private InputSource fXMLReaderInputSource=null; 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Constructors 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public IncrementalSAXSource_Filter() { 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.init( new CoroutineManager(), -1, -1); 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Create a IncrementalSAXSource_Filter which is not yet bound to a specific 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * SAX event source. 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public IncrementalSAXSource_Filter(CoroutineManager co, int controllerCoroutineID) 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this.init( co, controllerCoroutineID, -1 ); 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Factories 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static public IncrementalSAXSource createIncrementalSAXSource(CoroutineManager co, int controllerCoroutineID) { 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return new IncrementalSAXSource_Filter(co, controllerCoroutineID); 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Public methods 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void init( CoroutineManager co, int controllerCoroutineID, 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int sourceCoroutineID) 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(co==null) 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co = new CoroutineManager(); 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fCoroutineManager = co; 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fControllerCoroutineID = co.co_joinCoroutineSet(controllerCoroutineID); 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fSourceCoroutineID = co.co_joinCoroutineSet(sourceCoroutineID); 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (fControllerCoroutineID == -1 || fSourceCoroutineID == -1) 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new RuntimeException(XMLMessages.createXMLMessage(XMLErrorResources.ER_COJOINROUTINESET_FAILED, null)); //"co_joinCoroutineSet() failed"); 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fNoMoreEvents=false; 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Bind our input streams to an XMLReader. 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Just a convenience routine; obviously you can explicitly register 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * this as a listener with the same effect. 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setXMLReader(XMLReader eventsource) 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXMLReader=eventsource; 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventsource.setContentHandler(this); 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventsource.setDTDHandler(this); 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventsource.setErrorHandler(this); // to report fatal errors in filtering mode 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Not supported by all SAX2 filters: 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventsource. 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson setProperty("http://xml.org/sax/properties/lexical-handler", 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson this); 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(SAXNotRecognizedException e) 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Nothing we can do about it 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(SAXNotSupportedException e) 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Nothing we can do about it 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Should we also bind as other varieties of handler? 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // (DTDHandler and so on) 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Register a content handler for us to output to 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setContentHandler(ContentHandler handler) 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler=handler; 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Register a DTD handler for us to output to 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setDTDHandler(DTDHandler handler) 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientDTDHandler=handler; 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Register a lexical handler for us to output to 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Not all filters support this... 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ??? Should we register directly on the filter? 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // NOTE NAME -- subclassing issue in the Xerces version 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setLexicalHandler(LexicalHandler handler) 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler=handler; 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Register an error handler for us to output to 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // NOTE NAME -- subclassing issue in the Xerces version 1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setErrHandler(ErrorHandler handler) 1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientErrorHandler=handler; 1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Set the number of events between resumes of our coroutine 1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Immediately resets number of events before _next_ resume as well. 1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setReturnFrequency(int events) 1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(events<1) events=1; 1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson frequency=eventcounter=events; 2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ContentHandler methods 2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // These pass the data to our client ContentHandler... 2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // but they also count the number of events passing through, 2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // and resume our coroutine each time that counter hits zero and 2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // is reset. 2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Note that for everything except endDocument and fatalError, we do the count-and-yield 2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // BEFORE passing the call along. I'm hoping that this will encourage JIT 2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // compilers to realize that these are tail-calls, reducing the expense of 2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // the additional layer of data flow. 2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% Glenn suggests that pausing after endElement, endDocument, 2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // and characters may be sufficient. I actually may not want to 2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // stop after characters, since in our application these wind up being 2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // concatenated before they're processed... but that risks huge blocks of 2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // text causing greater than usual readahead. (Unlikely? Consider the 2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // possibility of a large base-64 block in a SOAP stream.) 2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void characters(char[] ch, int start, int length) 2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.characters(ch,start,length); 2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void endDocument() 2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // EXCEPTION: In this case we need to run the event BEFORE we yield. 2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.endDocument(); 2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=0; 2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(false); 2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void endElement(java.lang.String namespaceURI, java.lang.String localName, 2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson java.lang.String qName) 2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.endElement(namespaceURI,localName,qName); 2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void endPrefixMapping(java.lang.String prefix) 2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.endPrefixMapping(prefix); 2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void ignorableWhitespace(char[] ch, int start, int length) 2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.ignorableWhitespace(ch,start,length); 2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void processingInstruction(java.lang.String target, java.lang.String data) 2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.processingInstruction(target,data); 2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setDocumentLocator(Locator locator) 2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // This can cause a hang. -sb 2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // co_yield(true); 2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.setDocumentLocator(locator); 2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void skippedEntity(java.lang.String name) 2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.skippedEntity(name); 3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startDocument() 3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_entry_pause(); 3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Otherwise, begin normal event delivery 3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.startDocument(); 3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startElement(java.lang.String namespaceURI, java.lang.String localName, 3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson java.lang.String qName, Attributes atts) 3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.startElement(namespaceURI, localName, qName, atts); 3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startPrefixMapping(java.lang.String prefix, java.lang.String uri) 3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(clientContentHandler!=null) 3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientContentHandler.startPrefixMapping(prefix,uri); 3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // LexicalHandler support. Not all SAX2 filters support these events 3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // but we may want to pass them through when they exist... 3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% These do NOT currently affect the eventcounter; I'm asserting 3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // that they're rare enough that it makes little or no sense to 3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // pause after them. As such, it may make more sense for folks who 3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // actually want to use them to register directly with the filter. 3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // But I want 'em here for now, to remind us to recheck this assertion! 3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void comment(char[] ch, int start, int length) 3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientLexicalHandler) 3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler.comment(ch,start,length); 3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void endCDATA() 3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientLexicalHandler) 3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler.endCDATA(); 3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void endDTD() 3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientLexicalHandler) 3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler.endDTD(); 3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void endEntity(java.lang.String name) 3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientLexicalHandler) 3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler.endEntity(name); 3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startCDATA() 3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientLexicalHandler) 3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler.startCDATA(); 3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startDTD(java.lang.String name, java.lang.String publicId, 3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson java.lang.String systemId) 3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientLexicalHandler) 3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler. startDTD(name, publicId, systemId); 3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startEntity(java.lang.String name) 3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws org.xml.sax.SAXException 3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientLexicalHandler) 3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientLexicalHandler.startEntity(name); 3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // DTDHandler support. 4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void notationDecl(String a, String b, String c) throws SAXException 4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientDTDHandler) 4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientDTDHandler.notationDecl(a,b,c); 4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void unparsedEntityDecl(String a, String b, String c, String d) throws SAXException 4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientDTDHandler) 4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientDTDHandler.unparsedEntityDecl(a,b,c,d); 4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // ErrorHandler support. 4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // PROBLEM: Xerces is apparently _not_ calling the ErrorHandler for 4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // exceptions thrown by the ContentHandler, which prevents us from 4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // handling this properly when running in filtering mode with Xerces 4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // as our event source. It's unclear whether this is a Xerces bug 4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // or a SAX design flaw. 4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // %REVIEW% Current solution: In filtering mode, it is REQUIRED that 4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // event source make sure this method is invoked if the event stream 4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // abends before endDocument is delivered. If that means explicitly calling 4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // us in the exception handling code because it won't be delivered as part 4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // of the normal SAX ErrorHandler stream, that's fine; Not Our Problem. 4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void error(SAXParseException exception) throws SAXException 4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientErrorHandler) 4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientErrorHandler.error(exception); 4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void fatalError(SAXParseException exception) throws SAXException 4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // EXCEPTION: In this case we need to run the event BEFORE we yield -- 4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // just as with endDocument, this terminates the event stream. 4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientErrorHandler) 4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientErrorHandler.error(exception); 4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=0; 4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(false); 4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void warning(SAXParseException exception) throws SAXException 4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null!=clientErrorHandler) 4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson clientErrorHandler.error(exception); 4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // coroutine support 4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int getSourceCoroutineID() { 4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return fSourceCoroutineID; 4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int getControllerCoroutineID() { 4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return fControllerCoroutineID; 4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** @return the CoroutineManager this CoroutineFilter object is bound to. 4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * If you're using the do...() methods, applications should only 4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * need to talk to the CoroutineManager once, to obtain the 4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * application's Coroutine ID. 4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public CoroutineManager getCoroutineManager() 4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return fCoroutineManager; 4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** <p>In the SAX delegation code, I've inlined the count-down in 4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the hope of encouraging compilers to deliver better 4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * performance. However, if we subclass (eg to directly connect the 4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * output to a DTM builder), that would require calling super in 4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * order to run that logic... which seems inelegant. Hence this 4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * routine for the convenience of subclasses: every [frequency] 4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * invocations, issue a co_yield.</p> 4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param moreExepected Should always be true unless this is being called 4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * at the end of endDocument() handling. 4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected void count_and_yield(boolean moreExpected) throws SAXException 4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(!moreExpected) eventcounter=0; 4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(--eventcounter<=0) 4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(true); 4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson eventcounter=frequency; 4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * co_entry_pause is called in startDocument() before anything else 5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * happens. It causes the filter to wait for a "go ahead" request 5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * from the controller before delivering any events. Note that 5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * the very first thing the controller tells us may be "I don't 5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * need events after all"! 5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private void co_entry_pause() throws SAXException 5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fCoroutineManager==null) 5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Nobody called init()? Do it now... 5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson init(null,-1,-1); 5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Object arg=fCoroutineManager.co_entry_pause(fSourceCoroutineID); 5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(arg==Boolean.FALSE) 5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson co_yield(false); 5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(NoSuchMethodException e) 5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Coroutine system says we haven't registered. That's an 5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // application coding error, and is unrecoverable. 5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DEBUG) e.printStackTrace(); 5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new SAXException(e); 5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Co_Yield handles coroutine interactions while a parse is in progress. 5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * When moreRemains==true, we are pausing after delivering events, to 5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ask if more are needed. We will resume the controller thread with 5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * co_resume(Boolean.TRUE, ...) 5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * When control is passed back it may indicate 5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Boolean.TRUE indication to continue delivering events 5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Boolean.FALSE indication to discontinue events and shut down. 5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * When moreRemains==false, we shut down immediately without asking the 5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * controller's permission. Normally this means end of document has been 5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * reached. 5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Shutting down a IncrementalSAXSource_Filter requires terminating the incoming 5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * SAX event stream. If we are in control of that stream (if it came 5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * from an XMLReader passed to our startReader() method), we can do so 5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * very quickly by throwing a reserved exception to it. If the stream is 5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * coming from another source, we can't do that because its caller may 5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * not be prepared for this "normal abnormal exit", and instead we put 5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * ourselves in a "spin" mode where events are discarded. 5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private void co_yield(boolean moreRemains) throws SAXException 5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Horrendous kluge to run filter to completion. See below. 5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fNoMoreEvents) 5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return; 5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try // Coroutine manager might throw no-such. 5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Object arg=Boolean.FALSE; 5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(moreRemains) 5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Yield control, resume parsing when done 5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson arg = fCoroutineManager.co_resume(Boolean.TRUE, fSourceCoroutineID, 5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fControllerCoroutineID); 5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If we're at end of document or were told to stop early 5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(arg==Boolean.FALSE) 5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fNoMoreEvents=true; 5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fXMLReader!=null) // Running under startParseThread() 5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new StopException(); // We'll co_exit from there. 5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Yield control. We do NOT expect anyone to ever ask us again. 5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fCoroutineManager.co_exit_to(Boolean.FALSE, fSourceCoroutineID, 5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fControllerCoroutineID); 5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(NoSuchMethodException e) 5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Shouldn't happen unless we've miscoded our coroutine logic 5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // "Shut down the garbage smashers on the detention level!" 5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fNoMoreEvents=true; 5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fCoroutineManager.co_exit(fSourceCoroutineID); 5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new SAXException(e); 5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Convenience: Run an XMLReader in a thread 5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // 5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Launch a thread that will run an XMLReader's parse() operation within 5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * a thread, feeding events to this IncrementalSAXSource_Filter. Mostly a convenience 5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * routine, but has the advantage that -- since we invoked parse() -- 5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * we can halt parsing quickly via a StopException rather than waiting 5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * for the SAX stream to end by itself. 5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws SAXException is parse thread is already in progress 6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or parsing can not be started. 6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void startParse(InputSource source) throws SAXException 6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fNoMoreEvents) 6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new SAXException(XMLMessages.createXMLMessage(XMLErrorResources.ER_INCRSAXSRCFILTER_NOT_RESTARTABLE, null)); //"IncrmentalSAXSource_Filter not currently restartable."); 6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fXMLReader==null) 6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new SAXException(XMLMessages.createXMLMessage(XMLErrorResources.ER_XMLRDR_NOT_BEFORE_STARTPARSE, null)); //"XMLReader not before startParse request"); 6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXMLReaderInputSource=source; 6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Xalan thread pooling... 6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // org.apache.xalan.transformer.TransformerImpl.runTransformThread(this); 6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ThreadControllerWrapper.runThread(this, -1); 6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* Thread logic to support startParseThread() 6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void run() 6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Guard against direct invocation of start(). 6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fXMLReader==null) return; 6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DEBUG)System.out.println("IncrementalSAXSource_Filter parse thread launched"); 6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Initially assume we'll run successfully. 6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Object arg=Boolean.FALSE; 6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // For the duration of this operation, all coroutine handshaking 6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // will occur in the co_yield method. That's the nice thing about 6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // coroutines; they give us a way to hand off control from the 6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // middle of a synchronous method. 6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXMLReader.parse(fXMLReaderInputSource); 6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(IOException ex) 6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson arg=ex; 6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(StopException ex) 6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Expected and harmless 6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DEBUG)System.out.println("Active IncrementalSAXSource_Filter normal stop exception"); 6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch (SAXException ex) 6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Exception inner=ex.getException(); 6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(inner instanceof StopException){ 6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Expected and harmless 6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DEBUG)System.out.println("Active IncrementalSAXSource_Filter normal stop exception"); 6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else 6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Unexpected malfunction 6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(DEBUG) 6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("Active IncrementalSAXSource_Filter UNEXPECTED SAX exception: "+inner); 6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson inner.printStackTrace(); 6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson arg=ex; 6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // end parse 6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Mark as no longer running in thread. 6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fXMLReader=null; 6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Mark as done and yield control to the controller coroutine 6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fNoMoreEvents=true; 6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fCoroutineManager.co_exit_to(arg, fSourceCoroutineID, 6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fControllerCoroutineID); 6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(java.lang.NoSuchMethodException e) 6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Shouldn't happen unless we've miscoded our coroutine logic 6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // "CPO, shut down the garbage smashers on the detention level!" 6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson e.printStackTrace(System.err); 6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fCoroutineManager.co_exit(fSourceCoroutineID); 6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Used to quickly terminate parse when running under a 6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson startParse() thread. Only its type is important. */ 6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson class StopException extends RuntimeException 6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson static final long serialVersionUID = -1129245796185754956L; 6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** deliverMoreNodes() is a simple API which tells the coroutine 6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * parser that we need more nodes. This is intended to be called 6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * from one of our partner routines, and serves to encapsulate the 6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * details of how incremental parsing has been achieved. 6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param parsemore If true, tells the incremental filter to generate 6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * another chunk of output. If false, tells the filter that we're 6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * satisfied and it can terminate parsing of this document. 6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return Boolean.TRUE if there may be more events available by invoking 7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * deliverMoreNodes() again. Boolean.FALSE if parsing has run to completion (or been 7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * terminated by deliverMoreNodes(false). Or an exception object if something 7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * malfunctioned. %REVIEW% We _could_ actually throw the exception, but 7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * that would require runinng deliverMoreNodes() in a try/catch... and for many 7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * applications, exception will be simply be treated as "not TRUE" in 7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * any case. 7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * */ 7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public Object deliverMoreNodes(boolean parsemore) 7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If parsing is already done, we can immediately say so 7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(fNoMoreEvents) 7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return Boolean.FALSE; 7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Object result = 7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fCoroutineManager.co_resume(parsemore?Boolean.TRUE:Boolean.FALSE, 7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fControllerCoroutineID, fSourceCoroutineID); 7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(result==Boolean.FALSE) 7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson fCoroutineManager.co_exit(fControllerCoroutineID); 7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return result; 7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // SHOULD NEVER OCCUR, since the coroutine number and coroutine manager 7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // are those previously established for this IncrementalSAXSource_Filter... 7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // So I'm just going to return it as a parsing exception, for now. 7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(NoSuchMethodException e) 7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return e; 7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson //================================================================ 7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** Simple unit test. Attempt coroutine parsing of document indicated 7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * by first argument (as a URI), report progress. 7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /* 7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public static void main(String args[]) 7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("Starting..."); 7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.xml.sax.XMLReader theSAXParser= 7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new org.apache.xerces.parsers.SAXParser(); 7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(int arg=0;arg<args.length;++arg) 7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // The filter is not currently designed to be restartable 7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // after a parse has ended. Generate a new one each time. 7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson IncrementalSAXSource_Filter filter= 7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson new IncrementalSAXSource_Filter(); 7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Use a serializer as our sample output 7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xml.serialize.XMLSerializer trace; 7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson trace=new org.apache.xml.serialize.XMLSerializer(System.out,null); 7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson filter.setContentHandler(trace); 7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson filter.setLexicalHandler(trace); 7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson try 7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson InputSource source = new InputSource(args[arg]); 7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson Object result=null; 7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson boolean more=true; 7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // init not issued; we _should_ automagically Do The Right Thing 7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Bind parser, kick off parsing in a thread 7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson filter.setXMLReader(theSAXParser); 7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson filter.startParse(source); 7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson for(result = filter.deliverMoreNodes(more); 7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (result instanceof Boolean && ((Boolean)result)==Boolean.TRUE); 7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson result = filter.deliverMoreNodes(more)) 7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("\nSome parsing successful, trying more.\n"); 7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Special test: Terminate parsing early. 7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(arg+1<args.length && "!".equals(args[arg+1])) 7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ++arg; 7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson more=false; 7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (result instanceof Boolean && ((Boolean)result)==Boolean.FALSE) 7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("\nFilter ended (EOF or on request).\n"); 7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else if (result == null) { 7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("\nUNEXPECTED: Filter says shut down prematurely.\n"); 7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson else if (result instanceof Exception) { 7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.out.println("\nFilter threw exception:"); 7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson ((Exception)result).printStackTrace(); 7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson catch(SAXException e) 8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson e.printStackTrace(); 8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } // end for 8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} // class IncrementalSAXSource_Filter 808