1 16 17 package org.apache.xerces.impl; 18 19 import org.apache.xerces.impl.msg.XMLMessageFormatter; 20 import org.apache.xerces.util.SymbolTable; 21 import org.apache.xerces.util.XMLSymbols; 22 import org.apache.xerces.xni.Augmentations; 23 import org.apache.xerces.xni.NamespaceContext; 24 import org.apache.xerces.xni.QName; 25 import org.apache.xerces.xni.XMLAttributes; 26 import org.apache.xerces.xni.XMLDocumentHandler; 27 import org.apache.xerces.xni.XMLLocator; 28 import org.apache.xerces.xni.XMLResourceIdentifier; 29 import org.apache.xerces.xni.XMLString; 30 import org.apache.xerces.xni.XNIException; 31 import org.apache.xerces.xni.parser.XMLComponent; 32 import org.apache.xerces.xni.parser.XMLComponentManager; 33 import org.apache.xerces.xni.parser.XMLConfigurationException; 34 import org.apache.xerces.xni.parser.XMLDocumentFilter; 35 import org.apache.xerces.xni.parser.XMLDocumentSource; 36 37 57 public class XMLNamespaceBinder 58 implements XMLComponent, XMLDocumentFilter { 59 60 64 66 67 protected static final String NAMESPACES = 68 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; 69 70 72 73 protected static final String SYMBOL_TABLE = 74 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 75 76 77 protected static final String ERROR_REPORTER = 78 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 79 80 82 83 private static final String [] RECOGNIZED_FEATURES = { 84 NAMESPACES, 85 }; 86 87 88 private static final Boolean [] FEATURE_DEFAULTS = { 89 null, 90 }; 91 92 93 private static final String [] RECOGNIZED_PROPERTIES = { 94 SYMBOL_TABLE, 95 ERROR_REPORTER, 96 }; 97 98 99 private static final Object [] PROPERTY_DEFAULTS = { 100 null, 101 null, 102 }; 103 104 108 110 111 protected boolean fNamespaces; 112 113 115 116 protected SymbolTable fSymbolTable; 117 118 119 protected XMLErrorReporter fErrorReporter; 120 121 123 124 protected XMLDocumentHandler fDocumentHandler; 125 126 protected XMLDocumentSource fDocumentSource; 127 128 130 131 protected boolean fOnlyPassPrefixMappingEvents; 132 133 135 136 private NamespaceContext fNamespaceContext; 137 138 140 141 private QName fAttributeQName = new QName(); 142 143 147 148 public XMLNamespaceBinder() { 149 } 151 155 157 166 public void setOnlyPassPrefixMappingEvents(boolean onlyPassPrefixMappingEvents) { 167 fOnlyPassPrefixMappingEvents = onlyPassPrefixMappingEvents; 168 } 170 175 public boolean getOnlyPassPrefixMappingEvents() { 176 return fOnlyPassPrefixMappingEvents; 177 } 179 183 197 public void reset(XMLComponentManager componentManager) 198 throws XNIException { 199 200 try { 202 fNamespaces = componentManager.getFeature(NAMESPACES); 203 } 204 catch (XMLConfigurationException e) { 205 fNamespaces = true; 206 } 207 208 fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE); 210 fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); 211 212 } 214 219 public String [] getRecognizedFeatures() { 220 return (String [])(RECOGNIZED_FEATURES.clone()); 221 } 223 238 public void setFeature(String featureId, boolean state) 239 throws XMLConfigurationException { 240 } 242 247 public String [] getRecognizedProperties() { 248 return (String [])(RECOGNIZED_PROPERTIES.clone()); 249 } 251 257 public void setProperty(String propertyId, Object value) 258 throws XMLConfigurationException { 259 260 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 262 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 263 264 if (suffixLength == Constants.SYMBOL_TABLE_PROPERTY.length() && 265 propertyId.endsWith(Constants.SYMBOL_TABLE_PROPERTY)) { 266 fSymbolTable = (SymbolTable)value; 267 } 268 else if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() && 269 propertyId.endsWith(Constants.ERROR_REPORTER_PROPERTY)) { 270 fErrorReporter = (XMLErrorReporter)value; 271 } 272 return; 273 } 274 275 } 277 286 public Boolean getFeatureDefault(String featureId) { 287 for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { 288 if (RECOGNIZED_FEATURES[i].equals(featureId)) { 289 return FEATURE_DEFAULTS[i]; 290 } 291 } 292 return null; 293 } 295 304 public Object getPropertyDefault(String propertyId) { 305 for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { 306 if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { 307 return PROPERTY_DEFAULTS[i]; 308 } 309 } 310 return null; 311 } 313 317 318 public void setDocumentHandler(XMLDocumentHandler documentHandler) { 319 fDocumentHandler = documentHandler; 320 } 322 323 public XMLDocumentHandler getDocumentHandler() { 324 return fDocumentHandler; 325 } 327 328 332 333 public void setDocumentSource(XMLDocumentSource source){ 334 fDocumentSource = source; 335 } 337 338 public XMLDocumentSource getDocumentSource (){ 339 return fDocumentSource; 340 } 342 343 360 public void startGeneralEntity(String name, 361 XMLResourceIdentifier identifier, 362 String encoding, Augmentations augs) 363 throws XNIException { 364 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 365 fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs); 366 } 367 } 369 386 public void textDecl(String version, String encoding, Augmentations augs) 387 throws XNIException { 388 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 389 fDocumentHandler.textDecl(version, encoding, augs); 390 } 391 } 393 415 public void startDocument(XMLLocator locator, String encoding, 416 NamespaceContext namespaceContext, Augmentations augs) 417 throws XNIException { 418 fNamespaceContext = namespaceContext; 419 420 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 421 fDocumentHandler.startDocument(locator, encoding, namespaceContext, augs); 422 } 423 } 425 438 public void xmlDecl(String version, String encoding, String standalone, Augmentations augs) 439 throws XNIException { 440 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 441 fDocumentHandler.xmlDecl(version, encoding, standalone, augs); 442 } 443 } 445 457 public void doctypeDecl(String rootElement, 458 String publicId, String systemId, Augmentations augs) 459 throws XNIException { 460 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 461 fDocumentHandler.doctypeDecl(rootElement, publicId, systemId, augs); 462 } 463 } 465 473 public void comment(XMLString text, Augmentations augs) throws XNIException { 474 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 475 fDocumentHandler.comment(text, augs); 476 } 477 } 479 496 public void processingInstruction(String target, XMLString data, Augmentations augs) 497 throws XNIException { 498 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 499 fDocumentHandler.processingInstruction(target, data, augs); 500 } 501 } 503 504 519 public void startElement(QName element, XMLAttributes attributes, Augmentations augs) 520 throws XNIException { 521 522 if (fNamespaces) { 523 handleStartElement(element, attributes, augs, false); 524 } 525 else if (fDocumentHandler != null) { 526 fDocumentHandler.startElement(element, attributes, augs); 527 } 528 529 530 } 532 541 public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) 542 throws XNIException { 543 544 if (fNamespaces) { 545 handleStartElement(element, attributes, augs, true); 546 handleEndElement(element, augs, true); 547 } 548 else if (fDocumentHandler != null) { 549 fDocumentHandler.emptyElement(element, attributes, augs); 550 } 551 552 } 554 562 public void characters(XMLString text, Augmentations augs) throws XNIException { 563 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 564 fDocumentHandler.characters(text, augs); 565 } 566 } 568 581 public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException { 582 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 583 fDocumentHandler.ignorableWhitespace(text, augs); 584 } 585 } 587 595 public void endElement(QName element, Augmentations augs) throws XNIException { 596 597 if (fNamespaces) { 598 handleEndElement(element, augs, false); 599 } 600 else if (fDocumentHandler != null) { 601 fDocumentHandler.endElement(element, augs); 602 } 603 604 } 606 612 public void startCDATA(Augmentations augs) throws XNIException { 613 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 614 fDocumentHandler.startCDATA(augs); 615 } 616 } 618 624 public void endCDATA(Augmentations augs) throws XNIException { 625 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 626 fDocumentHandler.endCDATA(augs); 627 } 628 } 630 636 public void endDocument(Augmentations augs) throws XNIException { 637 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 638 fDocumentHandler.endDocument(augs); 639 } 640 } 642 654 public void endGeneralEntity(String name, Augmentations augs) throws XNIException { 655 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 656 fDocumentHandler.endGeneralEntity(name, augs); 657 } 658 } 660 664 665 protected void handleStartElement(QName element, XMLAttributes attributes, 666 Augmentations augs, 667 boolean isEmpty) throws XNIException { 668 669 fNamespaceContext.pushContext(); 671 672 if (element.prefix == XMLSymbols.PREFIX_XMLNS) { 673 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 674 "ElementXMLNSPrefix", 675 new Object []{element.rawname}, 676 XMLErrorReporter.SEVERITY_FATAL_ERROR); 677 } 678 679 int length = attributes.getLength(); 681 for (int i = 0; i < length; i++) { 682 String localpart = attributes.getLocalName(i); 683 String prefix = attributes.getPrefix(i); 684 if (prefix == XMLSymbols.PREFIX_XMLNS || 687 prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) { 688 689 String uri = fSymbolTable.addSymbol(attributes.getValue(i)); 691 692 if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) { 694 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 695 "CantBindXMLNS", 696 new Object []{attributes.getQName(i)}, 697 XMLErrorReporter.SEVERITY_FATAL_ERROR); 698 } 699 700 if (uri == NamespaceContext.XMLNS_URI) { 702 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 703 "CantBindXMLNS", 704 new Object []{attributes.getQName(i)}, 705 XMLErrorReporter.SEVERITY_FATAL_ERROR); 706 } 707 708 if (localpart == XMLSymbols.PREFIX_XML) { 710 if (uri != NamespaceContext.XML_URI) { 711 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 712 "CantBindXML", 713 new Object []{attributes.getQName(i)}, 714 XMLErrorReporter.SEVERITY_FATAL_ERROR); 715 } 716 } 717 else { 719 if (uri ==NamespaceContext.XML_URI) { 720 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 721 "CantBindXML", 722 new Object []{attributes.getQName(i)}, 723 XMLErrorReporter.SEVERITY_FATAL_ERROR); 724 } 725 } 726 727 prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING; 728 729 if(prefixBoundToNullURI(uri, localpart)) { 737 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 738 "EmptyPrefixedAttName", 739 new Object []{attributes.getQName(i)}, 740 XMLErrorReporter.SEVERITY_FATAL_ERROR); 741 continue; 742 } 743 744 fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null); 746 747 } 748 } 749 750 String prefix = element.prefix != null 752 ? element.prefix : XMLSymbols.EMPTY_STRING; 753 element.uri = fNamespaceContext.getURI(prefix); 754 if (element.prefix == null && element.uri != null) { 755 element.prefix = XMLSymbols.EMPTY_STRING; 756 } 757 if (element.prefix != null && element.uri == null) { 758 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 759 "ElementPrefixUnbound", 760 new Object []{element.prefix, element.rawname}, 761 XMLErrorReporter.SEVERITY_FATAL_ERROR); 762 } 763 764 for (int i = 0; i < length; i++) { 766 attributes.getName(i, fAttributeQName); 767 String aprefix = fAttributeQName.prefix != null 768 ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; 769 String arawname = fAttributeQName.rawname; 770 if (arawname == XMLSymbols.PREFIX_XMLNS) { 771 fAttributeQName.uri = fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS); 772 attributes.setName(i, fAttributeQName); 773 } 774 else if (aprefix != XMLSymbols.EMPTY_STRING) { 775 fAttributeQName.uri = fNamespaceContext.getURI(aprefix); 776 if (fAttributeQName.uri == null) { 777 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 778 "AttributePrefixUnbound", 779 new Object []{element.rawname,arawname,aprefix}, 780 XMLErrorReporter.SEVERITY_FATAL_ERROR); 781 } 782 attributes.setName(i, fAttributeQName); 783 } 784 } 785 786 int attrCount = attributes.getLength(); 789 for (int i = 0; i < attrCount - 1; i++) { 790 String auri = attributes.getURI(i); 791 if (auri == null || auri == NamespaceContext.XMLNS_URI) { 792 continue; 793 } 794 String alocalpart = attributes.getLocalName(i); 795 for (int j = i + 1; j < attrCount; j++) { 796 String blocalpart = attributes.getLocalName(j); 797 String buri = attributes.getURI(j); 798 if (alocalpart == blocalpart && auri == buri) { 799 fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, 800 "AttributeNSNotUnique", 801 new Object []{element.rawname,alocalpart, auri}, 802 XMLErrorReporter.SEVERITY_FATAL_ERROR); 803 } 804 } 805 } 806 807 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 809 if (isEmpty) { 810 fDocumentHandler.emptyElement(element, attributes, augs); 811 } 812 else { 813 fDocumentHandler.startElement(element, attributes, augs); 814 } 815 } 816 817 818 } 820 821 protected void handleEndElement(QName element, Augmentations augs, boolean isEmpty) 822 throws XNIException { 823 824 String eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING; 826 element.uri = fNamespaceContext.getURI(eprefix); 827 if (element.uri != null) { 828 element.prefix = eprefix; 829 } 830 831 if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) { 833 if (!isEmpty) { 834 fDocumentHandler.endElement(element, augs); 835 } 836 } 837 838 fNamespaceContext.popContext(); 840 841 } 843 protected boolean prefixBoundToNullURI(String uri, String localpart) { 846 return (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS); 847 } 849 } | Popular Tags |