View Javadoc

1   // XMLFilterImpl.java - base SAX2 filter implementation.
2   // http://www.saxproject.org
3   // Written by David Megginson
4   // NO WARRANTY!  This class is in the Public Domain.
5   // $Id: XMLFilterImpl.java,v 1.5 2004/03/19 20:17:55 maartenc Exp $
6   
7   package org.xml.sax.helpers;
8   
9   import java.io.IOException;
10  
11  import org.xml.sax.XMLReader;
12  import org.xml.sax.XMLFilter;
13  import org.xml.sax.InputSource;
14  import org.xml.sax.Locator;
15  import org.xml.sax.Attributes;
16  import org.xml.sax.EntityResolver;
17  import org.xml.sax.DTDHandler;
18  import org.xml.sax.ContentHandler;
19  import org.xml.sax.ErrorHandler;
20  import org.xml.sax.SAXException;
21  import org.xml.sax.SAXParseException;
22  import org.xml.sax.SAXNotSupportedException;
23  import org.xml.sax.SAXNotRecognizedException;
24  
25  
26  /***
27   * Base class for deriving an XML filter.
28   *
29   * <blockquote>
30   * <em>This module, both source code and documentation, is in the
31   * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
32   * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
33   * for further information.
34   * </blockquote>
35   *
36   * <p>This class is designed to sit between an {@link org.xml.sax.XMLReader
37   * XMLReader} and the client application's event handlers.  By default, it
38   * does nothing but pass requests up to the reader and events
39   * on to the handlers unmodified, but subclasses can override
40   * specific methods to modify the event stream or the configuration
41   * requests as they pass through.</p>
42   *
43   * @since SAX 2.0
44   * @author David Megginson
45   * @version 2.0.1 (sax2r2)
46   * @see org.xml.sax.XMLFilter
47   * @see org.xml.sax.XMLReader
48   * @see org.xml.sax.EntityResolver
49   * @see org.xml.sax.DTDHandler
50   * @see org.xml.sax.ContentHandler
51   * @see org.xml.sax.ErrorHandler
52   */
53  public class XMLFilterImpl
54      implements XMLFilter, EntityResolver, DTDHandler, ContentHandler, ErrorHandler
55  {
56  
57  
58      ////////////////////////////////////////////////////////////////////
59      // Constructors.
60      ////////////////////////////////////////////////////////////////////
61  
62  
63      /***
64       * Construct an empty XML filter, with no parent.
65       *
66       * <p>This filter will have no parent: you must assign a parent
67       * before you start a parse or do any configuration with
68       * setFeature or setProperty, unless you use this as a pure event
69       * consumer rather than as an {@link XMLReader}.</p>
70       *
71       * @see org.xml.sax.XMLReader#setFeature
72       * @see org.xml.sax.XMLReader#setProperty
73       * @see #setParent
74       */
75      public XMLFilterImpl ()
76      {
77  	super();
78      }
79  
80  
81      /***
82       * Construct an XML filter with the specified parent.
83       *
84       * @see #setParent
85       * @see #getParent
86       */
87      public XMLFilterImpl (XMLReader parent)
88      {
89          super();
90  	setParent(parent);
91      }
92  
93  
94  
95      ////////////////////////////////////////////////////////////////////
96      // Implementation of org.xml.sax.XMLFilter.
97      ////////////////////////////////////////////////////////////////////
98  
99  
100     /***
101      * Set the parent reader.
102      *
103      * <p>This is the {@link org.xml.sax.XMLReader XMLReader} from which 
104      * this filter will obtain its events and to which it will pass its 
105      * configuration requests.  The parent may itself be another filter.</p>
106      *
107      * <p>If there is no parent reader set, any attempt to parse
108      * or to set or get a feature or property will fail.</p>
109      *
110      * @param parent The parent XML reader.
111      * @see #getParent
112      */
113     public void setParent (XMLReader parent)
114     {
115 	this.parent = parent;
116     }
117 
118 
119     /***
120      * Get the parent reader.
121      *
122      * @return The parent XML reader, or null if none is set.
123      * @see #setParent
124      */
125     public XMLReader getParent ()
126     {
127 	return parent;
128     }
129 
130 
131 
132     ////////////////////////////////////////////////////////////////////
133     // Implementation of org.xml.sax.XMLReader.
134     ////////////////////////////////////////////////////////////////////
135 
136 
137     /***
138      * Set the value of a feature.
139      *
140      * <p>This will always fail if the parent is null.</p>
141      *
142      * @param name The feature name.
143      * @param value The requested feature value.
144      * @exception org.xml.sax.SAXNotRecognizedException If the feature
145      *            value can't be assigned or retrieved from the parent.
146      * @exception org.xml.sax.SAXNotSupportedException When the
147      *            parent recognizes the feature name but 
148      *            cannot set the requested value.
149      */
150     public void setFeature (String name, boolean value)
151 	throws SAXNotRecognizedException, SAXNotSupportedException
152     {
153 	if (parent != null) {
154 	    parent.setFeature(name, value);
155 	} else {
156 	    throw new SAXNotRecognizedException("Feature: " + name);
157 	}
158     }
159 
160 
161     /***
162      * Look up the value of a feature.
163      *
164      * <p>This will always fail if the parent is null.</p>
165      *
166      * @param name The feature name.
167      * @return The current value of the feature.
168      * @exception org.xml.sax.SAXNotRecognizedException If the feature
169      *            value can't be assigned or retrieved from the parent.
170      * @exception org.xml.sax.SAXNotSupportedException When the
171      *            parent recognizes the feature name but 
172      *            cannot determine its value at this time.
173      */
174     public boolean getFeature (String name)
175 	throws SAXNotRecognizedException, SAXNotSupportedException
176     {
177 	if (parent != null) {
178 	    return parent.getFeature(name);
179 	} else {
180 	    throw new SAXNotRecognizedException("Feature: " + name);
181 	}
182     }
183 
184 
185     /***
186      * Set the value of a property.
187      *
188      * <p>This will always fail if the parent is null.</p>
189      *
190      * @param name The property name.
191      * @param value The requested property value.
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 set the requested value.
197      */
198     public void setProperty (String name, Object value)
199 	throws SAXNotRecognizedException, SAXNotSupportedException
200     {
201 	if (parent != null) {
202 	    parent.setProperty(name, value);
203 	} else {
204 	    throw new SAXNotRecognizedException("Property: " + name);
205 	}
206     }
207 
208 
209     /***
210      * Look up the value of a property.
211      *
212      * @param name The property name.
213      * @return The current value of the property.
214      * @exception org.xml.sax.SAXNotRecognizedException If the property
215      *            value can't be assigned or retrieved from the parent.
216      * @exception org.xml.sax.SAXNotSupportedException When the
217      *            parent recognizes the property name but 
218      *            cannot determine its value at this time.
219      */
220     public Object getProperty (String name)
221 	throws SAXNotRecognizedException, SAXNotSupportedException
222     {
223 	if (parent != null) {
224 	    return parent.getProperty(name);
225 	} else {
226 	    throw new SAXNotRecognizedException("Property: " + name);
227 	}
228     }
229 
230 
231     /***
232      * Set the entity resolver.
233      *
234      * @param resolver The new entity resolver.
235      */
236     public void setEntityResolver (EntityResolver resolver)
237     {
238 	entityResolver = resolver;
239     }
240 
241 
242     /***
243      * Get the current entity resolver.
244      *
245      * @return The current entity resolver, or null if none was set.
246      */
247     public EntityResolver getEntityResolver ()
248     {
249 	return entityResolver;
250     }
251 
252 
253     /***
254      * Set the DTD event handler.
255      *
256      * @param resolver The new DTD handler.
257      */
258     public void setDTDHandler (DTDHandler handler)
259     {
260 	dtdHandler = handler;
261     }
262 
263 
264     /***
265      * Get the current DTD event handler.
266      *
267      * @return The current DTD handler, or null if none was set.
268      */
269     public DTDHandler getDTDHandler ()
270     {
271 	return dtdHandler;
272     }
273 
274 
275     /***
276      * Set the content event handler.
277      *
278      * @param resolver The new content handler.
279      */
280     public void setContentHandler (ContentHandler handler)
281     {
282 	contentHandler = handler;
283     }
284 
285 
286     /***
287      * Get the content event handler.
288      *
289      * @return The current content handler, or null if none was set.
290      */
291     public ContentHandler getContentHandler ()
292     {
293 	return contentHandler;
294     }
295 
296 
297     /***
298      * Set the error event handler.
299      *
300      * @param handle The new error handler.
301      */
302     public void setErrorHandler (ErrorHandler handler)
303     {
304 	errorHandler = handler;
305     }
306 
307 
308     /***
309      * Get the current error event handler.
310      *
311      * @return The current error handler, or null if none was set.
312      */
313     public ErrorHandler getErrorHandler ()
314     {
315 	return errorHandler;
316     }
317 
318 
319     /***
320      * Parse a document.
321      *
322      * @param input The input source for the document entity.
323      * @exception org.xml.sax.SAXException Any SAX exception, possibly
324      *            wrapping another exception.
325      * @exception java.io.IOException An IO exception from the parser,
326      *            possibly from a byte stream or character stream
327      *            supplied by the application.
328      */
329     public void parse (InputSource input)
330 	throws SAXException, IOException
331     {
332 	setupParse();
333 	parent.parse(input);
334     }
335 
336 
337     /***
338      * Parse a document.
339      *
340      * @param systemId The system identifier as a fully-qualified URI.
341      * @exception org.xml.sax.SAXException Any SAX exception, possibly
342      *            wrapping another exception.
343      * @exception java.io.IOException An IO exception from the parser,
344      *            possibly from a byte stream or character stream
345      *            supplied by the application.
346      */
347     public void parse (String systemId)
348 	throws SAXException, IOException
349     {
350 	parse(new InputSource(systemId));
351     }
352 
353 
354 
355     ////////////////////////////////////////////////////////////////////
356     // Implementation of org.xml.sax.EntityResolver.
357     ////////////////////////////////////////////////////////////////////
358 
359 
360     /***
361      * Filter an external entity resolution.
362      *
363      * @param publicId The entity's public identifier, or null.
364      * @param systemId The entity's system identifier.
365      * @return A new InputSource or null for the default.
366      * @exception org.xml.sax.SAXException The client may throw
367      *            an exception during processing.
368      * @exception java.io.IOException The client may throw an
369      *            I/O-related exception while obtaining the
370      *            new InputSource.
371      */
372     public InputSource resolveEntity (String publicId, String systemId)
373 	throws SAXException, IOException
374     {
375 	if (entityResolver != null) {
376 	    return entityResolver.resolveEntity(publicId, systemId);
377 	} else {
378 	    return null;
379 	}
380     }
381 
382 
383 
384     ////////////////////////////////////////////////////////////////////
385     // Implementation of org.xml.sax.DTDHandler.
386     ////////////////////////////////////////////////////////////////////
387 
388     
389     /***
390      * Filter a notation declaration event.
391      *
392      * @param name The notation name.
393      * @param publicId The notation's public identifier, or null.
394      * @param systemId The notation's system identifier, or null.
395      * @exception org.xml.sax.SAXException The client may throw
396      *            an exception during processing.
397      */
398     public void notationDecl (String name, String publicId, String systemId)
399 	throws SAXException
400     {
401 	if (dtdHandler != null) {
402 	    dtdHandler.notationDecl(name, publicId, systemId);
403 	}
404     }
405 
406     
407     /***
408      * Filter an unparsed entity declaration event.
409      *
410      * @param name The entity name.
411      * @param publicId The entity's public identifier, or null.
412      * @param systemId The entity's system identifier, or null.
413      * @param notationName The name of the associated notation.
414      * @exception org.xml.sax.SAXException The client may throw
415      *            an exception during processing.
416      */
417     public void unparsedEntityDecl (String name, String publicId,
418 				    String systemId, String notationName)
419 	throws SAXException
420     {
421 	if (dtdHandler != null) {
422 	    dtdHandler.unparsedEntityDecl(name, publicId, systemId,
423 					  notationName);
424 	}
425     }
426 
427 
428 
429     ////////////////////////////////////////////////////////////////////
430     // Implementation of org.xml.sax.ContentHandler.
431     ////////////////////////////////////////////////////////////////////
432 
433 
434     /***
435      * Filter a new document locator event.
436      *
437      * @param locator The document locator.
438      */
439     public void setDocumentLocator (Locator locator)
440     {
441 	this.locator = locator;
442 	if (contentHandler != null) {
443 	    contentHandler.setDocumentLocator(locator);
444 	}
445     }
446 
447 
448     /***
449      * Filter a start document event.
450      *
451      * @exception org.xml.sax.SAXException The client may throw
452      *            an exception during processing.
453      */
454     public void startDocument ()
455 	throws SAXException
456     {
457 	if (contentHandler != null) {
458 	    contentHandler.startDocument();
459 	}
460     }
461 
462 
463     /***
464      * Filter an end document event.
465      *
466      * @exception org.xml.sax.SAXException The client may throw
467      *            an exception during processing.
468      */
469     public void endDocument ()
470 	throws SAXException
471     {
472 	if (contentHandler != null) {
473 	    contentHandler.endDocument();
474 	}
475     }
476 
477 
478     /***
479      * Filter a start Namespace prefix mapping event.
480      *
481      * @param prefix The Namespace prefix.
482      * @param uri The Namespace URI.
483      * @exception org.xml.sax.SAXException The client may throw
484      *            an exception during processing.
485      */
486     public void startPrefixMapping (String prefix, String uri)
487 	throws SAXException
488     {
489 	if (contentHandler != null) {
490 	    contentHandler.startPrefixMapping(prefix, uri);
491 	}
492     }
493 
494 
495     /***
496      * Filter an end Namespace prefix mapping event.
497      *
498      * @param prefix The Namespace prefix.
499      * @exception org.xml.sax.SAXException The client may throw
500      *            an exception during processing.
501      */
502     public void endPrefixMapping (String prefix)
503 	throws SAXException
504     {
505 	if (contentHandler != null) {
506 	    contentHandler.endPrefixMapping(prefix);
507 	}
508     }
509 
510 
511     /***
512      * Filter a start element event.
513      *
514      * @param uri The element's Namespace URI, or the empty string.
515      * @param localName The element's local name, or the empty string.
516      * @param qName The element's qualified (prefixed) name, or the empty
517      *        string.
518      * @param atts The element's attributes.
519      * @exception org.xml.sax.SAXException The client may throw
520      *            an exception during processing.
521      */
522     public void startElement (String uri, String localName, String qName,
523 			      Attributes atts)
524 	throws SAXException
525     {
526 	if (contentHandler != null) {
527 	    contentHandler.startElement(uri, localName, qName, atts);
528 	}
529     }
530 
531 
532     /***
533      * Filter an end element event.
534      *
535      * @param uri The element's Namespace URI, or the empty string.
536      * @param localName The element's local name, or the empty string.
537      * @param qName The element's qualified (prefixed) name, or the empty
538      *        string.
539      * @exception org.xml.sax.SAXException The client may throw
540      *            an exception during processing.
541      */
542     public void endElement (String uri, String localName, String qName)
543 	throws SAXException
544     {
545 	if (contentHandler != null) {
546 	    contentHandler.endElement(uri, localName, qName);
547 	}
548     }
549 
550 
551     /***
552      * Filter a character data event.
553      *
554      * @param ch An array of characters.
555      * @param start The starting position in the array.
556      * @param length The number of characters to use from the array.
557      * @exception org.xml.sax.SAXException The client may throw
558      *            an exception during processing.
559      */
560     public void characters (char ch[], int start, int length)
561 	throws SAXException
562     {
563 	if (contentHandler != null) {
564 	    contentHandler.characters(ch, start, length);
565 	}
566     }
567 
568 
569     /***
570      * Filter an ignorable whitespace event.
571      *
572      * @param ch An array of characters.
573      * @param start The starting position in the array.
574      * @param length The number of characters to use from the array.
575      * @exception org.xml.sax.SAXException The client may throw
576      *            an exception during processing.
577      */
578     public void ignorableWhitespace (char ch[], int start, int length)
579 	throws SAXException
580     {
581 	if (contentHandler != null) {
582 	    contentHandler.ignorableWhitespace(ch, start, length);
583 	}
584     }
585 
586 
587     /***
588      * Filter a processing instruction event.
589      *
590      * @param target The processing instruction target.
591      * @param data The text following the target.
592      * @exception org.xml.sax.SAXException The client may throw
593      *            an exception during processing.
594      */
595     public void processingInstruction (String target, String data)
596 	throws SAXException
597     {
598 	if (contentHandler != null) {
599 	    contentHandler.processingInstruction(target, data);
600 	}
601     }
602 
603 
604     /***
605      * Filter a skipped entity event.
606      *
607      * @param name The name of the skipped entity.
608      * @exception org.xml.sax.SAXException The client may throw
609      *            an exception during processing.
610      */
611     public void skippedEntity (String name)
612 	throws SAXException
613     {
614 	if (contentHandler != null) {
615 	    contentHandler.skippedEntity(name);
616 	}
617     }
618 
619 
620 
621     ////////////////////////////////////////////////////////////////////
622     // Implementation of org.xml.sax.ErrorHandler.
623     ////////////////////////////////////////////////////////////////////
624 
625 
626     /***
627      * Filter a warning event.
628      *
629      * @param e The warning as an exception.
630      * @exception org.xml.sax.SAXException The client may throw
631      *            an exception during processing.
632      */
633     public void warning (SAXParseException e)
634 	throws SAXException
635     {
636 	if (errorHandler != null) {
637 	    errorHandler.warning(e);
638 	}
639     }
640 
641 
642     /***
643      * Filter an error event.
644      *
645      * @param e The error as an exception.
646      * @exception org.xml.sax.SAXException The client may throw
647      *            an exception during processing.
648      */
649     public void error (SAXParseException e)
650 	throws SAXException
651     {
652 	if (errorHandler != null) {
653 	    errorHandler.error(e);
654 	}
655     }
656 
657 
658     /***
659      * Filter a fatal error event.
660      *
661      * @param e The error as an exception.
662      * @exception org.xml.sax.SAXException The client may throw
663      *            an exception during processing.
664      */
665     public void fatalError (SAXParseException e)
666 	throws SAXException
667     {
668 	if (errorHandler != null) {
669 	    errorHandler.fatalError(e);
670 	}
671     }
672 
673 
674 
675     ////////////////////////////////////////////////////////////////////
676     // Internal methods.
677     ////////////////////////////////////////////////////////////////////
678 
679 
680     /***
681      * Set up before a parse.
682      *
683      * <p>Before every parse, check whether the parent is
684      * non-null, and re-register the filter for all of the 
685      * events.</p>
686      */
687     private void setupParse ()
688     {
689 	if (parent == null) {
690 	    throw new NullPointerException("No parent for filter");
691 	}
692 	parent.setEntityResolver(this);
693 	parent.setDTDHandler(this);
694 	parent.setContentHandler(this);
695 	parent.setErrorHandler(this);
696     }
697 
698 
699 
700     ////////////////////////////////////////////////////////////////////
701     // Internal state.
702     ////////////////////////////////////////////////////////////////////
703 
704     private XMLReader parent = null;
705     private Locator locator = null;
706     private EntityResolver entityResolver = null;
707     private DTDHandler dtdHandler = null;
708     private ContentHandler contentHandler = null;
709     private ErrorHandler errorHandler = null;
710 
711 }
712 
713 // end of XMLFilterImpl.java