1 16 17 package org.apache.xerces.impl; 18 19 import java.io.CharConversionException ; 20 import java.io.EOFException ; 21 import java.io.IOException ; 22 23 import org.apache.xerces.impl.dtd.XMLDTDDescription; 24 import org.apache.xerces.impl.io.MalformedByteSequenceException; 25 import org.apache.xerces.impl.validation.ValidationManager; 26 import org.apache.xerces.util.NamespaceSupport; 27 import org.apache.xerces.util.XMLChar; 28 import org.apache.xerces.util.XMLStringBuffer; 29 import org.apache.xerces.xni.Augmentations; 30 import org.apache.xerces.xni.NamespaceContext; 31 import org.apache.xerces.xni.XMLResourceIdentifier; 32 import org.apache.xerces.xni.XMLString; 33 import org.apache.xerces.xni.XNIException; 34 import org.apache.xerces.xni.parser.XMLComponentManager; 35 import org.apache.xerces.xni.parser.XMLConfigurationException; 36 import org.apache.xerces.xni.parser.XMLDTDScanner; 37 import org.apache.xerces.xni.parser.XMLInputSource; 38 39 67 public class XMLDocumentScannerImpl 68 extends XMLDocumentFragmentScannerImpl { 69 70 74 76 77 protected static final int SCANNER_STATE_XML_DECL = 0; 78 79 80 protected static final int SCANNER_STATE_PROLOG = 5; 81 82 83 protected static final int SCANNER_STATE_TRAILING_MISC = 12; 84 85 86 protected static final int SCANNER_STATE_DTD_INTERNAL_DECLS = 17; 87 88 89 protected static final int SCANNER_STATE_DTD_EXTERNAL = 18; 90 91 92 protected static final int SCANNER_STATE_DTD_EXTERNAL_DECLS = 19; 93 94 96 97 protected static final String LOAD_EXTERNAL_DTD = 98 Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE; 99 100 101 protected static final String DISALLOW_DOCTYPE_DECL_FEATURE = 102 Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE; 103 104 106 107 protected static final String DTD_SCANNER = 108 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY; 109 110 111 protected static final String VALIDATION_MANAGER = 112 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 113 114 115 protected static final String NAMESPACE_CONTEXT = 116 Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY; 117 118 119 120 122 123 private static final String [] RECOGNIZED_FEATURES = { 124 LOAD_EXTERNAL_DTD, 125 DISALLOW_DOCTYPE_DECL_FEATURE, 126 }; 127 128 129 private static final Boolean [] FEATURE_DEFAULTS = { 130 Boolean.TRUE, 131 Boolean.FALSE, 132 }; 133 134 135 private static final String [] RECOGNIZED_PROPERTIES = { 136 DTD_SCANNER, 137 VALIDATION_MANAGER, 138 NAMESPACE_CONTEXT, 139 }; 140 141 142 private static final Object [] PROPERTY_DEFAULTS = { 143 null, 144 null, 145 null, 146 }; 147 148 152 154 155 protected XMLDTDScanner fDTDScanner; 156 157 protected ValidationManager fValidationManager; 158 159 161 162 protected boolean fScanningDTD; 163 164 166 167 protected String fDoctypeName; 168 169 170 protected String fDoctypePublicId; 171 172 173 protected String fDoctypeSystemId; 174 175 176 protected NamespaceContext fNamespaceContext = new NamespaceSupport(); 177 178 180 181 protected boolean fLoadExternalDTD = true; 182 183 184 protected boolean fDisallowDoctype = false; 185 186 188 189 protected boolean fSeenDoctypeDecl; 190 191 193 194 protected Dispatcher fXMLDeclDispatcher = new XMLDeclDispatcher(); 195 196 197 protected Dispatcher fPrologDispatcher = new PrologDispatcher(); 198 199 200 protected Dispatcher fDTDDispatcher = new DTDDispatcher(); 201 202 203 protected Dispatcher fTrailingMiscDispatcher = new TrailingMiscDispatcher(); 204 205 207 208 private final String [] fStrings = new String [3]; 209 210 211 private final XMLString fString = new XMLString(); 212 213 214 private final XMLStringBuffer fStringBuffer = new XMLStringBuffer(); 215 216 217 private XMLInputSource fExternalSubsetSource = null; 218 219 220 private final XMLDTDDescription fDTDDescription = new XMLDTDDescription(null, null, null, null, null); 221 222 226 227 public XMLDocumentScannerImpl() {} 229 233 240 public void setInputSource(XMLInputSource inputSource) throws IOException { 241 fEntityManager.setEntityHandler(this); 242 fEntityManager.startDocumentEntity(inputSource); 243 } 246 250 264 public void reset(XMLComponentManager componentManager) 265 throws XMLConfigurationException { 266 267 super.reset(componentManager); 268 269 fDoctypeName = null; 271 fDoctypePublicId = null; 272 fDoctypeSystemId = null; 273 fSeenDoctypeDecl = false; 274 fScanningDTD = false; 275 fExternalSubsetSource = null; 276 277 if (!fParserSettings) { 278 fNamespaceContext.reset(); 280 setScannerState(SCANNER_STATE_XML_DECL); 282 setDispatcher(fXMLDeclDispatcher); 283 return; 284 } 285 286 try { 288 fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD); 289 } 290 catch (XMLConfigurationException e) { 291 fLoadExternalDTD = true; 292 } 293 try { 294 fDisallowDoctype = componentManager.getFeature(DISALLOW_DOCTYPE_DECL_FEATURE); 295 } 296 catch (XMLConfigurationException e) { 297 fDisallowDoctype = false; 298 } 299 300 fDTDScanner = (XMLDTDScanner)componentManager.getProperty(DTD_SCANNER); 302 try { 303 fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER); 304 } 305 catch (XMLConfigurationException e) { 306 fValidationManager = null; 307 } 308 309 try { 310 fNamespaceContext = (NamespaceContext)componentManager.getProperty(NAMESPACE_CONTEXT); 311 } 312 catch (XMLConfigurationException e) { } 313 if (fNamespaceContext == null) { 314 fNamespaceContext = new NamespaceSupport(); 315 } 316 fNamespaceContext.reset(); 317 318 setScannerState(SCANNER_STATE_XML_DECL); 320 setDispatcher(fXMLDeclDispatcher); 321 322 } 324 329 public String [] getRecognizedFeatures() { 330 String [] featureIds = super.getRecognizedFeatures(); 331 int length = featureIds != null ? featureIds.length : 0; 332 String [] combinedFeatureIds = new String [length + RECOGNIZED_FEATURES.length]; 333 if (featureIds != null) { 334 System.arraycopy(featureIds, 0, combinedFeatureIds, 0, featureIds.length); 335 } 336 System.arraycopy(RECOGNIZED_FEATURES, 0, combinedFeatureIds, length, RECOGNIZED_FEATURES.length); 337 return combinedFeatureIds; 338 } 340 355 public void setFeature(String featureId, boolean state) 356 throws XMLConfigurationException { 357 358 super.setFeature(featureId, state); 359 360 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 362 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 363 364 if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && 365 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { 366 fLoadExternalDTD = state; 367 return; 368 } 369 else if (suffixLength == Constants.DISALLOW_DOCTYPE_DECL_FEATURE.length() && 370 featureId.endsWith(Constants.DISALLOW_DOCTYPE_DECL_FEATURE)) { 371 fDisallowDoctype = state; 372 return; 373 } 374 } 375 376 } 378 383 public String [] getRecognizedProperties() { 384 String [] propertyIds = super.getRecognizedProperties(); 385 int length = propertyIds != null ? propertyIds.length : 0; 386 String [] combinedPropertyIds = new String [length + RECOGNIZED_PROPERTIES.length]; 387 if (propertyIds != null) { 388 System.arraycopy(propertyIds, 0, combinedPropertyIds, 0, propertyIds.length); 389 } 390 System.arraycopy(RECOGNIZED_PROPERTIES, 0, combinedPropertyIds, length, RECOGNIZED_PROPERTIES.length); 391 return combinedPropertyIds; 392 } 394 409 public void setProperty(String propertyId, Object value) 410 throws XMLConfigurationException { 411 412 super.setProperty(propertyId, value); 413 414 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 416 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 417 418 if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && 419 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { 420 fDTDScanner = (XMLDTDScanner)value; 421 } 422 if (suffixLength == Constants.NAMESPACE_CONTEXT_PROPERTY.length() && 423 propertyId.endsWith(Constants.NAMESPACE_CONTEXT_PROPERTY)) { 424 if (value != null) { 425 fNamespaceContext = (NamespaceContext)value; 426 } 427 } 428 429 return; 430 } 431 432 } 434 443 public Boolean getFeatureDefault(String featureId) { 444 445 for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { 446 if (RECOGNIZED_FEATURES[i].equals(featureId)) { 447 return FEATURE_DEFAULTS[i]; 448 } 449 } 450 return super.getFeatureDefault(featureId); 451 } 453 462 public Object getPropertyDefault(String propertyId) { 463 for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { 464 if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { 465 return PROPERTY_DEFAULTS[i]; 466 } 467 } 468 return super.getPropertyDefault(propertyId); 469 } 471 475 490 public void startEntity(String name, 491 XMLResourceIdentifier identifier, 492 String encoding, Augmentations augs) throws XNIException { 493 494 super.startEntity(name, identifier, encoding, augs); 495 496 if (!name.equals("[xml]") && fEntityScanner.isExternal()) { 498 setScannerState(SCANNER_STATE_TEXT_DECL); 499 } 500 501 if (fDocumentHandler != null && name.equals("[xml]")) { 503 fDocumentHandler.startDocument(fEntityScanner, encoding, fNamespaceContext, null); 504 } 505 506 } 508 517 public void endEntity(String name, Augmentations augs) throws XNIException { 518 519 super.endEntity(name, augs); 520 521 if (fDocumentHandler != null && name.equals("[xml]")) { 523 fDocumentHandler.endDocument(null); 524 } 525 526 } 528 532 534 535 protected Dispatcher createContentDispatcher() { 536 return new ContentDispatcher(); 537 } 539 541 542 protected boolean scanDoctypeDecl() throws IOException , XNIException { 543 544 if (!fEntityScanner.skipSpaces()) { 546 reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL", 547 null); 548 } 549 550 fDoctypeName = fEntityScanner.scanName(); 552 if (fDoctypeName == null) { 553 reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null); 554 } 555 556 if (fEntityScanner.skipSpaces()) { 558 scanExternalID(fStrings, false); 559 fDoctypeSystemId = fStrings[0]; 560 fDoctypePublicId = fStrings[1]; 561 fEntityScanner.skipSpaces(); 562 } 563 564 fHasExternalDTD = fDoctypeSystemId != null; 565 566 if (!fHasExternalDTD && fExternalSubsetResolver != null) { 568 fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null); 569 fDTDDescription.setRootName(fDoctypeName); 570 fExternalSubsetSource = fExternalSubsetResolver.getExternalSubset(fDTDDescription); 571 fHasExternalDTD = fExternalSubsetSource != null; 572 } 573 574 if (fDocumentHandler != null) { 576 if (fExternalSubsetSource == null) { 582 fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null); 583 } 584 else { 585 fDocumentHandler.doctypeDecl(fDoctypeName, fExternalSubsetSource.getPublicId(), fExternalSubsetSource.getSystemId(), null); 586 } 587 } 588 589 boolean internalSubset = true; 591 if (!fEntityScanner.skipChar('[')) { 592 internalSubset = false; 593 fEntityScanner.skipSpaces(); 594 if (!fEntityScanner.skipChar('>')) { 595 reportFatalError("DoctypedeclUnterminated", new Object []{fDoctypeName}); 596 } 597 fMarkupDepth--; 598 } 599 600 return internalSubset; 601 602 } 604 608 609 protected String getScannerStateName(int state) { 610 611 switch (state) { 612 case SCANNER_STATE_XML_DECL: return "SCANNER_STATE_XML_DECL"; 613 case SCANNER_STATE_PROLOG: return "SCANNER_STATE_PROLOG"; 614 case SCANNER_STATE_TRAILING_MISC: return "SCANNER_STATE_TRAILING_MISC"; 615 case SCANNER_STATE_DTD_INTERNAL_DECLS: return "SCANNER_STATE_DTD_INTERNAL_DECLS"; 616 case SCANNER_STATE_DTD_EXTERNAL: return "SCANNER_STATE_DTD_EXTERNAL"; 617 case SCANNER_STATE_DTD_EXTERNAL_DECLS: return "SCANNER_STATE_DTD_EXTERNAL_DECLS"; 618 } 619 return super.getScannerStateName(state); 620 621 } 623 627 632 protected final class XMLDeclDispatcher 633 implements Dispatcher { 634 635 639 651 public boolean dispatch(boolean complete) 652 throws IOException , XNIException { 653 654 setScannerState(SCANNER_STATE_PROLOG); 657 setDispatcher(fPrologDispatcher); 658 659 try { 661 if (fEntityScanner.skipString("<?xml")) { 662 fMarkupDepth++; 663 if (XMLChar.isName(fEntityScanner.peekChar())) { 666 fStringBuffer.clear(); 667 fStringBuffer.append("xml"); 668 if (fNamespaces) { 669 while (XMLChar.isNCName(fEntityScanner.peekChar())) { 670 fStringBuffer.append((char)fEntityScanner.scanChar()); 671 } 672 } 673 else { 674 while (XMLChar.isName(fEntityScanner.peekChar())) { 675 fStringBuffer.append((char)fEntityScanner.scanChar()); 676 } 677 } 678 String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length); 679 scanPIData(target, fString); 680 } 681 682 else { 684 scanXMLDeclOrTextDecl(false); 685 } 686 } 687 fEntityManager.fCurrentEntity.mayReadChunks = true; 688 689 return true; 691 } 692 catch (MalformedByteSequenceException e) { 694 fErrorReporter.reportError(e.getDomain(), e.getKey(), 695 e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR); 696 return false; 697 } 698 catch (CharConversionException e) { 699 reportFatalError("CharConversionFailure", null); 700 return false; 701 } 702 catch (EOFException e) { 704 reportFatalError("PrematureEOF", null); 705 return false; 706 } 708 709 710 } 712 } 714 719 protected final class PrologDispatcher 720 implements Dispatcher { 721 722 726 738 public boolean dispatch(boolean complete) 739 throws IOException , XNIException { 740 741 try { 742 boolean again; 743 do { 744 again = false; 745 switch (fScannerState) { 746 case SCANNER_STATE_PROLOG: { 747 fEntityScanner.skipSpaces(); 748 if (fEntityScanner.skipChar('<')) { 749 setScannerState(SCANNER_STATE_START_OF_MARKUP); 750 again = true; 751 } 752 else if (fEntityScanner.skipChar('&')) { 753 setScannerState(SCANNER_STATE_REFERENCE); 754 again = true; 755 } 756 else { 757 setScannerState(SCANNER_STATE_CONTENT); 758 again = true; 759 } 760 break; 761 } 762 case SCANNER_STATE_START_OF_MARKUP: { 763 fMarkupDepth++; 764 if (fEntityScanner.skipChar('!')) { 765 if (fEntityScanner.skipChar('-')) { 766 if (!fEntityScanner.skipChar('-')) { 767 reportFatalError("InvalidCommentStart", 768 null); 769 } 770 setScannerState(SCANNER_STATE_COMMENT); 771 again = true; 772 } 773 else if (fEntityScanner.skipString("DOCTYPE")) { 774 setScannerState(SCANNER_STATE_DOCTYPE); 775 again = true; 776 } 777 else { 778 reportFatalError("MarkupNotRecognizedInProlog", 779 null); 780 } 781 } 782 else if (isValidNameStartChar(fEntityScanner.peekChar())) { 783 setScannerState(SCANNER_STATE_ROOT_ELEMENT); 784 setDispatcher(fContentDispatcher); 785 return true; 786 } 787 else if (fEntityScanner.skipChar('?')) { 788 setScannerState(SCANNER_STATE_PI); 789 again = true; 790 } 791 else if (isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { 792 setScannerState(SCANNER_STATE_ROOT_ELEMENT); 793 setDispatcher(fContentDispatcher); 794 return true; 795 } 796 else { 797 reportFatalError("MarkupNotRecognizedInProlog", 798 null); 799 } 800 break; 801 } 802 case SCANNER_STATE_COMMENT: { 803 scanComment(); 804 setScannerState(SCANNER_STATE_PROLOG); 805 break; 806 } 807 case SCANNER_STATE_PI: { 808 scanPI(); 809 setScannerState(SCANNER_STATE_PROLOG); 810 break; 811 } 812 case SCANNER_STATE_DOCTYPE: { 813 if (fDisallowDoctype) { 814 reportFatalError("DoctypeNotAllowed", null); 815 } 816 if (fSeenDoctypeDecl) { 817 reportFatalError("AlreadySeenDoctype", null); 818 } 819 fSeenDoctypeDecl = true; 820 821 if (scanDoctypeDecl()) { 824 setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS); 825 setDispatcher(fDTDDispatcher); 826 return true; 827 } 828 829 if (fDoctypeSystemId != null) { 831 if (((fValidation || fLoadExternalDTD) 832 && (fValidationManager == null || !fValidationManager.isCachedDTD()))) { 833 setScannerState(SCANNER_STATE_DTD_EXTERNAL); 834 setDispatcher(fDTDDispatcher); 835 return true; 836 } 837 } 838 else if (fExternalSubsetSource != null) { 839 if (((fValidation || fLoadExternalDTD) 840 && (fValidationManager == null || !fValidationManager.isCachedDTD()))) { 841 fDTDScanner.setInputSource(fExternalSubsetSource); 843 fExternalSubsetSource = null; 844 setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS); 845 setDispatcher(fDTDDispatcher); 846 return true; 847 } 848 } 849 850 855 fDTDScanner.setInputSource(null); 858 setScannerState(SCANNER_STATE_PROLOG); 859 break; 860 } 861 case SCANNER_STATE_CONTENT: { 862 reportFatalError("ContentIllegalInProlog", null); 863 fEntityScanner.scanChar(); 864 } 865 case SCANNER_STATE_REFERENCE: { 866 reportFatalError("ReferenceIllegalInProlog", null); 867 } 868 } 869 } while (complete || again); 870 871 if (complete) { 872 if (fEntityScanner.scanChar() != '<') { 873 reportFatalError("RootElementRequired", null); 874 } 875 setScannerState(SCANNER_STATE_ROOT_ELEMENT); 876 setDispatcher(fContentDispatcher); 877 } 878 } 879 catch (MalformedByteSequenceException e) { 881 fErrorReporter.reportError(e.getDomain(), e.getKey(), 882 e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR); 883 return false; 884 } 885 catch (CharConversionException e) { 886 reportFatalError("CharConversionFailure", null); 887 return false; 888 } 889 catch (EOFException e) { 891 reportFatalError("PrematureEOF", null); 892 return false; 893 } 895 896 return true; 897 898 } 900 } 902 907 protected final class DTDDispatcher 908 implements Dispatcher { 909 910 914 926 public boolean dispatch(boolean complete) 927 throws IOException , XNIException { 928 fEntityManager.setEntityHandler(null); 929 try { 930 boolean again; 931 do { 932 again = false; 933 switch (fScannerState) { 934 case SCANNER_STATE_DTD_INTERNAL_DECLS: { 935 boolean completeDTD = true; 938 939 boolean moreToScan = fDTDScanner.scanDTDInternalSubset(completeDTD, fStandalone, fHasExternalDTD && fLoadExternalDTD); 940 if (!moreToScan) { 941 if (!fEntityScanner.skipChar(']')) { 943 reportFatalError("EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET", 944 null); 945 } 946 fEntityScanner.skipSpaces(); 947 if (!fEntityScanner.skipChar('>')) { 948 reportFatalError("DoctypedeclUnterminated", new Object []{fDoctypeName}); 949 } 950 fMarkupDepth--; 951 952 if (fDoctypeSystemId != null) { 954 if ((fValidation || fLoadExternalDTD) 955 && (fValidationManager == null || !fValidationManager.isCachedDTD())) { 956 setScannerState(SCANNER_STATE_DTD_EXTERNAL); 957 break; 958 } 959 } 960 else if (fExternalSubsetSource != null) { 961 if ((fValidation || fLoadExternalDTD) 962 && (fValidationManager == null || !fValidationManager.isCachedDTD())) { 963 fDTDScanner.setInputSource(fExternalSubsetSource); 965 fExternalSubsetSource = null; 966 setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS); 967 break; 968 } 969 } 970 971 setScannerState(SCANNER_STATE_PROLOG); 973 setDispatcher(fPrologDispatcher); 974 fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this); 975 return true; 976 } 977 break; 978 } 979 case SCANNER_STATE_DTD_EXTERNAL: { 980 fDTDDescription.setValues(fDoctypePublicId, fDoctypeSystemId, null, null); 981 fDTDDescription.setRootName(fDoctypeName); 982 XMLInputSource xmlInputSource = 983 fEntityManager.resolveEntity(fDTDDescription); 984 fDTDScanner.setInputSource(xmlInputSource); 985 setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS); 986 again = true; 987 break; 988 } 989 case SCANNER_STATE_DTD_EXTERNAL_DECLS: { 990 boolean completeDTD = true; 993 boolean moreToScan = fDTDScanner.scanDTDExternalSubset(completeDTD); 994 if (!moreToScan) { 995 setScannerState(SCANNER_STATE_PROLOG); 996 setDispatcher(fPrologDispatcher); 997 fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this); 998 return true; 999 } 1000 break; 1001 } 1002 default: { 1003 throw new XNIException("DTDDispatcher#dispatch: scanner state="+fScannerState+" ("+getScannerStateName(fScannerState)+')'); 1004 } 1005 } 1006 } while (complete || again); 1007 } 1008 catch (MalformedByteSequenceException e) { 1010 fErrorReporter.reportError(e.getDomain(), e.getKey(), 1011 e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR); 1012 return false; 1013 } 1014 catch (CharConversionException e) { 1015 reportFatalError("CharConversionFailure", null); 1016 return false; 1017 } 1018 catch (EOFException e) { 1020 reportFatalError("PrematureEOF", null); 1021 return false; 1022 } 1024 1025 finally { 1027 fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this); 1028 } 1029 1030 return true; 1031 1032 } 1034 } 1036 1042 protected class ContentDispatcher 1043 extends FragmentContentDispatcher { 1044 1045 1049 1051 1054 1062 protected boolean scanForDoctypeHook() 1063 throws IOException , XNIException { 1064 1065 if (fEntityScanner.skipString("DOCTYPE")) { 1066 setScannerState(SCANNER_STATE_DOCTYPE); 1067 return true; 1068 } 1069 return false; 1070 1071 } 1073 1086 protected boolean elementDepthIsZeroHook() 1087 throws IOException , XNIException { 1088 1089 setScannerState(SCANNER_STATE_TRAILING_MISC); 1090 setDispatcher(fTrailingMiscDispatcher); 1091 return true; 1092 1093 } 1095 1107 protected boolean scanRootElementHook() 1108 throws IOException , XNIException { 1109 1110 if (fExternalSubsetResolver != null && !fSeenDoctypeDecl 1111 && !fDisallowDoctype && (fValidation || fLoadExternalDTD)) { 1112 scanStartElementName(); 1113 resolveExternalSubsetAndRead(); 1114 if (scanStartElementAfterName()) { 1115 setScannerState(SCANNER_STATE_TRAILING_MISC); 1116 setDispatcher(fTrailingMiscDispatcher); 1117 return true; 1118 } 1119 } 1120 else if (scanStartElement()) { 1121 setScannerState(SCANNER_STATE_TRAILING_MISC); 1122 setDispatcher(fTrailingMiscDispatcher); 1123 return true; 1124 } 1125 return false; 1126 1127 } 1129 1136 protected void endOfFileHook(EOFException e) 1137 throws IOException , XNIException { 1138 1139 reportFatalError("PrematureEOF", null); 1140 1143 } 1145 1149 protected void resolveExternalSubsetAndRead() 1150 throws IOException , XNIException { 1151 1152 fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null); 1153 fDTDDescription.setRootName(fElementQName.rawname); 1154 XMLInputSource src = fExternalSubsetResolver.getExternalSubset(fDTDDescription); 1155 1156 if (src != null) { 1157 fDoctypeName = fElementQName.rawname; 1158 fDoctypePublicId = src.getPublicId(); 1159 fDoctypeSystemId = src.getSystemId(); 1160 if (fDocumentHandler != null) { 1162 fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null); 1165 } 1166 try { 1167 if (fValidationManager == null || !fValidationManager.isCachedDTD()) { 1168 fDTDScanner.setInputSource(src); 1169 while (fDTDScanner.scanDTDExternalSubset(true)); 1170 } 1171 else { 1172 fDTDScanner.setInputSource(null); 1174 } 1175 } 1176 finally { 1177 fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this); 1178 } 1179 } 1180 } 1182 } 1184 1190 protected final class TrailingMiscDispatcher 1191 implements Dispatcher { 1192 1193 1197 1209 public boolean dispatch(boolean complete) 1210 throws IOException , XNIException { 1211 1212 try { 1213 boolean again; 1214 do { 1215 again = false; 1216 switch (fScannerState) { 1217 case SCANNER_STATE_TRAILING_MISC: { 1218 fEntityScanner.skipSpaces(); 1219 if (fEntityScanner.skipChar('<')) { 1220 setScannerState(SCANNER_STATE_START_OF_MARKUP); 1221 again = true; 1222 } 1223 else { 1224 setScannerState(SCANNER_STATE_CONTENT); 1225 again = true; 1226 } 1227 break; 1228 } 1229 case SCANNER_STATE_START_OF_MARKUP: { 1230 fMarkupDepth++; 1231 if (fEntityScanner.skipChar('?')) { 1232 setScannerState(SCANNER_STATE_PI); 1233 again = true; 1234 } 1235 else if (fEntityScanner.skipChar('!')) { 1236 setScannerState(SCANNER_STATE_COMMENT); 1237 again = true; 1238 } 1239 else if (fEntityScanner.skipChar('/')) { 1240 reportFatalError("MarkupNotRecognizedInMisc", 1241 null); 1242 again = true; 1243 } 1244 else if (isValidNameStartChar(fEntityScanner.peekChar())) { 1245 reportFatalError("MarkupNotRecognizedInMisc", 1246 null); 1247 scanStartElement(); 1248 setScannerState(SCANNER_STATE_CONTENT); 1249 } 1250 else if (isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { 1251 reportFatalError("MarkupNotRecognizedInMisc", 1252 null); 1253 scanStartElement(); 1254 setScannerState(SCANNER_STATE_CONTENT); 1255 } 1256 else { 1257 reportFatalError("MarkupNotRecognizedInMisc", 1258 null); 1259 } 1260 break; 1261 } 1262 case SCANNER_STATE_PI: { 1263 scanPI(); 1264 setScannerState(SCANNER_STATE_TRAILING_MISC); 1265 break; 1266 } 1267 case SCANNER_STATE_COMMENT: { 1268 if (!fEntityScanner.skipString("--")) { 1269 reportFatalError("InvalidCommentStart", null); 1270 } 1271 scanComment(); 1272 setScannerState(SCANNER_STATE_TRAILING_MISC); 1273 break; 1274 } 1275 case SCANNER_STATE_CONTENT: { 1276 int ch = fEntityScanner.peekChar(); 1277 if (ch == -1) { 1278 setScannerState(SCANNER_STATE_TERMINATED); 1279 return false; 1280 } 1281 reportFatalError("ContentIllegalInTrailingMisc", 1282 null); 1283 fEntityScanner.scanChar(); 1284 setScannerState(SCANNER_STATE_TRAILING_MISC); 1285 break; 1286 } 1287 case SCANNER_STATE_REFERENCE: { 1288 reportFatalError("ReferenceIllegalInTrailingMisc", 1289 null); 1290 setScannerState(SCANNER_STATE_TRAILING_MISC); 1291 break; 1292 } 1293 case SCANNER_STATE_TERMINATED: { 1294 return false; 1295 } 1296 } 1297 } while (complete || again); 1298 } 1299 catch (MalformedByteSequenceException e) { 1301 fErrorReporter.reportError(e.getDomain(), e.getKey(), 1302 e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR); 1303 return false; 1304 } 1305 catch (CharConversionException e) { 1306 reportFatalError("CharConversionFailure", null); 1307 return false; 1308 } 1309 catch (EOFException e) { 1310 if (fMarkupDepth != 0) { 1314 reportFatalError("PrematureEOF", null); 1315 return false; 1316 } 1318 1319 setScannerState(SCANNER_STATE_TERMINATED); 1320 return false; 1321 } 1322 1323 return true; 1324 1325 } 1327 } 1329} | Popular Tags |