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