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 226184 2005-04-08 10:53:24Z neeraj $ 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