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