001: // XMLFilterImpl.java - base SAX2 filter implementation.
002: // http://www.saxproject.org
003: // Written by David Megginson
004: // NO WARRANTY! This class is in the Public Domain.
005: // $Id: XMLFilterImpl.java,v 1.8 2002/02/01 20:06:20 db Exp $
006:
007: package org.xml.sax.helpers;
008:
009: import java.io.IOException;
010:
011: import org.xml.sax.XMLReader;
012: import org.xml.sax.XMLFilter;
013: import org.xml.sax.InputSource;
014: import org.xml.sax.Locator;
015: import org.xml.sax.Attributes;
016: import org.xml.sax.EntityResolver;
017: import org.xml.sax.DTDHandler;
018: import org.xml.sax.ContentHandler;
019: import org.xml.sax.ErrorHandler;
020: import org.xml.sax.SAXException;
021: import org.xml.sax.SAXParseException;
022: import org.xml.sax.SAXNotSupportedException;
023: import org.xml.sax.SAXNotRecognizedException;
024:
025: /**
026: * Base class for deriving an XML filter.
027: *
028: * <blockquote>
029: * <em>This module, both source code and documentation, is in the
030: * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
031: * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
032: * for further information.
033: * </blockquote>
034: *
035: * <p>This class is designed to sit between an {@link org.xml.sax.XMLReader
036: * XMLReader} and the client application's event handlers. By default, it
037: * does nothing but pass requests up to the reader and events
038: * on to the handlers unmodified, but subclasses can override
039: * specific methods to modify the event stream or the configuration
040: * requests as they pass through.</p>
041: *
042: * @since SAX 2.0
043: * @author David Megginson
044: * @version 2.0.1 (sax2r2)
045: * @see org.xml.sax.XMLFilter
046: * @see org.xml.sax.XMLReader
047: * @see org.xml.sax.EntityResolver
048: * @see org.xml.sax.DTDHandler
049: * @see org.xml.sax.ContentHandler
050: * @see org.xml.sax.ErrorHandler
051: */
052: public class XMLFilterImpl implements XMLFilter, EntityResolver,
053: DTDHandler, ContentHandler, ErrorHandler {
054:
055: ////////////////////////////////////////////////////////////////////
056: // Constructors.
057: ////////////////////////////////////////////////////////////////////
058:
059: /**
060: * Construct an empty XML filter, with no parent.
061: *
062: * <p>This filter will have no parent: you must assign a parent
063: * before you start a parse or do any configuration with
064: * setFeature or setProperty, unless you use this as a pure event
065: * consumer rather than as an {@link XMLReader}.</p>
066: *
067: * @see org.xml.sax.XMLReader#setFeature
068: * @see org.xml.sax.XMLReader#setProperty
069: * @see #setParent
070: */
071: public XMLFilterImpl() {
072: super ();
073: }
074:
075: /**
076: * Construct an XML filter with the specified parent.
077: *
078: * @see #setParent
079: * @see #getParent
080: */
081: public XMLFilterImpl(XMLReader parent) {
082: super ();
083: setParent(parent);
084: }
085:
086: ////////////////////////////////////////////////////////////////////
087: // Implementation of org.xml.sax.XMLFilter.
088: ////////////////////////////////////////////////////////////////////
089:
090: /**
091: * Set the parent reader.
092: *
093: * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which
094: * this filter will obtain its events and to which it will pass its
095: * configuration requests. The parent may itself be another filter.</p>
096: *
097: * <p>If there is no parent reader set, any attempt to parse
098: * or to set or get a feature or property will fail.</p>
099: *
100: * @param parent The parent XML reader.
101: * @see #getParent
102: */
103: public void setParent(XMLReader parent) {
104: this .parent = parent;
105: }
106:
107: /**
108: * Get the parent reader.
109: *
110: * @return The parent XML reader, or null if none is set.
111: * @see #setParent
112: */
113: public XMLReader getParent() {
114: return parent;
115: }
116:
117: ////////////////////////////////////////////////////////////////////
118: // Implementation of org.xml.sax.XMLReader.
119: ////////////////////////////////////////////////////////////////////
120:
121: /**
122: * Set the value of a feature.
123: *
124: * <p>This will always fail if the parent is null.</p>
125: *
126: * @param name The feature name.
127: * @param value The requested feature value.
128: * @exception org.xml.sax.SAXNotRecognizedException If the feature
129: * value can't be assigned or retrieved from the parent.
130: * @exception org.xml.sax.SAXNotSupportedException When the
131: * parent recognizes the feature name but
132: * cannot set the requested value.
133: */
134: public void setFeature(String name, boolean value)
135: throws SAXNotRecognizedException, SAXNotSupportedException {
136: if (parent != null) {
137: parent.setFeature(name, value);
138: } else {
139: throw new SAXNotRecognizedException("Feature: " + name);
140: }
141: }
142:
143: /**
144: * Look up the value of a feature.
145: *
146: * <p>This will always fail if the parent is null.</p>
147: *
148: * @param name The feature name.
149: * @return The current value of the feature.
150: * @exception org.xml.sax.SAXNotRecognizedException If the feature
151: * value can't be assigned or retrieved from the parent.
152: * @exception org.xml.sax.SAXNotSupportedException When the
153: * parent recognizes the feature name but
154: * cannot determine its value at this time.
155: */
156: public boolean getFeature(String name)
157: throws SAXNotRecognizedException, SAXNotSupportedException {
158: if (parent != null) {
159: return parent.getFeature(name);
160: } else {
161: throw new SAXNotRecognizedException("Feature: " + name);
162: }
163: }
164:
165: /**
166: * Set the value of a property.
167: *
168: * <p>This will always fail if the parent is null.</p>
169: *
170: * @param name The property name.
171: * @param value The requested property value.
172: * @exception org.xml.sax.SAXNotRecognizedException If the property
173: * value can't be assigned or retrieved from the parent.
174: * @exception org.xml.sax.SAXNotSupportedException When the
175: * parent recognizes the property name but
176: * cannot set the requested value.
177: */
178: public void setProperty(String name, Object value)
179: throws SAXNotRecognizedException, SAXNotSupportedException {
180: if (parent != null) {
181: parent.setProperty(name, value);
182: } else {
183: throw new SAXNotRecognizedException("Property: " + name);
184: }
185: }
186:
187: /**
188: * Look up the value of a property.
189: *
190: * @param name The property name.
191: * @return The current value of the property.
192: * @exception org.xml.sax.SAXNotRecognizedException If the property
193: * value can't be assigned or retrieved from the parent.
194: * @exception org.xml.sax.SAXNotSupportedException When the
195: * parent recognizes the property name but
196: * cannot determine its value at this time.
197: */
198: public Object getProperty(String name)
199: throws SAXNotRecognizedException, SAXNotSupportedException {
200: if (parent != null) {
201: return parent.getProperty(name);
202: } else {
203: throw new SAXNotRecognizedException("Property: " + name);
204: }
205: }
206:
207: /**
208: * Set the entity resolver.
209: *
210: * @param resolver The new entity resolver.
211: */
212: public void setEntityResolver(EntityResolver resolver) {
213: entityResolver = resolver;
214: }
215:
216: /**
217: * Get the current entity resolver.
218: *
219: * @return The current entity resolver, or null if none was set.
220: */
221: public EntityResolver getEntityResolver() {
222: return entityResolver;
223: }
224:
225: /**
226: * Set the DTD event handler.
227: *
228: * @param resolver The new DTD handler.
229: */
230: public void setDTDHandler(DTDHandler handler) {
231: dtdHandler = handler;
232: }
233:
234: /**
235: * Get the current DTD event handler.
236: *
237: * @return The current DTD handler, or null if none was set.
238: */
239: public DTDHandler getDTDHandler() {
240: return dtdHandler;
241: }
242:
243: /**
244: * Set the content event handler.
245: *
246: * @param resolver The new content handler.
247: */
248: public void setContentHandler(ContentHandler handler) {
249: contentHandler = handler;
250: }
251:
252: /**
253: * Get the content event handler.
254: *
255: * @return The current content handler, or null if none was set.
256: */
257: public ContentHandler getContentHandler() {
258: return contentHandler;
259: }
260:
261: /**
262: * Set the error event handler.
263: *
264: * @param handle The new error handler.
265: */
266: public void setErrorHandler(ErrorHandler handler) {
267: errorHandler = handler;
268: }
269:
270: /**
271: * Get the current error event handler.
272: *
273: * @return The current error handler, or null if none was set.
274: */
275: public ErrorHandler getErrorHandler() {
276: return errorHandler;
277: }
278:
279: /**
280: * Parse a document.
281: *
282: * @param input The input source for the document entity.
283: * @exception org.xml.sax.SAXException Any SAX exception, possibly
284: * wrapping another exception.
285: * @exception java.io.IOException An IO exception from the parser,
286: * possibly from a byte stream or character stream
287: * supplied by the application.
288: */
289: public void parse(InputSource input) throws SAXException,
290: IOException {
291: setupParse();
292: parent.parse(input);
293: }
294:
295: /**
296: * Parse a document.
297: *
298: * @param systemId The system identifier as a fully-qualified URI.
299: * @exception org.xml.sax.SAXException Any SAX exception, possibly
300: * wrapping another exception.
301: * @exception java.io.IOException An IO exception from the parser,
302: * possibly from a byte stream or character stream
303: * supplied by the application.
304: */
305: public void parse(String systemId) throws SAXException, IOException {
306: parse(new InputSource(systemId));
307: }
308:
309: ////////////////////////////////////////////////////////////////////
310: // Implementation of org.xml.sax.EntityResolver.
311: ////////////////////////////////////////////////////////////////////
312:
313: /**
314: * Filter an external entity resolution.
315: *
316: * @param publicId The entity's public identifier, or null.
317: * @param systemId The entity's system identifier.
318: * @return A new InputSource or null for the default.
319: * @exception org.xml.sax.SAXException The client may throw
320: * an exception during processing.
321: * @exception java.io.IOException The client may throw an
322: * I/O-related exception while obtaining the
323: * new InputSource.
324: */
325: public InputSource resolveEntity(String publicId, String systemId)
326: throws SAXException, IOException {
327: if (entityResolver != null) {
328: return entityResolver.resolveEntity(publicId, systemId);
329: } else {
330: return null;
331: }
332: }
333:
334: ////////////////////////////////////////////////////////////////////
335: // Implementation of org.xml.sax.DTDHandler.
336: ////////////////////////////////////////////////////////////////////
337:
338: /**
339: * Filter a notation declaration event.
340: *
341: * @param name The notation name.
342: * @param publicId The notation's public identifier, or null.
343: * @param systemId The notation's system identifier, or null.
344: * @exception org.xml.sax.SAXException The client may throw
345: * an exception during processing.
346: */
347: public void notationDecl(String name, String publicId,
348: String systemId) throws SAXException {
349: if (dtdHandler != null) {
350: dtdHandler.notationDecl(name, publicId, systemId);
351: }
352: }
353:
354: /**
355: * Filter an unparsed entity declaration event.
356: *
357: * @param name The entity name.
358: * @param publicId The entity's public identifier, or null.
359: * @param systemId The entity's system identifier, or null.
360: * @param notationName The name of the associated notation.
361: * @exception org.xml.sax.SAXException The client may throw
362: * an exception during processing.
363: */
364: public void unparsedEntityDecl(String name, String publicId,
365: String systemId, String notationName) throws SAXException {
366: if (dtdHandler != null) {
367: dtdHandler.unparsedEntityDecl(name, publicId, systemId,
368: notationName);
369: }
370: }
371:
372: ////////////////////////////////////////////////////////////////////
373: // Implementation of org.xml.sax.ContentHandler.
374: ////////////////////////////////////////////////////////////////////
375:
376: /**
377: * Filter a new document locator event.
378: *
379: * @param locator The document locator.
380: */
381: public void setDocumentLocator(Locator locator) {
382: this .locator = locator;
383: if (contentHandler != null) {
384: contentHandler.setDocumentLocator(locator);
385: }
386: }
387:
388: /**
389: * Filter a start document event.
390: *
391: * @exception org.xml.sax.SAXException The client may throw
392: * an exception during processing.
393: */
394: public void startDocument() throws SAXException {
395: if (contentHandler != null) {
396: contentHandler.startDocument();
397: }
398: }
399:
400: /**
401: * Filter an end document event.
402: *
403: * @exception org.xml.sax.SAXException The client may throw
404: * an exception during processing.
405: */
406: public void endDocument() throws SAXException {
407: if (contentHandler != null) {
408: contentHandler.endDocument();
409: }
410: }
411:
412: /**
413: * Filter a start Namespace prefix mapping event.
414: *
415: * @param prefix The Namespace prefix.
416: * @param uri The Namespace URI.
417: * @exception org.xml.sax.SAXException The client may throw
418: * an exception during processing.
419: */
420: public void startPrefixMapping(String prefix, String uri)
421: throws SAXException {
422: if (contentHandler != null) {
423: contentHandler.startPrefixMapping(prefix, uri);
424: }
425: }
426:
427: /**
428: * Filter an end Namespace prefix mapping event.
429: *
430: * @param prefix The Namespace prefix.
431: * @exception org.xml.sax.SAXException The client may throw
432: * an exception during processing.
433: */
434: public void endPrefixMapping(String prefix) throws SAXException {
435: if (contentHandler != null) {
436: contentHandler.endPrefixMapping(prefix);
437: }
438: }
439:
440: /**
441: * Filter a start element event.
442: *
443: * @param uri The element's Namespace URI, or the empty string.
444: * @param localName The element's local name, or the empty string.
445: * @param qName The element's qualified (prefixed) name, or the empty
446: * string.
447: * @param atts The element's attributes.
448: * @exception org.xml.sax.SAXException The client may throw
449: * an exception during processing.
450: */
451: public void startElement(String uri, String localName,
452: String qName, Attributes atts) throws SAXException {
453: if (contentHandler != null) {
454: contentHandler.startElement(uri, localName, qName, atts);
455: }
456: }
457:
458: /**
459: * Filter an end element event.
460: *
461: * @param uri The element's Namespace URI, or the empty string.
462: * @param localName The element's local name, or the empty string.
463: * @param qName The element's qualified (prefixed) name, or the empty
464: * string.
465: * @exception org.xml.sax.SAXException The client may throw
466: * an exception during processing.
467: */
468: public void endElement(String uri, String localName, String qName)
469: throws SAXException {
470: if (contentHandler != null) {
471: contentHandler.endElement(uri, localName, qName);
472: }
473: }
474:
475: /**
476: * Filter a character data event.
477: *
478: * @param ch An array of characters.
479: * @param start The starting position in the array.
480: * @param length The number of characters to use from the array.
481: * @exception org.xml.sax.SAXException The client may throw
482: * an exception during processing.
483: */
484: public void characters(char ch[], int start, int length)
485: throws SAXException {
486: if (contentHandler != null) {
487: contentHandler.characters(ch, start, length);
488: }
489: }
490:
491: /**
492: * Filter an ignorable whitespace event.
493: *
494: * @param ch An array of characters.
495: * @param start The starting position in the array.
496: * @param length The number of characters to use from the array.
497: * @exception org.xml.sax.SAXException The client may throw
498: * an exception during processing.
499: */
500: public void ignorableWhitespace(char ch[], int start, int length)
501: throws SAXException {
502: if (contentHandler != null) {
503: contentHandler.ignorableWhitespace(ch, start, length);
504: }
505: }
506:
507: /**
508: * Filter a processing instruction event.
509: *
510: * @param target The processing instruction target.
511: * @param data The text following the target.
512: * @exception org.xml.sax.SAXException The client may throw
513: * an exception during processing.
514: */
515: public void processingInstruction(String target, String data)
516: throws SAXException {
517: if (contentHandler != null) {
518: contentHandler.processingInstruction(target, data);
519: }
520: }
521:
522: /**
523: * Filter a skipped entity event.
524: *
525: * @param name The name of the skipped entity.
526: * @exception org.xml.sax.SAXException The client may throw
527: * an exception during processing.
528: */
529: public void skippedEntity(String name) throws SAXException {
530: if (contentHandler != null) {
531: contentHandler.skippedEntity(name);
532: }
533: }
534:
535: ////////////////////////////////////////////////////////////////////
536: // Implementation of org.xml.sax.ErrorHandler.
537: ////////////////////////////////////////////////////////////////////
538:
539: /**
540: * Filter a warning event.
541: *
542: * @param e The warning as an exception.
543: * @exception org.xml.sax.SAXException The client may throw
544: * an exception during processing.
545: */
546: public void warning(SAXParseException e) throws SAXException {
547: if (errorHandler != null) {
548: errorHandler.warning(e);
549: }
550: }
551:
552: /**
553: * Filter an error event.
554: *
555: * @param e The error as an exception.
556: * @exception org.xml.sax.SAXException The client may throw
557: * an exception during processing.
558: */
559: public void error(SAXParseException e) throws SAXException {
560: if (errorHandler != null) {
561: errorHandler.error(e);
562: }
563: }
564:
565: /**
566: * Filter a fatal error event.
567: *
568: * @param e The error as an exception.
569: * @exception org.xml.sax.SAXException The client may throw
570: * an exception during processing.
571: */
572: public void fatalError(SAXParseException e) throws SAXException {
573: if (errorHandler != null) {
574: errorHandler.fatalError(e);
575: }
576: }
577:
578: ////////////////////////////////////////////////////////////////////
579: // Internal methods.
580: ////////////////////////////////////////////////////////////////////
581:
582: /**
583: * Set up before a parse.
584: *
585: * <p>Before every parse, check whether the parent is
586: * non-null, and re-register the filter for all of the
587: * events.</p>
588: */
589: private void setupParse() {
590: if (parent == null) {
591: throw new NullPointerException("No parent for filter");
592: }
593: parent.setEntityResolver(this );
594: parent.setDTDHandler(this );
595: parent.setContentHandler(this );
596: parent.setErrorHandler(this );
597: }
598:
599: ////////////////////////////////////////////////////////////////////
600: // Internal state.
601: ////////////////////////////////////////////////////////////////////
602:
603: private XMLReader parent = null;
604: private Locator locator = null;
605: private EntityResolver entityResolver = null;
606: private DTDHandler dtdHandler = null;
607: private ContentHandler contentHandler = null;
608: private ErrorHandler errorHandler = null;
609:
610: }
611:
612: // end of XMLFilterImpl.java
|