1 // ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader. 2 // http://www.saxproject.org 3 // Written by David Megginson 4 // NO WARRANTY! This class is in the public domain. 5 // $Id: ParserAdapter.java,v 1.16 2004/04/26 17:34:35 dmegginson Exp $ 6 7 package org.xml.sax.helpers; 8 9 import org.xml.sax.AttributeList; 10 import org.xml.sax.Attributes; 11 import org.xml.sax.ContentHandler; 12 import org.xml.sax.DTDHandler; 13 import org.xml.sax.DocumentHandler; 14 import org.xml.sax.EntityResolver; 15 import org.xml.sax.ErrorHandler; 16 import org.xml.sax.InputSource; 17 import org.xml.sax.Locator; 18 import org.xml.sax.Parser; 19 import org.xml.sax.SAXException; 20 import org.xml.sax.SAXNotRecognizedException; 21 import org.xml.sax.SAXNotSupportedException; 22 import org.xml.sax.SAXParseException; 23 import org.xml.sax.XMLReader; 24 25 import android.compat.annotation.UnsupportedAppUsage; 26 27 import java.io.IOException; 28 import java.util.ArrayList; 29 import java.util.Enumeration; 30 31 32 /** 33 * Adapt a SAX1 Parser as a SAX2 XMLReader. 34 * 35 * <blockquote> 36 * <em>This module, both source code and documentation, is in the 37 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> 38 * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> 39 * for further information. 40 * </blockquote> 41 * 42 * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser} 43 * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader}, 44 * with feature, property, and Namespace support. Note 45 * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity 46 * skippedEntity} events, since SAX1 does not make that information available.</p> 47 * 48 * <p>This adapter does not test for duplicate Namespace-qualified 49 * attribute names.</p> 50 * 51 * @since SAX 2.0 52 * @author David Megginson 53 * @version 2.0.1 (sax2r2) 54 * @see org.xml.sax.helpers.XMLReaderAdapter 55 * @see org.xml.sax.XMLReader 56 * @see org.xml.sax.Parser 57 */ 58 public class ParserAdapter implements XMLReader, DocumentHandler 59 { 60 61 62 //////////////////////////////////////////////////////////////////// 63 // Constructors. 64 //////////////////////////////////////////////////////////////////// 65 66 67 /** 68 * Construct a new parser adapter. 69 * 70 * <p>Use the "org.xml.sax.parser" property to locate the 71 * embedded SAX1 driver.</p> 72 * 73 * @exception SAXException If the embedded driver 74 * cannot be instantiated or if the 75 * org.xml.sax.parser property is not specified. 76 */ ParserAdapter()77 public ParserAdapter () 78 throws SAXException 79 { 80 81 String driver = System.getProperty("org.xml.sax.parser"); 82 83 try { 84 setup(ParserFactory.makeParser()); 85 } catch (ClassNotFoundException e1) { 86 throw new 87 SAXException("Cannot find SAX1 driver class " + 88 driver, e1); 89 } catch (IllegalAccessException e2) { 90 throw new 91 SAXException("SAX1 driver class " + 92 driver + 93 " found but cannot be loaded", e2); 94 } catch (InstantiationException e3) { 95 throw new 96 SAXException("SAX1 driver class " + 97 driver + 98 " loaded but cannot be instantiated", e3); 99 } catch (ClassCastException e4) { 100 throw new 101 SAXException("SAX1 driver class " + 102 driver + 103 " does not implement org.xml.sax.Parser"); 104 } catch (NullPointerException e5) { 105 throw new 106 SAXException("System property org.xml.sax.parser not specified"); 107 } 108 } 109 110 111 /** 112 * Construct a new parser adapter. 113 * 114 * <p>Note that the embedded parser cannot be changed once the 115 * adapter is created; to embed a different parser, allocate 116 * a new ParserAdapter.</p> 117 * 118 * @param parser The SAX1 parser to embed. 119 * @exception java.lang.NullPointerException If the parser parameter 120 * is null. 121 */ ParserAdapter(Parser parser)122 public ParserAdapter (Parser parser) 123 { 124 setup(parser); 125 } 126 127 128 /** 129 * Internal setup method. 130 * 131 * @param parser The embedded parser. 132 * @exception java.lang.NullPointerException If the parser parameter 133 * is null. 134 */ 135 @UnsupportedAppUsage setup(Parser parser)136 private void setup (Parser parser) 137 { 138 if (parser == null) { 139 throw new 140 NullPointerException("Parser argument must not be null"); 141 } 142 this.parser = parser; 143 atts = new AttributesImpl(); 144 nsSupport = new NamespaceSupport(); 145 attAdapter = new AttributeListAdapter(); 146 } 147 148 149 150 //////////////////////////////////////////////////////////////////// 151 // Implementation of org.xml.sax.XMLReader. 152 //////////////////////////////////////////////////////////////////// 153 154 155 // 156 // Internal constants for the sake of convenience. 157 // 158 private static final String FEATURES = "http://xml.org/sax/features/"; 159 private static final String NAMESPACES = FEATURES + "namespaces"; 160 private static final String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes"; 161 private static final String XMLNS_URIs = FEATURES + "xmlns-uris"; 162 163 164 /** 165 * Set a feature flag for the parser. 166 * 167 * <p>The only features recognized are namespaces and 168 * namespace-prefixes.</p> 169 * 170 * @param name The feature name, as a complete URI. 171 * @param value The requested feature value. 172 * @exception SAXNotRecognizedException If the feature 173 * can't be assigned or retrieved. 174 * @exception SAXNotSupportedException If the feature 175 * can't be assigned that value. 176 * @see org.xml.sax.XMLReader#setFeature 177 */ setFeature(String name, boolean value)178 public void setFeature (String name, boolean value) 179 throws SAXNotRecognizedException, SAXNotSupportedException 180 { 181 if (name.equals(NAMESPACES)) { 182 checkNotParsing("feature", name); 183 namespaces = value; 184 if (!namespaces && !prefixes) { 185 prefixes = true; 186 } 187 } else if (name.equals(NAMESPACE_PREFIXES)) { 188 checkNotParsing("feature", name); 189 prefixes = value; 190 if (!prefixes && !namespaces) { 191 namespaces = true; 192 } 193 } else if (name.equals(XMLNS_URIs)) { 194 checkNotParsing("feature", name); 195 uris = value; 196 } else { 197 throw new SAXNotRecognizedException("Feature: " + name); 198 } 199 } 200 201 202 /** 203 * Check a parser feature flag. 204 * 205 * <p>The only features recognized are namespaces and 206 * namespace-prefixes.</p> 207 * 208 * @param name The feature name, as a complete URI. 209 * @return The current feature value. 210 * @exception SAXNotRecognizedException If the feature 211 * value can't be assigned or retrieved. 212 * @exception SAXNotSupportedException If the 213 * feature is not currently readable. 214 * @see org.xml.sax.XMLReader#setFeature 215 */ getFeature(String name)216 public boolean getFeature (String name) 217 throws SAXNotRecognizedException, SAXNotSupportedException 218 { 219 if (name.equals(NAMESPACES)) { 220 return namespaces; 221 } else if (name.equals(NAMESPACE_PREFIXES)) { 222 return prefixes; 223 } else if (name.equals(XMLNS_URIs)) { 224 return uris; 225 } else { 226 throw new SAXNotRecognizedException("Feature: " + name); 227 } 228 } 229 230 231 /** 232 * Set a parser property. 233 * 234 * <p>No properties are currently recognized.</p> 235 * 236 * @param name The property name. 237 * @param value The property value. 238 * @exception SAXNotRecognizedException If the property 239 * value can't be assigned or retrieved. 240 * @exception SAXNotSupportedException If the property 241 * can't be assigned that value. 242 * @see org.xml.sax.XMLReader#setProperty 243 */ setProperty(String name, Object value)244 public void setProperty (String name, Object value) 245 throws SAXNotRecognizedException, SAXNotSupportedException 246 { 247 throw new SAXNotRecognizedException("Property: " + name); 248 } 249 250 251 /** 252 * Get a parser property. 253 * 254 * <p>No properties are currently recognized.</p> 255 * 256 * @param name The property name. 257 * @return The property value. 258 * @exception SAXNotRecognizedException If the property 259 * value can't be assigned or retrieved. 260 * @exception SAXNotSupportedException If the property 261 * value is not currently readable. 262 * @see org.xml.sax.XMLReader#getProperty 263 */ getProperty(String name)264 public Object getProperty (String name) 265 throws SAXNotRecognizedException, SAXNotSupportedException 266 { 267 throw new SAXNotRecognizedException("Property: " + name); 268 } 269 270 271 /** 272 * Set the entity resolver. 273 * 274 * @param resolver The new entity resolver. 275 * @see org.xml.sax.XMLReader#setEntityResolver 276 */ setEntityResolver(EntityResolver resolver)277 public void setEntityResolver (EntityResolver resolver) 278 { 279 entityResolver = resolver; 280 } 281 282 283 /** 284 * Return the current entity resolver. 285 * 286 * @return The current entity resolver, or null if none was supplied. 287 * @see org.xml.sax.XMLReader#getEntityResolver 288 */ getEntityResolver()289 public EntityResolver getEntityResolver () 290 { 291 return entityResolver; 292 } 293 294 295 /** 296 * Set the DTD handler. 297 * 298 * @param handler the new DTD handler 299 * @see org.xml.sax.XMLReader#setEntityResolver 300 */ setDTDHandler(DTDHandler handler)301 public void setDTDHandler (DTDHandler handler) 302 { 303 dtdHandler = handler; 304 } 305 306 307 /** 308 * Return the current DTD handler. 309 * 310 * @return the current DTD handler, or null if none was supplied 311 * @see org.xml.sax.XMLReader#getEntityResolver 312 */ getDTDHandler()313 public DTDHandler getDTDHandler () 314 { 315 return dtdHandler; 316 } 317 318 319 /** 320 * Set the content handler. 321 * 322 * @param handler the new content handler 323 * @see org.xml.sax.XMLReader#setEntityResolver 324 */ setContentHandler(ContentHandler handler)325 public void setContentHandler (ContentHandler handler) 326 { 327 contentHandler = handler; 328 } 329 330 331 /** 332 * Return the current content handler. 333 * 334 * @return The current content handler, or null if none was supplied. 335 * @see org.xml.sax.XMLReader#getEntityResolver 336 */ getContentHandler()337 public ContentHandler getContentHandler () 338 { 339 return contentHandler; 340 } 341 342 343 /** 344 * Set the error handler. 345 * 346 * @param handler The new error handler. 347 * @see org.xml.sax.XMLReader#setEntityResolver 348 */ setErrorHandler(ErrorHandler handler)349 public void setErrorHandler (ErrorHandler handler) 350 { 351 errorHandler = handler; 352 } 353 354 355 /** 356 * Return the current error handler. 357 * 358 * @return The current error handler, or null if none was supplied. 359 * @see org.xml.sax.XMLReader#getEntityResolver 360 */ getErrorHandler()361 public ErrorHandler getErrorHandler () 362 { 363 return errorHandler; 364 } 365 366 367 /** 368 * Parse an XML document. 369 * 370 * @param systemId The absolute URL of the document. 371 * @exception java.io.IOException If there is a problem reading 372 * the raw content of the document. 373 * @exception SAXException If there is a problem 374 * processing the document. 375 * @see #parse(org.xml.sax.InputSource) 376 * @see org.xml.sax.Parser#parse(java.lang.String) 377 */ parse(String systemId)378 public void parse (String systemId) 379 throws IOException, SAXException 380 { 381 parse(new InputSource(systemId)); 382 } 383 384 385 /** 386 * Parse an XML document. 387 * 388 * @param input An input source for the document. 389 * @exception java.io.IOException If there is a problem reading 390 * the raw content of the document. 391 * @exception SAXException If there is a problem 392 * processing the document. 393 * @see #parse(java.lang.String) 394 * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource) 395 */ parse(InputSource input)396 public void parse (InputSource input) 397 throws IOException, SAXException 398 { 399 if (parsing) { 400 throw new SAXException("Parser is already in use"); 401 } 402 setupParser(); 403 parsing = true; 404 try { 405 parser.parse(input); 406 } finally { 407 parsing = false; 408 } 409 parsing = false; 410 } 411 412 413 414 //////////////////////////////////////////////////////////////////// 415 // Implementation of org.xml.sax.DocumentHandler. 416 //////////////////////////////////////////////////////////////////// 417 418 419 /** 420 * Adapter implementation method; do not call. 421 * Adapt a SAX1 document locator event. 422 * 423 * @param locator A document locator. 424 * @see org.xml.sax.ContentHandler#setDocumentLocator 425 */ setDocumentLocator(Locator locator)426 public void setDocumentLocator (Locator locator) 427 { 428 this.locator = locator; 429 if (contentHandler != null) { 430 contentHandler.setDocumentLocator(locator); 431 } 432 } 433 434 435 /** 436 * Adapter implementation method; do not call. 437 * Adapt a SAX1 start document event. 438 * 439 * @exception SAXException The client may raise a 440 * processing exception. 441 * @see org.xml.sax.DocumentHandler#startDocument 442 */ startDocument()443 public void startDocument () 444 throws SAXException 445 { 446 if (contentHandler != null) { 447 contentHandler.startDocument(); 448 } 449 } 450 451 452 /** 453 * Adapter implementation method; do not call. 454 * Adapt a SAX1 end document event. 455 * 456 * @exception SAXException The client may raise a 457 * processing exception. 458 * @see org.xml.sax.DocumentHandler#endDocument 459 */ endDocument()460 public void endDocument () 461 throws SAXException 462 { 463 if (contentHandler != null) { 464 contentHandler.endDocument(); 465 } 466 } 467 468 469 /** 470 * Adapter implementation method; do not call. 471 * Adapt a SAX1 startElement event. 472 * 473 * <p>If necessary, perform Namespace processing.</p> 474 * 475 * @param qName The qualified (prefixed) name. 476 * @param qAtts The XML attribute list (with qnames). 477 * @exception SAXException The client may raise a 478 * processing exception. 479 */ startElement(String qName, AttributeList qAtts)480 public void startElement (String qName, AttributeList qAtts) throws SAXException { 481 // These are exceptions from the 482 // first pass; they should be 483 // ignored if there's a second pass, 484 // but reported otherwise. 485 ArrayList<SAXParseException> exceptions = null; 486 487 // If we're not doing Namespace 488 // processing, dispatch this quickly. 489 if (!namespaces) { 490 if (contentHandler != null) { 491 attAdapter.setAttributeList(qAtts); 492 contentHandler.startElement("", "", qName.intern(), 493 attAdapter); 494 } 495 return; 496 } 497 498 499 // OK, we're doing Namespace processing. 500 nsSupport.pushContext(); 501 int length = qAtts.getLength(); 502 503 // First pass: handle NS decls 504 for (int i = 0; i < length; i++) { 505 String attQName = qAtts.getName(i); 506 507 if (!attQName.startsWith("xmlns")) 508 continue; 509 // Could be a declaration... 510 String prefix; 511 int n = attQName.indexOf(':'); 512 513 // xmlns=... 514 if (n == -1 && attQName.length () == 5) { 515 prefix = ""; 516 } else if (n != 5) { 517 // XML namespaces spec doesn't discuss "xmlnsf:oo" 518 // (and similarly named) attributes ... at most, warn 519 continue; 520 } else // xmlns:foo=... 521 prefix = attQName.substring(n+1); 522 523 String value = qAtts.getValue(i); 524 if (!nsSupport.declarePrefix(prefix, value)) { 525 reportError("Illegal Namespace prefix: " + prefix); 526 continue; 527 } 528 if (contentHandler != null) 529 contentHandler.startPrefixMapping(prefix, value); 530 } 531 532 // Second pass: copy all relevant 533 // attributes into the SAX2 AttributeList 534 // using updated prefix bindings 535 atts.clear(); 536 for (int i = 0; i < length; i++) { 537 String attQName = qAtts.getName(i); 538 String type = qAtts.getType(i); 539 String value = qAtts.getValue(i); 540 541 // Declaration? 542 if (attQName.startsWith("xmlns")) { 543 String prefix; 544 int n = attQName.indexOf(':'); 545 546 if (n == -1 && attQName.length () == 5) { 547 prefix = ""; 548 } else if (n != 5) { 549 // XML namespaces spec doesn't discuss "xmlnsf:oo" 550 // (and similarly named) attributes ... ignore 551 prefix = null; 552 } else { 553 prefix = attQName.substring(6); 554 } 555 // Yes, decl: report or prune 556 if (prefix != null) { 557 if (prefixes) { 558 if (uris) 559 // note funky case: localname can be null 560 // when declaring the default prefix, and 561 // yet the uri isn't null. 562 atts.addAttribute (nsSupport.XMLNS, prefix, 563 attQName.intern(), type, value); 564 else 565 atts.addAttribute ("", "", 566 attQName.intern(), type, value); 567 } 568 continue; 569 } 570 } 571 572 // Not a declaration -- report 573 try { 574 String attName[] = processName(attQName, true, true); 575 atts.addAttribute(attName[0], attName[1], attName[2], 576 type, value); 577 } catch (SAXException e) { 578 if (exceptions == null) { 579 exceptions = new ArrayList<SAXParseException>(); 580 } 581 exceptions.add((SAXParseException) e); 582 atts.addAttribute("", attQName, attQName, type, value); 583 } 584 } 585 586 // now handle the deferred exception reports 587 if (exceptions != null && errorHandler != null) { 588 for (SAXParseException ex : exceptions) { 589 errorHandler.error(ex); 590 } 591 } 592 593 // OK, finally report the event. 594 if (contentHandler != null) { 595 String name[] = processName(qName, false, false); 596 contentHandler.startElement(name[0], name[1], name[2], atts); 597 } 598 } 599 600 601 /** 602 * Adapter implementation method; do not call. 603 * Adapt a SAX1 end element event. 604 * 605 * @param qName The qualified (prefixed) name. 606 * @exception SAXException The client may raise a 607 * processing exception. 608 * @see org.xml.sax.DocumentHandler#endElement 609 */ endElement(String qName)610 public void endElement (String qName) 611 throws SAXException 612 { 613 // If we're not doing Namespace 614 // processing, dispatch this quickly. 615 if (!namespaces) { 616 if (contentHandler != null) { 617 contentHandler.endElement("", "", qName.intern()); 618 } 619 return; 620 } 621 622 // Split the name. 623 String names[] = processName(qName, false, false); 624 if (contentHandler != null) { 625 contentHandler.endElement(names[0], names[1], names[2]); 626 Enumeration prefixes = nsSupport.getDeclaredPrefixes(); 627 while (prefixes.hasMoreElements()) { 628 String prefix = (String)prefixes.nextElement(); 629 contentHandler.endPrefixMapping(prefix); 630 } 631 } 632 nsSupport.popContext(); 633 } 634 635 636 /** 637 * Adapter implementation method; do not call. 638 * Adapt a SAX1 characters event. 639 * 640 * @param ch An array of characters. 641 * @param start The starting position in the array. 642 * @param length The number of characters to use. 643 * @exception SAXException The client may raise a 644 * processing exception. 645 * @see org.xml.sax.DocumentHandler#characters 646 */ characters(char ch[], int start, int length)647 public void characters (char ch[], int start, int length) 648 throws SAXException 649 { 650 if (contentHandler != null) { 651 contentHandler.characters(ch, start, length); 652 } 653 } 654 655 656 /** 657 * Adapter implementation method; do not call. 658 * Adapt a SAX1 ignorable whitespace event. 659 * 660 * @param ch An array of characters. 661 * @param start The starting position in the array. 662 * @param length The number of characters to use. 663 * @exception SAXException The client may raise a 664 * processing exception. 665 * @see org.xml.sax.DocumentHandler#ignorableWhitespace 666 */ ignorableWhitespace(char ch[], int start, int length)667 public void ignorableWhitespace (char ch[], int start, int length) 668 throws SAXException 669 { 670 if (contentHandler != null) { 671 contentHandler.ignorableWhitespace(ch, start, length); 672 } 673 } 674 675 676 /** 677 * Adapter implementation method; do not call. 678 * Adapt a SAX1 processing instruction event. 679 * 680 * @param target The processing instruction target. 681 * @param data The remainder of the processing instruction 682 * @exception SAXException The client may raise a 683 * processing exception. 684 * @see org.xml.sax.DocumentHandler#processingInstruction 685 */ processingInstruction(String target, String data)686 public void processingInstruction (String target, String data) 687 throws SAXException 688 { 689 if (contentHandler != null) { 690 contentHandler.processingInstruction(target, data); 691 } 692 } 693 694 695 696 //////////////////////////////////////////////////////////////////// 697 // Internal utility methods. 698 //////////////////////////////////////////////////////////////////// 699 700 701 /** 702 * Initialize the parser before each run. 703 */ 704 @UnsupportedAppUsage setupParser()705 private void setupParser () 706 { 707 // catch an illegal "nonsense" state. 708 if (!prefixes && !namespaces) 709 throw new IllegalStateException (); 710 711 nsSupport.reset(); 712 if (uris) 713 nsSupport.setNamespaceDeclUris (true); 714 715 if (entityResolver != null) { 716 parser.setEntityResolver(entityResolver); 717 } 718 if (dtdHandler != null) { 719 parser.setDTDHandler(dtdHandler); 720 } 721 if (errorHandler != null) { 722 parser.setErrorHandler(errorHandler); 723 } 724 parser.setDocumentHandler(this); 725 locator = null; 726 } 727 728 729 /** 730 * Process a qualified (prefixed) name. 731 * 732 * <p>If the name has an undeclared prefix, use only the qname 733 * and make an ErrorHandler.error callback in case the app is 734 * interested.</p> 735 * 736 * @param qName The qualified (prefixed) name. 737 * @param isAttribute true if this is an attribute name. 738 * @return The name split into three parts. 739 * @exception SAXException The client may throw 740 * an exception if there is an error callback. 741 */ 742 @UnsupportedAppUsage processName(String qName, boolean isAttribute, boolean useException)743 private String [] processName (String qName, boolean isAttribute, 744 boolean useException) 745 throws SAXException 746 { 747 String parts[] = nsSupport.processName(qName, nameParts, 748 isAttribute); 749 if (parts == null) { 750 if (useException) 751 throw makeException("Undeclared prefix: " + qName); 752 reportError("Undeclared prefix: " + qName); 753 parts = new String[3]; 754 parts[0] = parts[1] = ""; 755 parts[2] = qName.intern(); 756 } 757 return parts; 758 } 759 760 761 /** 762 * Report a non-fatal error. 763 * 764 * @param message The error message. 765 * @exception SAXException The client may throw 766 * an exception. 767 */ 768 @UnsupportedAppUsage reportError(String message)769 void reportError (String message) 770 throws SAXException 771 { 772 if (errorHandler != null) 773 errorHandler.error(makeException(message)); 774 } 775 776 777 /** 778 * Construct an exception for the current context. 779 * 780 * @param message The error message. 781 */ 782 @UnsupportedAppUsage makeException(String message)783 private SAXParseException makeException (String message) 784 { 785 if (locator != null) { 786 return new SAXParseException(message, locator); 787 } else { 788 return new SAXParseException(message, null, null, -1, -1); 789 } 790 } 791 792 793 /** 794 * Throw an exception if we are parsing. 795 * 796 * <p>Use this method to detect illegal feature or 797 * property changes.</p> 798 * 799 * @param type The type of thing (feature or property). 800 * @param name The feature or property name. 801 * @exception SAXNotSupportedException If a 802 * document is currently being parsed. 803 */ 804 @UnsupportedAppUsage checkNotParsing(String type, String name)805 private void checkNotParsing (String type, String name) 806 throws SAXNotSupportedException 807 { 808 if (parsing) { 809 throw new SAXNotSupportedException("Cannot change " + 810 type + ' ' + 811 name + " while parsing"); 812 813 } 814 } 815 816 817 818 //////////////////////////////////////////////////////////////////// 819 // Internal state. 820 //////////////////////////////////////////////////////////////////// 821 822 @UnsupportedAppUsage 823 private NamespaceSupport nsSupport; 824 @UnsupportedAppUsage 825 private AttributeListAdapter attAdapter; 826 827 @UnsupportedAppUsage 828 private boolean parsing = false; 829 @UnsupportedAppUsage 830 private String nameParts[] = new String[3]; 831 832 @UnsupportedAppUsage 833 private Parser parser = null; 834 835 @UnsupportedAppUsage 836 private AttributesImpl atts = null; 837 838 // Features 839 @UnsupportedAppUsage 840 private boolean namespaces = true; 841 @UnsupportedAppUsage 842 private boolean prefixes = false; 843 @UnsupportedAppUsage 844 private boolean uris = false; 845 846 // Properties 847 848 // Handlers 849 @UnsupportedAppUsage 850 Locator locator; 851 852 @UnsupportedAppUsage 853 EntityResolver entityResolver = null; 854 @UnsupportedAppUsage 855 DTDHandler dtdHandler = null; 856 @UnsupportedAppUsage 857 ContentHandler contentHandler = null; 858 @UnsupportedAppUsage 859 ErrorHandler errorHandler = null; 860 861 862 863 //////////////////////////////////////////////////////////////////// 864 // Inner class to wrap an AttributeList when not doing NS proc. 865 //////////////////////////////////////////////////////////////////// 866 867 868 /** 869 * Adapt a SAX1 AttributeList as a SAX2 Attributes object. 870 * 871 * <p>This class is in the Public Domain, and comes with NO 872 * WARRANTY of any kind.</p> 873 * 874 * <p>This wrapper class is used only when Namespace support 875 * is disabled -- it provides pretty much a direct mapping 876 * from SAX1 to SAX2, except that names and types are 877 * interned whenever requested.</p> 878 */ 879 final class AttributeListAdapter implements Attributes 880 { 881 882 /** 883 * Construct a new adapter. 884 */ 885 @UnsupportedAppUsage AttributeListAdapter()886 AttributeListAdapter () 887 { 888 } 889 890 891 /** 892 * Set the embedded AttributeList. 893 * 894 * <p>This method must be invoked before any of the others 895 * can be used.</p> 896 * 897 * @param The SAX1 attribute list (with qnames). 898 */ setAttributeList(AttributeList qAtts)899 void setAttributeList (AttributeList qAtts) 900 { 901 this.qAtts = qAtts; 902 } 903 904 905 /** 906 * Return the length of the attribute list. 907 * 908 * @return The number of attributes in the list. 909 * @see org.xml.sax.Attributes#getLength 910 */ getLength()911 public int getLength () 912 { 913 return qAtts.getLength(); 914 } 915 916 917 /** 918 * Return the Namespace URI of the specified attribute. 919 * 920 * @param The attribute's index. 921 * @return Always the empty string. 922 * @see org.xml.sax.Attributes#getURI 923 */ getURI(int i)924 public String getURI (int i) 925 { 926 return ""; 927 } 928 929 930 /** 931 * Return the local name of the specified attribute. 932 * 933 * @param The attribute's index. 934 * @return Always the empty string. 935 * @see org.xml.sax.Attributes#getLocalName 936 */ getLocalName(int i)937 public String getLocalName (int i) 938 { 939 return ""; 940 } 941 942 943 /** 944 * Return the qualified (prefixed) name of the specified attribute. 945 * 946 * @param The attribute's index. 947 * @return The attribute's qualified name, internalized. 948 */ getQName(int i)949 public String getQName (int i) 950 { 951 return qAtts.getName(i).intern(); 952 } 953 954 955 /** 956 * Return the type of the specified attribute. 957 * 958 * @param The attribute's index. 959 * @return The attribute's type as an internalized string. 960 */ getType(int i)961 public String getType (int i) 962 { 963 return qAtts.getType(i).intern(); 964 } 965 966 967 /** 968 * Return the value of the specified attribute. 969 * 970 * @param The attribute's index. 971 * @return The attribute's value. 972 */ getValue(int i)973 public String getValue (int i) 974 { 975 return qAtts.getValue(i); 976 } 977 978 979 /** 980 * Look up an attribute index by Namespace name. 981 * 982 * @param uri The Namespace URI or the empty string. 983 * @param localName The local name. 984 * @return The attributes index, or -1 if none was found. 985 * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String) 986 */ getIndex(String uri, String localName)987 public int getIndex (String uri, String localName) 988 { 989 return -1; 990 } 991 992 993 /** 994 * Look up an attribute index by qualified (prefixed) name. 995 * 996 * @param qName The qualified name. 997 * @return The attributes index, or -1 if none was found. 998 * @see org.xml.sax.Attributes#getIndex(java.lang.String) 999 */ getIndex(String qName)1000 public int getIndex (String qName) 1001 { 1002 int max = atts.getLength(); 1003 for (int i = 0; i < max; i++) { 1004 if (qAtts.getName(i).equals(qName)) { 1005 return i; 1006 } 1007 } 1008 return -1; 1009 } 1010 1011 1012 /** 1013 * Look up the type of an attribute by Namespace name. 1014 * 1015 * @param uri The Namespace URI 1016 * @param localName The local name. 1017 * @return The attribute's type as an internalized string. 1018 */ getType(String uri, String localName)1019 public String getType (String uri, String localName) 1020 { 1021 return null; 1022 } 1023 1024 1025 /** 1026 * Look up the type of an attribute by qualified (prefixed) name. 1027 * 1028 * @param qName The qualified name. 1029 * @return The attribute's type as an internalized string. 1030 */ getType(String qName)1031 public String getType (String qName) 1032 { 1033 return qAtts.getType(qName).intern(); 1034 } 1035 1036 1037 /** 1038 * Look up the value of an attribute by Namespace name. 1039 * 1040 * @param uri The Namespace URI 1041 * @param localName The local name. 1042 * @return The attribute's value. 1043 */ getValue(String uri, String localName)1044 public String getValue (String uri, String localName) 1045 { 1046 return null; 1047 } 1048 1049 1050 /** 1051 * Look up the value of an attribute by qualified (prefixed) name. 1052 * 1053 * @param qName The qualified name. 1054 * @return The attribute's value. 1055 */ getValue(String qName)1056 public String getValue (String qName) 1057 { 1058 return qAtts.getValue(qName); 1059 } 1060 1061 private AttributeList qAtts; 1062 } 1063 } 1064 1065 // end of ParserAdapter.java 1066