Source for org.xml.sax.helpers.XMLFilterImpl

   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.1 2004/12/23 22:38:42 mark 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 handler 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 handler 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 handler 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