001: /* Copyright 2001 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.utils;
007:
008: import java.io.IOException;
009:
010: import org.apache.commons.logging.Log;
011: import org.apache.commons.logging.LogFactory;
012: import org.xml.sax.Attributes;
013: import org.xml.sax.ContentHandler;
014: import org.xml.sax.DTDHandler;
015: import org.xml.sax.EntityResolver;
016: import org.xml.sax.ErrorHandler;
017: import org.xml.sax.InputSource;
018: import org.xml.sax.Locator;
019: import org.xml.sax.SAXException;
020: import org.xml.sax.SAXNotRecognizedException;
021: import org.xml.sax.SAXNotSupportedException;
022: import org.xml.sax.SAXParseException;
023: import org.xml.sax.XMLFilter;
024: import org.xml.sax.XMLReader;
025: import org.xml.sax.ext.LexicalHandler;
026:
027: /**
028: * This is a remake of <code>org.xml.sax.helpers.XMLFilterImpl</code>
029: * that allows for downward chaining of LexicalHandlers, and further extensions.
030: * <p>Some of the behavior is slightly different from that of hte XMLFilterImpl.
031: * For example this implementation allows to set null handlers. It also redirects parent's handlers
032: * right after instantiation or setParent() invokation, not just at the parse().</p>
033: * @see org.xml.sax.helpers.XMLFilterImpl
034: */
035: public class SAX2FilterImpl implements XMLFilter, EntityResolver,
036: DTDHandler, ContentHandler, ErrorHandler, LexicalHandler {
037:
038: protected final Log log = LogFactory.getLog(getClass());
039:
040: // Internal state
041:
042: private XMLReader parent = null;
043: protected Locator locator = null;
044: protected EntityResolver entityResolver = null;
045: protected DTDHandler dtdHandler = null;
046: protected ContentHandler contentHandler = null;
047: protected ErrorHandler errorHandler = null;
048: protected LexicalHandler lexicalHandler = null;
049:
050: // Constructors
051:
052: /**
053: * Construct an empty XML filter, with no parent.
054: *
055: * <p>This filter will have no parent: you must assign a parent
056: * before you start a parse or do any configuration with
057: * setFeature or setProperty.</p>
058: *
059: * @see org.xml.sax.XMLReader#setFeature
060: * @see org.xml.sax.XMLReader#setProperty
061: */
062: public SAX2FilterImpl() {
063: super ();
064: }
065:
066: /**
067: * Construct an XML filter with the specified parent.
068: *
069: * @see #setParent
070: * @see #getParent
071: */
072: public SAX2FilterImpl(XMLReader parent) {
073: super ();
074: setParent(parent);
075: }
076:
077: /**
078: * Construct an XML filter with the specified children handlers.
079: * @see #setContentHandler
080: * @see #setDTDHandler
081: * @see #setErrorHandler
082: * @see #setEntityResolver
083: * @see #setLexicalHandler
084: */
085: public SAX2FilterImpl(ContentHandler ch, EntityResolver er,
086: ErrorHandler eh, LexicalHandler lh, DTDHandler dh) {
087: this ();
088: setContentHandler(ch);
089: setEntityResolver(er);
090: setErrorHandler(eh);
091: setDTDHandler(dh);
092: setLexicalHandler(lh);
093: }
094:
095: /**
096: * Try to imply all of the handlers from ContentHandler alone.
097: */
098: public SAX2FilterImpl(ContentHandler ch) {
099: this ();
100: setAllHandlers(ch);
101: }
102:
103: /**
104: * Try to imply all of the handlers from ContentHandler alone.
105: */
106: public void setAllHandlers(ContentHandler ch) {
107: setContentHandler(ch);
108: if (ch instanceof EntityResolver) {
109: setEntityResolver((EntityResolver) ch);
110: }
111: if (ch instanceof ErrorHandler) {
112: setErrorHandler((ErrorHandler) ch);
113: }
114: if (ch instanceof DTDHandler) {
115: setDTDHandler((DTDHandler) ch);
116: }
117: if (ch instanceof LexicalHandler) {
118: setLexicalHandler((LexicalHandler) ch);
119: }
120: }
121:
122: ////////////////////////////////////////////////////////////////////
123: // Implementation of org.xml.sax.XMLFilter.
124: ////////////////////////////////////////////////////////////////////
125:
126: /**
127: * Set the parent reader.
128: *
129: * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which
130: * this filter will obtain its events and to which it will pass its
131: * configuration requests. The parent may itself be another filter.</p>
132: *
133: * <p>If there is no parent reader set, any attempt to parse
134: * or to set or get a feature or property will fail.</p>
135: *
136: * @param parent The parent XML reader.
137: * @exception java.lang.NullPointerException If the parent is null.
138: * @see #getParent
139: */
140: public void setParent(XMLReader parent) {
141: if (parent == null) {
142: throw new NullPointerException("Null parent");
143: }
144: this .parent = parent;
145: setupParse();
146: }
147:
148: /**
149: * Get the parent reader.
150: *
151: * @return The parent XML reader, or null if none is set.
152: * @see #setParent
153: */
154: public XMLReader getParent() {
155: return parent;
156: }
157:
158: ////////////////////////////////////////////////////////////////////
159: // Implementation of org.xml.sax.XMLReader.
160: ////////////////////////////////////////////////////////////////////
161:
162: /**
163: * Set the state of a feature.
164: *
165: * <p>This will always fail if the parent is null.</p>
166: *
167: * @param name The feature name.
168: * @param state The requested feature state.
169: * @exception org.xml.sax.SAXNotRecognizedException When the
170: * XMLReader does not recognize the feature name.
171: * @exception org.xml.sax.SAXNotSupportedException When the
172: * XMLReader recognizes the feature name but
173: * cannot set the requested value.
174: * @see org.xml.sax.XMLReader#setFeature
175: */
176: public void setFeature(String name, boolean state)
177: throws SAXNotRecognizedException, SAXNotSupportedException {
178: if (parent != null) {
179: parent.setFeature(name, state);
180: } else {
181: throw new SAXNotRecognizedException("Feature: " + name);
182: }
183: }
184:
185: /**
186: * Look up the state of a feature.
187: *
188: * <p>This will always fail if the parent is null.</p>
189: *
190: * @param name The feature name.
191: * @return The current state of the feature.
192: * @exception org.xml.sax.SAXNotRecognizedException When the
193: * XMLReader does not recognize the feature name.
194: * @exception org.xml.sax.SAXNotSupportedException When the
195: * XMLReader recognizes the feature name but
196: * cannot determine its state at this time.
197: * @see org.xml.sax.XMLReader#getFeature
198: */
199: public boolean getFeature(String name)
200: throws SAXNotRecognizedException, SAXNotSupportedException {
201: if (parent != null) {
202: return parent.getFeature(name);
203: } else {
204: throw new SAXNotRecognizedException("Feature: " + name);
205: }
206: }
207:
208: /**
209: * Set the value of a property.
210: *
211: * <p>This will always fail if the parent is null.</p>
212: *
213: * @param name The property name.
214: * @param value The requested property value.
215: * @exception org.xml.sax.SAXNotRecognizedException When the
216: * XMLReader does not recognize the property name.
217: * @exception org.xml.sax.SAXNotSupportedException When the
218: * XMLReader recognizes the property name but
219: * cannot set the requested value.
220: * @see org.xml.sax.XMLReader#setProperty
221: */
222: public void setProperty(String name, Object value)
223: throws SAXNotRecognizedException, SAXNotSupportedException {
224: // monitor for lexical handler property
225: if (name.equals("http://xml.org/sax/handlers/LexicalHandler")) {
226: this .lexicalHandler = (LexicalHandler) value;
227: if (parent != null) {
228: parent.setProperty(name, this );
229: }
230: } else if (parent != null) {
231: parent.setProperty(name, value);
232: } else {
233: throw new SAXNotRecognizedException("Property: " + name);
234: }
235: }
236:
237: /**
238: * Look up the value of a property.
239: *
240: * @param name The property name.
241: * @return The current value of the property.
242: * @exception org.xml.sax.SAXNotRecognizedException When the
243: * XMLReader does not recognize the feature name.
244: * @exception org.xml.sax.SAXNotSupportedException When the
245: * XMLReader recognizes the property name but
246: * cannot determine its value at this time.
247: * @see org.xml.sax.XMLReader#setFeature
248: */
249: public Object getProperty(String name)
250: throws SAXNotRecognizedException, SAXNotSupportedException {
251: if (parent != null) {
252: return parent.getProperty(name);
253: } else {
254: throw new SAXNotRecognizedException("Property: " + name);
255: }
256: }
257:
258: /**
259: * Set the entity resolver.
260: *
261: * @param resolver The new entity resolver.
262: * @see org.xml.sax.XMLReader#setEntityResolver
263: */
264: public void setEntityResolver(EntityResolver resolver) {
265: entityResolver = resolver;
266: }
267:
268: /**
269: * Get the current entity resolver.
270: *
271: * @return The current entity resolver, or null if none was set.
272: * @see org.xml.sax.XMLReader#getEntityResolver
273: */
274: public EntityResolver getEntityResolver() {
275: return entityResolver;
276: }
277:
278: /**
279: * Set the DTD event handler.
280: *
281: * @param handler The new DTD handler.
282: * @see org.xml.sax.XMLReader#setDTDHandler
283: */
284: public void setDTDHandler(DTDHandler handler) {
285: dtdHandler = handler;
286: }
287:
288: /**
289: * Get the current DTD event handler.
290: *
291: * @return The current DTD handler, or null if none was set.
292: * @see org.xml.sax.XMLReader#getDTDHandler
293: */
294: public DTDHandler getDTDHandler() {
295: return dtdHandler;
296: }
297:
298: /**
299: * Set the content event handler.
300: *
301: * @param handler The new content handler.
302: * @see org.xml.sax.XMLReader#setContentHandler
303: */
304: public void setContentHandler(ContentHandler handler) {
305: contentHandler = handler;
306: }
307:
308: /**
309: * Get the content event handler.
310: *
311: * @return The current content handler, or null if none was set.
312: * @see org.xml.sax.XMLReader#getContentHandler
313: */
314: public ContentHandler getContentHandler() {
315: return contentHandler;
316: }
317:
318: /**
319: * Set the error event handler.
320: *
321: * @param handler The new error handler.
322: * @see org.xml.sax.XMLReader#setErrorHandler
323: */
324: public void setErrorHandler(ErrorHandler handler) {
325: errorHandler = handler;
326: }
327:
328: /**
329: * Set the lexical handler.
330: *
331: * @param handler The new lexical handler.
332: */
333: public void setLexicalHandler(LexicalHandler handler) {
334: lexicalHandler = handler;
335: if (lexicalHandler != null && parent != null) {
336: try {
337: parent.setProperty(
338: "http://xml.org/sax/handlers/LexicalHandler",
339: this );
340: } catch (SAXNotRecognizedException e1) {
341: } catch (SAXNotSupportedException e2) {
342: }
343: ;
344: }
345: }
346:
347: /**
348: * Get the current error event handler.
349: *
350: * @return The current error handler, or null if none was set.
351: * @see org.xml.sax.XMLReader#getErrorHandler
352: */
353: public ErrorHandler getErrorHandler() {
354: return errorHandler;
355: }
356:
357: /**
358: * Parse a document.
359: *
360: * @param input The input source for the document entity.
361: * @exception org.xml.sax.SAXException Any SAX exception, possibly
362: * wrapping another exception.
363: * @exception java.io.IOException An IO exception from the parser,
364: * possibly from a byte stream or character stream
365: * supplied by the application.
366: * @see org.xml.sax.XMLReader#parse(org.xml.sax.InputSource)
367: */
368: public void parse(InputSource input) throws SAXException,
369: IOException {
370: setupParse();
371: parent.parse(input);
372: }
373:
374: /**
375: * Parse a document.
376: *
377: * @param systemId The system identifier as a fully-qualified URI.
378: * @exception org.xml.sax.SAXException Any SAX exception, possibly
379: * wrapping another exception.
380: * @exception java.io.IOException An IO exception from the parser,
381: * possibly from a byte stream or character stream
382: * supplied by the application.
383: * @see org.xml.sax.XMLReader#parse(java.lang.String)
384: */
385: public void parse(String systemId) throws SAXException, IOException {
386: parse(new InputSource(systemId));
387: }
388:
389: ////////////////////////////////////////////////////////////////////
390: // Implementation of org.xml.sax.ext.LexicalHandler.
391: ////////////////////////////////////////////////////////////////////
392:
393: /**
394: * Filter startDTD event.
395: * @param name The document type name.
396: * @param publicId The declared public identifier for the
397: * external DTD subset, or null if none was declared.
398: * @param systemId The declared system identifier for the
399: * external DTD subset, or null if none was declared.
400: * @exception SAXException The application may raise an
401: * exception.
402: * @see #endDTD
403: * @see #startEntity
404: */
405: public void startDTD(String name, String publicId, String systemId)
406: throws SAXException {
407: if (lexicalHandler != null) {
408: lexicalHandler.startDTD(name, publicId, systemId);
409: }
410: }
411:
412: /**
413: * Filter endDTD event
414: *
415: * @exception SAXException The application may raise an exception.
416: * @see #startDTD
417: */
418: public void endDTD() throws SAXException {
419: if (lexicalHandler != null) {
420: lexicalHandler.endDTD();
421: }
422: }
423:
424: /**
425: * Filter startEntity event.
426: *
427: * @param name The name of the entity. If it is a parameter
428: * entity, the name will begin with '%'.
429: * @exception SAXException The application may raise an exception.
430: * @see #endEntity
431: * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
432: * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
433: */
434: public void startEntity(String name) throws SAXException {
435: if (lexicalHandler != null) {
436: lexicalHandler.startEntity(name);
437: }
438: }
439:
440: /**
441: * Filter endEntity event.
442: *
443: * @param name The name of the entity that is ending.
444: * @exception SAXException The application may raise an exception.
445: * @see #startEntity
446: */
447: public void endEntity(String name) throws SAXException {
448: if (lexicalHandler != null) {
449: lexicalHandler.endEntity(name);
450: }
451: }
452:
453: /**
454: * Filter startCDATA event.
455: *
456: * @exception SAXException The application may raise an exception.
457: * @see #endCDATA
458: */
459: public void startCDATA() throws SAXException {
460: if (lexicalHandler != null) {
461: lexicalHandler.startCDATA();
462: }
463: }
464:
465: /**
466: * Filter endCDATA event.
467: *
468: * @exception SAXException The application may raise an exception.
469: * @see #startCDATA
470: */
471: public void endCDATA() throws SAXException {
472: if (lexicalHandler != null) {
473: lexicalHandler.endCDATA();
474: }
475: }
476:
477: /**
478: * Filter comment event.
479: *
480: * @param ch An array holding the characters in the comment.
481: * @param start The starting position in the array.
482: * @param length The number of characters to use from the array.
483: * @exception SAXException The application may raise an exception.
484: */
485: public void comment(char ch[], int start, int length)
486: throws SAXException {
487: if (lexicalHandler != null) {
488: lexicalHandler.comment(ch, start, length);
489: }
490: }
491:
492: ////////////////////////////////////////////////////////////////////
493: // Implementation of org.xml.sax.EntityResolver.
494: ////////////////////////////////////////////////////////////////////
495:
496: /**
497: * Filter an external entity resolution.
498: *
499: * @param publicId The entity's public identifier, or null.
500: * @param systemId The entity's system identifier.
501: * @return A new InputSource or null for the default.
502: * @exception org.xml.sax.SAXException The client may throw
503: * an exception during processing.
504: * @exception java.io.IOException The client may throw an
505: * I/O-related exception while obtaining the
506: * new InputSource.
507: * @see org.xml.sax.EntityResolver#resolveEntity
508: */
509: public InputSource resolveEntity(String publicId, String systemId)
510: throws SAXException, IOException {
511: if (entityResolver != null) {
512: return entityResolver.resolveEntity(publicId, systemId);
513: } else {
514: return null;
515: }
516: }
517:
518: ////////////////////////////////////////////////////////////////////
519: // Implementation of org.xml.sax.DTDHandler.
520: ////////////////////////////////////////////////////////////////////
521:
522: /**
523: * Filter a notation declaration event.
524: *
525: * @param name The notation name.
526: * @param publicId The notation's public identifier, or null.
527: * @param systemId The notation's system identifier, or null.
528: * @exception org.xml.sax.SAXException The client may throw
529: * an exception during processing.
530: * @see org.xml.sax.DTDHandler#notationDecl
531: */
532: public void notationDecl(String name, String publicId,
533: String systemId) throws SAXException {
534: if (dtdHandler != null) {
535: dtdHandler.notationDecl(name, publicId, systemId);
536: }
537: }
538:
539: /**
540: * Filter an unparsed entity declaration event.
541: *
542: * @param name The entity name.
543: * @param publicId The entity's public identifier, or null.
544: * @param systemId The entity's system identifier, or null.
545: * @param notationName The name of the associated notation.
546: * @exception org.xml.sax.SAXException The client may throw
547: * an exception during processing.
548: * @see org.xml.sax.DTDHandler#unparsedEntityDecl
549: */
550: public void unparsedEntityDecl(String name, String publicId,
551: String systemId, String notationName) throws SAXException {
552: if (dtdHandler != null) {
553: dtdHandler.unparsedEntityDecl(name, publicId, systemId,
554: notationName);
555: }
556: }
557:
558: ////////////////////////////////////////////////////////////////////
559: // Implementation of org.xml.sax.ContentHandler.
560: ////////////////////////////////////////////////////////////////////
561:
562: /**
563: * Filter a new document locator event.
564: *
565: * @param locator The document locator.
566: * @see org.xml.sax.ContentHandler#setDocumentLocator
567: */
568: public void setDocumentLocator(Locator locator) {
569: this .locator = locator;
570: if (contentHandler != null) {
571: contentHandler.setDocumentLocator(locator);
572: }
573: }
574:
575: /**
576: * Filter a start document event.
577: *
578: * @exception org.xml.sax.SAXException The client may throw
579: * an exception during processing.
580: * @see org.xml.sax.ContentHandler#startDocument
581: */
582: public void startDocument() throws SAXException {
583: if (contentHandler != null) {
584: contentHandler.startDocument();
585: }
586: }
587:
588: /**
589: * Filter an end document event.
590: *
591: * @exception org.xml.sax.SAXException The client may throw
592: * an exception during processing.
593: * @see org.xml.sax.ContentHandler#endDocument
594: */
595: public void endDocument() throws SAXException {
596: if (contentHandler != null) {
597: contentHandler.endDocument();
598: }
599: }
600:
601: /**
602: * Filter a start Namespace prefix mapping event.
603: *
604: * @param prefix The Namespace prefix.
605: * @param uri The Namespace URI.
606: * @exception org.xml.sax.SAXException The client may throw
607: * an exception during processing.
608: * @see org.xml.sax.ContentHandler#startPrefixMapping
609: */
610: public void startPrefixMapping(String prefix, String uri)
611: throws SAXException {
612: if (contentHandler != null) {
613: contentHandler.startPrefixMapping(prefix, uri);
614: }
615: }
616:
617: /**
618: * Filter an end Namespace prefix mapping event.
619: *
620: * @param prefix The Namespace prefix.
621: * @exception org.xml.sax.SAXException The client may throw
622: * an exception during processing.
623: * @see org.xml.sax.ContentHandler#endPrefixMapping
624: */
625: public void endPrefixMapping(String prefix) throws SAXException {
626: if (contentHandler != null) {
627: contentHandler.endPrefixMapping(prefix);
628: }
629: }
630:
631: /**
632: * Filter a start element event.
633: *
634: * @param uri The element's Namespace URI, or the empty string.
635: * @param localName The element's local name, or the empty string.
636: * @param qName The element's qualified (prefixed) name, or the empty
637: * string.
638: * @param atts The element's attributes.
639: * @exception org.xml.sax.SAXException The client may throw
640: * an exception during processing.
641: * @see org.xml.sax.ContentHandler#startElement
642: */
643: public void startElement(String uri, String localName,
644: String qName, Attributes atts) throws SAXException {
645: if (contentHandler != null) {
646: contentHandler.startElement(uri, localName, qName, atts);
647: }
648: }
649:
650: /**
651: * Filter an end element event.
652: *
653: * @param uri The element's Namespace URI, or the empty string.
654: * @param localName The element's local name, or the empty string.
655: * @param qName The element's qualified (prefixed) name, or the empty
656: * string.
657: * @exception org.xml.sax.SAXException The client may throw
658: * an exception during processing.
659: * @see org.xml.sax.ContentHandler#endElement
660: */
661: public void endElement(String uri, String localName, String qName)
662: throws SAXException {
663: if (contentHandler != null) {
664: contentHandler.endElement(uri, localName, qName);
665: }
666: }
667:
668: /**
669: * Filter a character data event.
670: *
671: * @param ch An array of characters.
672: * @param start The starting position in the array.
673: * @param length The number of characters to use from the array.
674: * @exception org.xml.sax.SAXException The client may throw
675: * an exception during processing.
676: * @see org.xml.sax.ContentHandler#characters
677: */
678: public void characters(char ch[], int start, int length)
679: throws SAXException {
680: if (contentHandler != null) {
681: contentHandler.characters(ch, start, length);
682: }
683: }
684:
685: /**
686: * Filter an ignorable whitespace event.
687: *
688: * @param ch An array of characters.
689: * @param start The starting position in the array.
690: * @param length The number of characters to use from the array.
691: * @exception org.xml.sax.SAXException The client may throw
692: * an exception during processing.
693: * @see org.xml.sax.ContentHandler#ignorableWhitespace
694: */
695: public void ignorableWhitespace(char ch[], int start, int length)
696: throws SAXException {
697: if (contentHandler != null) {
698: contentHandler.ignorableWhitespace(ch, start, length);
699: }
700: }
701:
702: /**
703: * Filter a processing instruction event.
704: *
705: * @param target The processing instruction target.
706: * @param data The text following the target.
707: * @exception org.xml.sax.SAXException The client may throw
708: * an exception during processing.
709: * @see org.xml.sax.ContentHandler#processingInstruction
710: */
711: public void processingInstruction(String target, String data)
712: throws SAXException {
713: if (contentHandler != null) {
714: contentHandler.processingInstruction(target, data);
715: }
716: }
717:
718: /**
719: * Filter a skipped entity event.
720: *
721: * @param name The name of the skipped entity.
722: * @exception org.xml.sax.SAXException The client may throw
723: * an exception during processing.
724: * @see org.xml.sax.ContentHandler#skippedEntity
725: */
726: public void skippedEntity(String name) throws SAXException {
727: if (contentHandler != null) {
728: contentHandler.skippedEntity(name);
729: }
730: }
731:
732: ////////////////////////////////////////////////////////////////////
733: // Implementation of org.xml.sax.ErrorHandler.
734: ////////////////////////////////////////////////////////////////////
735:
736: /**
737: * Filter a warning event.
738: *
739: * @param e The nwarning as an exception.
740: * @exception org.xml.sax.SAXException The client may throw
741: * an exception during processing.
742: * @see org.xml.sax.ErrorHandler#warning
743: */
744: public void warning(SAXParseException e) throws SAXException {
745: if (errorHandler != null) {
746: errorHandler.warning(e);
747: }
748: }
749:
750: /**
751: * Filter an error event.
752: *
753: * @param e The error as an exception.
754: * @exception org.xml.sax.SAXException The client may throw
755: * an exception during processing.
756: * @see org.xml.sax.ErrorHandler#error
757: */
758: public void error(SAXParseException e) throws SAXException {
759: if (errorHandler != null) {
760: errorHandler.error(e);
761: }
762: }
763:
764: /**
765: * Filter a fatal error event.
766: *
767: * @param e The error as an exception.
768: * @exception org.xml.sax.SAXException The client may throw
769: * an exception during processing.
770: * @see org.xml.sax.ErrorHandler#fatalError
771: */
772: public void fatalError(SAXParseException e) throws SAXException {
773: if (errorHandler != null) {
774: errorHandler.fatalError(e);
775: }
776: }
777:
778: ////////////////////////////////////////////////////////////////////
779: // Internal methods.
780: ////////////////////////////////////////////////////////////////////
781:
782: /**
783: * Set up before a parse.
784: *
785: * <p>Before every parse, check whether the parent is
786: * non-null, and re-register the filter for all of the
787: * events.</p>
788: */
789: private void setupParse() {
790: if (parent == null) {
791: throw new NullPointerException("No parent for filter");
792: }
793: if (entityResolver != null)
794: parent.setEntityResolver(this);
795: parent.setDTDHandler(this);
796: parent.setContentHandler(this);
797: if (errorHandler != null)
798: parent.setErrorHandler(this);
799:
800: }
801:
802: }
|