1 16 17 package org.apache.xerces.impl; 18 19 import java.io.IOException ; 20 21 import org.apache.xerces.impl.dtd.XMLDTDValidatorFilter; 22 import org.apache.xerces.impl.msg.XMLMessageFormatter; 23 import org.apache.xerces.util.XMLAttributesImpl; 24 import org.apache.xerces.util.XMLSymbols; 25 import org.apache.xerces.xni.NamespaceContext; 26 import org.apache.xerces.xni.QName; 27 import org.apache.xerces.xni.XMLDocumentHandler; 28 import org.apache.xerces.xni.XNIException; 29 import org.apache.xerces.xni.parser.XMLComponentManager; 30 import org.apache.xerces.xni.parser.XMLConfigurationException; 31 import org.apache.xerces.xni.parser.XMLDocumentSource; 32 33 66 public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl { 67 68 72 protected boolean fBindNamespaces; 73 74 78 protected boolean fPerformValidation; 79 80 83 84 private XMLDTDValidatorFilter fDTDValidator; 85 86 93 private boolean fSawSpace; 94 95 101 public void setDTDValidator(XMLDTDValidatorFilter validator) { 102 fDTDValidator = validator; 103 } 104 105 126 protected boolean scanStartElement() throws IOException , XNIException { 127 if (DEBUG_CONTENT_SCANNING) 128 System.out.println(">>> scanStartElementNS()"); 129 130 fEntityScanner.scanQName(fElementQName); 132 String rawname = fElementQName.rawname; 134 if (fBindNamespaces) { 135 fNamespaceContext.pushContext(); 136 if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) { 137 if (fPerformValidation) { 138 fErrorReporter.reportError( 139 XMLMessageFormatter.XML_DOMAIN, 140 "MSG_GRAMMAR_NOT_FOUND", 141 new Object [] { rawname }, 142 XMLErrorReporter.SEVERITY_ERROR); 143 144 if (fDoctypeName == null 145 || !fDoctypeName.equals(rawname)) { 146 fErrorReporter.reportError( 147 XMLMessageFormatter.XML_DOMAIN, 148 "RootElementTypeMustMatchDoctypedecl", 149 new Object [] { fDoctypeName, rawname }, 150 XMLErrorReporter.SEVERITY_ERROR); 151 } 152 } 153 } 154 } 155 156 fCurrentElement = fElementStack.pushElement(fElementQName); 158 159 boolean empty = false; 161 fAttributes.removeAllAttributes(); 162 do { 163 boolean sawSpace = fEntityScanner.skipSpaces(); 165 166 int c = fEntityScanner.peekChar(); 168 if (c == '>') { 169 fEntityScanner.scanChar(); 170 break; 171 } else if (c == '/') { 172 fEntityScanner.scanChar(); 173 if (!fEntityScanner.skipChar('>')) { 174 reportFatalError( 175 "ElementUnterminated", 176 new Object [] { rawname }); 177 } 178 empty = true; 179 break; 180 } else if (!isValidNameStartChar(c) || !sawSpace) { 181 if (!isValidNameStartHighSurrogate(c) || !sawSpace) { 184 reportFatalError( 185 "ElementUnterminated", 186 new Object [] { rawname }); 187 } 188 } 189 190 scanAttribute(fAttributes); 192 193 } while (true); 194 195 if (fBindNamespaces) { 196 if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) { 198 fErrorReporter.reportError( 199 XMLMessageFormatter.XMLNS_DOMAIN, 200 "ElementXMLNSPrefix", 201 new Object [] { fElementQName.rawname }, 202 XMLErrorReporter.SEVERITY_FATAL_ERROR); 203 } 204 205 String prefix = 207 fElementQName.prefix != null 208 ? fElementQName.prefix 209 : XMLSymbols.EMPTY_STRING; 210 fElementQName.uri = fNamespaceContext.getURI(prefix); 212 fCurrentElement.uri = fElementQName.uri; 214 215 if (fElementQName.prefix == null && fElementQName.uri != null) { 216 fElementQName.prefix = XMLSymbols.EMPTY_STRING; 217 fCurrentElement.prefix = XMLSymbols.EMPTY_STRING; 219 } 220 if (fElementQName.prefix != null && fElementQName.uri == null) { 221 fErrorReporter.reportError( 222 XMLMessageFormatter.XMLNS_DOMAIN, 223 "ElementPrefixUnbound", 224 new Object [] { 225 fElementQName.prefix, 226 fElementQName.rawname }, 227 XMLErrorReporter.SEVERITY_FATAL_ERROR); 228 } 229 230 int length = fAttributes.getLength(); 232 for (int i = 0; i < length; i++) { 233 fAttributes.getName(i, fAttributeQName); 234 235 String aprefix = 236 fAttributeQName.prefix != null 237 ? fAttributeQName.prefix 238 : XMLSymbols.EMPTY_STRING; 239 String uri = fNamespaceContext.getURI(aprefix); 240 if (fAttributeQName.uri != null 243 && fAttributeQName.uri == uri) { 244 continue; 245 } 246 if (aprefix != XMLSymbols.EMPTY_STRING) { 247 fAttributeQName.uri = uri; 248 if (uri == null) { 249 fErrorReporter.reportError( 250 XMLMessageFormatter.XMLNS_DOMAIN, 251 "AttributePrefixUnbound", 252 new Object [] { 253 fElementQName.rawname, 254 fAttributeQName.rawname, 255 aprefix }, 256 XMLErrorReporter.SEVERITY_FATAL_ERROR); 257 } 258 fAttributes.setURI(i, uri); 259 } 260 } 261 262 if (length > 1) { 263 QName name = fAttributes.checkDuplicatesNS(); 264 if (name != null) { 265 if (name.uri != null) { 266 fErrorReporter.reportError( 267 XMLMessageFormatter.XMLNS_DOMAIN, 268 "AttributeNSNotUnique", 269 new Object [] { 270 fElementQName.rawname, 271 name.localpart, 272 name.uri }, 273 XMLErrorReporter.SEVERITY_FATAL_ERROR); 274 } else { 275 fErrorReporter.reportError( 276 XMLMessageFormatter.XMLNS_DOMAIN, 277 "AttributeNotUnique", 278 new Object [] { 279 fElementQName.rawname, 280 name.rawname }, 281 XMLErrorReporter.SEVERITY_FATAL_ERROR); 282 } 283 } 284 } 285 } 286 287 if (fDocumentHandler != null) { 289 if (empty) { 290 291 fMarkupDepth--; 293 294 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 296 reportFatalError( 297 "ElementEntityMismatch", 298 new Object [] { fCurrentElement.rawname }); 299 } 300 301 fDocumentHandler.emptyElement(fElementQName, fAttributes, null); 302 303 if (fBindNamespaces) { 304 fNamespaceContext.popContext(); 305 } 306 fElementStack.popElement(fElementQName); 308 } else { 309 fDocumentHandler.startElement(fElementQName, fAttributes, null); 310 } 311 } 312 313 if (DEBUG_CONTENT_SCANNING) 314 System.out.println("<<< scanStartElement(): " + empty); 315 return empty; 316 317 } 319 324 protected void scanStartElementName () 325 throws IOException , XNIException { 326 fEntityScanner.scanQName(fElementQName); 328 fSawSpace = fEntityScanner.skipSpaces(); 331 } 333 339 protected boolean scanStartElementAfterName() 340 throws IOException , XNIException { 341 342 String rawname = fElementQName.rawname; 344 if (fBindNamespaces) { 345 fNamespaceContext.pushContext(); 346 if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) { 347 if (fPerformValidation) { 348 fErrorReporter.reportError( 349 XMLMessageFormatter.XML_DOMAIN, 350 "MSG_GRAMMAR_NOT_FOUND", 351 new Object [] { rawname }, 352 XMLErrorReporter.SEVERITY_ERROR); 353 354 if (fDoctypeName == null 355 || !fDoctypeName.equals(rawname)) { 356 fErrorReporter.reportError( 357 XMLMessageFormatter.XML_DOMAIN, 358 "RootElementTypeMustMatchDoctypedecl", 359 new Object [] { fDoctypeName, rawname }, 360 XMLErrorReporter.SEVERITY_ERROR); 361 } 362 } 363 } 364 } 365 366 fCurrentElement = fElementStack.pushElement(fElementQName); 368 369 boolean empty = false; 371 fAttributes.removeAllAttributes(); 372 do { 373 374 int c = fEntityScanner.peekChar(); 376 if (c == '>') { 377 fEntityScanner.scanChar(); 378 break; 379 } else if (c == '/') { 380 fEntityScanner.scanChar(); 381 if (!fEntityScanner.skipChar('>')) { 382 reportFatalError( 383 "ElementUnterminated", 384 new Object [] { rawname }); 385 } 386 empty = true; 387 break; 388 } else if (!isValidNameStartChar(c) || !fSawSpace) { 389 if (!isValidNameStartHighSurrogate(c) || !fSawSpace) { 392 reportFatalError( 393 "ElementUnterminated", 394 new Object [] { rawname }); 395 } 396 } 397 398 scanAttribute(fAttributes); 400 401 fSawSpace = fEntityScanner.skipSpaces(); 403 404 } while (true); 405 406 if (fBindNamespaces) { 407 if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) { 409 fErrorReporter.reportError( 410 XMLMessageFormatter.XMLNS_DOMAIN, 411 "ElementXMLNSPrefix", 412 new Object [] { fElementQName.rawname }, 413 XMLErrorReporter.SEVERITY_FATAL_ERROR); 414 } 415 416 String prefix = 418 fElementQName.prefix != null 419 ? fElementQName.prefix 420 : XMLSymbols.EMPTY_STRING; 421 fElementQName.uri = fNamespaceContext.getURI(prefix); 423 fCurrentElement.uri = fElementQName.uri; 425 426 if (fElementQName.prefix == null && fElementQName.uri != null) { 427 fElementQName.prefix = XMLSymbols.EMPTY_STRING; 428 fCurrentElement.prefix = XMLSymbols.EMPTY_STRING; 430 } 431 if (fElementQName.prefix != null && fElementQName.uri == null) { 432 fErrorReporter.reportError( 433 XMLMessageFormatter.XMLNS_DOMAIN, 434 "ElementPrefixUnbound", 435 new Object [] { 436 fElementQName.prefix, 437 fElementQName.rawname }, 438 XMLErrorReporter.SEVERITY_FATAL_ERROR); 439 } 440 441 int length = fAttributes.getLength(); 443 for (int i = 0; i < length; i++) { 444 fAttributes.getName(i, fAttributeQName); 445 446 String aprefix = 447 fAttributeQName.prefix != null 448 ? fAttributeQName.prefix 449 : XMLSymbols.EMPTY_STRING; 450 String uri = fNamespaceContext.getURI(aprefix); 451 if (fAttributeQName.uri != null 454 && fAttributeQName.uri == uri) { 455 continue; 456 } 457 if (aprefix != XMLSymbols.EMPTY_STRING) { 458 fAttributeQName.uri = uri; 459 if (uri == null) { 460 fErrorReporter.reportError( 461 XMLMessageFormatter.XMLNS_DOMAIN, 462 "AttributePrefixUnbound", 463 new Object [] { 464 fElementQName.rawname, 465 fAttributeQName.rawname, 466 aprefix }, 467 XMLErrorReporter.SEVERITY_FATAL_ERROR); 468 } 469 fAttributes.setURI(i, uri); 470 } 471 } 472 473 if (length > 1) { 474 QName name = fAttributes.checkDuplicatesNS(); 475 if (name != null) { 476 if (name.uri != null) { 477 fErrorReporter.reportError( 478 XMLMessageFormatter.XMLNS_DOMAIN, 479 "AttributeNSNotUnique", 480 new Object [] { 481 fElementQName.rawname, 482 name.localpart, 483 name.uri }, 484 XMLErrorReporter.SEVERITY_FATAL_ERROR); 485 } else { 486 fErrorReporter.reportError( 487 XMLMessageFormatter.XMLNS_DOMAIN, 488 "AttributeNotUnique", 489 new Object [] { 490 fElementQName.rawname, 491 name.rawname }, 492 XMLErrorReporter.SEVERITY_FATAL_ERROR); 493 } 494 } 495 } 496 } 497 498 if (fDocumentHandler != null) { 500 if (empty) { 501 502 fMarkupDepth--; 504 505 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 507 reportFatalError( 508 "ElementEntityMismatch", 509 new Object [] { fCurrentElement.rawname }); 510 } 511 512 fDocumentHandler.emptyElement(fElementQName, fAttributes, null); 513 514 if (fBindNamespaces) { 515 fNamespaceContext.popContext(); 516 } 517 fElementStack.popElement(fElementQName); 519 } else { 520 fDocumentHandler.startElement(fElementQName, fAttributes, null); 521 } 522 } 523 524 if (DEBUG_CONTENT_SCANNING) 525 System.out.println("<<< scanStartElementAfterName(): " + empty); 526 return empty; 527 528 } 530 547 protected void scanAttribute(XMLAttributesImpl attributes) 548 throws IOException , XNIException { 549 if (DEBUG_CONTENT_SCANNING) 550 System.out.println(">>> scanAttribute()"); 551 552 fEntityScanner.scanQName(fAttributeQName); 554 555 fEntityScanner.skipSpaces(); 557 if (!fEntityScanner.skipChar('=')) { 558 reportFatalError( 559 "EqRequiredInAttribute", 560 new Object [] { 561 fCurrentElement.rawname, 562 fAttributeQName.rawname }); 563 } 564 fEntityScanner.skipSpaces(); 565 566 int attrIndex; 568 569 if (fBindNamespaces) { 570 attrIndex = attributes.getLength(); 571 attributes.addAttributeNS( 572 fAttributeQName, 573 XMLSymbols.fCDATASymbol, 574 null); 575 } else { 576 int oldLen = attributes.getLength(); 577 attrIndex = 578 attributes.addAttribute( 579 fAttributeQName, 580 XMLSymbols.fCDATASymbol, 581 null); 582 583 if (oldLen == attributes.getLength()) { 585 reportFatalError( 586 "AttributeNotUnique", 587 new Object [] { 588 fCurrentElement.rawname, 589 fAttributeQName.rawname }); 590 } 591 } 592 593 boolean isVC = fHasExternalDTD && !fStandalone; 595 596 boolean isSameNormalizedAttr = scanAttributeValue(this.fTempString, fTempString2, 598 fAttributeQName.rawname,isVC,fCurrentElement.rawname); 599 600 String value = fTempString.toString(); 601 attributes.setValue(attrIndex, value); 602 if (!isSameNormalizedAttr) { 604 attributes.setNonNormalizedValue(attrIndex, fTempString2.toString()); 605 } 606 attributes.setSpecified(attrIndex, true); 607 608 if (fBindNamespaces) { 610 611 String localpart = fAttributeQName.localpart; 612 String prefix = 613 fAttributeQName.prefix != null 614 ? fAttributeQName.prefix 615 : XMLSymbols.EMPTY_STRING; 616 if (prefix == XMLSymbols.PREFIX_XMLNS 619 || prefix == XMLSymbols.EMPTY_STRING 620 && localpart == XMLSymbols.PREFIX_XMLNS) { 621 622 String uri = fSymbolTable.addSymbol(value); 624 625 if (prefix == XMLSymbols.PREFIX_XMLNS 627 && localpart == XMLSymbols.PREFIX_XMLNS) { 628 fErrorReporter.reportError( 629 XMLMessageFormatter.XMLNS_DOMAIN, 630 "CantBindXMLNS", 631 new Object [] { fAttributeQName }, 632 XMLErrorReporter.SEVERITY_FATAL_ERROR); 633 } 634 635 if (uri == NamespaceContext.XMLNS_URI) { 637 fErrorReporter.reportError( 638 XMLMessageFormatter.XMLNS_DOMAIN, 639 "CantBindXMLNS", 640 new Object [] { fAttributeQName }, 641 XMLErrorReporter.SEVERITY_FATAL_ERROR); 642 } 643 644 if (localpart == XMLSymbols.PREFIX_XML) { 646 if (uri != NamespaceContext.XML_URI) { 647 fErrorReporter.reportError( 648 XMLMessageFormatter.XMLNS_DOMAIN, 649 "CantBindXML", 650 new Object [] { fAttributeQName }, 651 XMLErrorReporter.SEVERITY_FATAL_ERROR); 652 } 653 } 654 else { 656 if (uri == NamespaceContext.XML_URI) { 657 fErrorReporter.reportError( 658 XMLMessageFormatter.XMLNS_DOMAIN, 659 "CantBindXML", 660 new Object [] { fAttributeQName }, 661 XMLErrorReporter.SEVERITY_FATAL_ERROR); 662 } 663 } 664 665 prefix = 666 localpart != XMLSymbols.PREFIX_XMLNS 667 ? localpart 668 : XMLSymbols.EMPTY_STRING; 669 670 fNamespaceContext.declarePrefix( 674 prefix, 675 uri.length() != 0 ? uri : null); 676 attributes.setURI( 678 attrIndex, 679 fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS)); 680 681 } else { 682 if (fAttributeQName.prefix != null) { 684 attributes.setURI( 685 attrIndex, 686 fNamespaceContext.getURI(fAttributeQName.prefix)); 687 } 688 } 689 } 690 691 if (DEBUG_CONTENT_SCANNING) 692 System.out.println("<<< scanAttribute()"); 693 } 695 709 protected int scanEndElement() throws IOException , XNIException { 710 if (DEBUG_CONTENT_SCANNING) 711 System.out.println(">>> scanEndElement()"); 712 713 fElementStack.popElement(fElementQName); 715 716 721 723 if (!fEntityScanner.skipString(fElementQName.rawname)) { 726 reportFatalError( 727 "ETagRequired", 728 new Object [] { fElementQName.rawname }); 729 } 730 731 fEntityScanner.skipSpaces(); 733 if (!fEntityScanner.skipChar('>')) { 734 reportFatalError( 735 "ETagUnterminated", 736 new Object [] { fElementQName.rawname }); 737 } 738 fMarkupDepth--; 739 740 fMarkupDepth--; 742 743 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 745 reportFatalError( 746 "ElementEntityMismatch", 747 new Object [] { fCurrentElement.rawname }); 748 } 749 750 if (fDocumentHandler != null) { 752 753 fDocumentHandler.endElement(fElementQName, null); 754 if (fBindNamespaces) { 755 fNamespaceContext.popContext(); 756 } 757 758 } 759 760 return fMarkupDepth; 761 762 } 764 public void reset(XMLComponentManager componentManager) 765 throws XMLConfigurationException { 766 767 super.reset(componentManager); 768 fPerformValidation = false; 769 fBindNamespaces = false; 770 } 771 772 773 protected Dispatcher createContentDispatcher() { 774 return new NS11ContentDispatcher(); 775 } 777 780 protected final class NS11ContentDispatcher extends ContentDispatcher { 781 794 protected boolean scanRootElementHook() 795 throws IOException , XNIException { 796 797 if (fExternalSubsetResolver != null && !fSeenDoctypeDecl 798 && !fDisallowDoctype && (fValidation || fLoadExternalDTD)) { 799 scanStartElementName(); 800 resolveExternalSubsetAndRead(); 801 reconfigurePipeline(); 802 if (scanStartElementAfterName()) { 803 setScannerState(SCANNER_STATE_TRAILING_MISC); 804 setDispatcher(fTrailingMiscDispatcher); 805 return true; 806 } 807 } 808 else { 809 reconfigurePipeline(); 810 if (scanStartElement()) { 811 setScannerState(SCANNER_STATE_TRAILING_MISC); 812 setDispatcher(fTrailingMiscDispatcher); 813 return true; 814 } 815 } 816 return false; 817 818 } 820 826 private void reconfigurePipeline() { 827 if (fDTDValidator == null) { 828 fBindNamespaces = true; 829 } 830 else if (!fDTDValidator.hasGrammar()) { 831 fBindNamespaces = true; 832 fPerformValidation = fDTDValidator.validate(); 833 XMLDocumentSource source = fDTDValidator.getDocumentSource(); 835 XMLDocumentHandler handler = fDTDValidator.getDocumentHandler(); 836 source.setDocumentHandler(handler); 837 if (handler != null) 838 handler.setDocumentSource(source); 839 fDTDValidator.setDocumentSource(null); 840 fDTDValidator.setDocumentHandler(null); 841 } 842 } } 844 } 845 | Popular Tags |