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