1 16 17 package org.apache.xerces.impl; 18 19 import java.io.IOException ; 20 21 import org.apache.xerces.impl.msg.XMLMessageFormatter; 22 import org.apache.xerces.util.SymbolTable; 23 import org.apache.xerces.util.XMLChar; 24 import org.apache.xerces.util.XMLResourceIdentifierImpl; 25 import org.apache.xerces.util.XMLStringBuffer; 26 import org.apache.xerces.xni.Augmentations; 27 import org.apache.xerces.xni.XMLResourceIdentifier; 28 import org.apache.xerces.xni.XMLString; 29 import org.apache.xerces.xni.XNIException; 30 import org.apache.xerces.xni.parser.XMLComponent; 31 import org.apache.xerces.xni.parser.XMLComponentManager; 32 import org.apache.xerces.xni.parser.XMLConfigurationException; 33 34 60 public abstract class XMLScanner 61 implements XMLComponent { 62 63 67 69 70 protected static final String VALIDATION = 71 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE; 72 73 74 protected static final String NAMESPACES = 75 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; 76 77 78 protected static final String NOTIFY_CHAR_REFS = 79 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE; 80 81 protected static final String PARSER_SETTINGS = 82 Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; 83 84 86 87 protected static final String SYMBOL_TABLE = 88 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 89 90 91 protected static final String ERROR_REPORTER = 92 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 93 94 95 protected static final String ENTITY_MANAGER = 96 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; 97 98 100 101 protected static final boolean DEBUG_ATTR_NORMALIZATION = false; 102 103 107 108 110 114 protected boolean fValidation = false; 115 116 117 protected boolean fNamespaces; 118 119 120 protected boolean fNotifyCharRefs = false; 121 122 123 protected boolean fParserSettings = true; 124 125 127 128 protected SymbolTable fSymbolTable; 129 130 131 protected XMLErrorReporter fErrorReporter; 132 133 134 protected XMLEntityManager fEntityManager; 135 136 138 139 protected XMLEntityScanner fEntityScanner; 140 141 142 protected int fEntityDepth; 143 144 145 protected String fCharRefLiteral = null; 146 147 148 protected boolean fScanningAttribute; 149 150 151 protected boolean fReportEntity; 152 153 155 156 protected final static String fVersionSymbol = "version".intern(); 157 158 159 protected final static String fEncodingSymbol = "encoding".intern(); 160 161 162 protected final static String fStandaloneSymbol = "standalone".intern(); 163 164 165 protected final static String fAmpSymbol = "amp".intern(); 166 167 168 protected final static String fLtSymbol = "lt".intern(); 169 170 171 protected final static String fGtSymbol = "gt".intern(); 172 173 174 protected final static String fQuotSymbol = "quot".intern(); 175 176 177 protected final static String fAposSymbol = "apos".intern(); 178 179 181 187 188 private XMLString fString = new XMLString(); 189 190 191 private XMLStringBuffer fStringBuffer = new XMLStringBuffer(); 192 193 194 private XMLStringBuffer fStringBuffer2 = new XMLStringBuffer(); 195 196 197 private XMLStringBuffer fStringBuffer3 = new XMLStringBuffer(); 198 199 protected XMLResourceIdentifierImpl fResourceIdentifier = new XMLResourceIdentifierImpl(); 201 202 206 214 public void reset(XMLComponentManager componentManager) 215 throws XMLConfigurationException { 216 217 try { 218 fParserSettings = componentManager.getFeature(PARSER_SETTINGS); 219 } catch (XMLConfigurationException e) { 220 fParserSettings = true; 221 } 222 223 if (!fParserSettings) { 224 init(); 226 return; 227 } 228 229 fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE); 231 fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); 232 fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER); 233 234 try { 236 fValidation = componentManager.getFeature(VALIDATION); 237 } 238 catch (XMLConfigurationException e) { 239 fValidation = false; 240 } 241 try { 242 fNamespaces = componentManager.getFeature(NAMESPACES); 243 } 244 catch (XMLConfigurationException e) { 245 fNamespaces = true; 246 } 247 try { 248 fNotifyCharRefs = componentManager.getFeature(NOTIFY_CHAR_REFS); 249 } 250 catch (XMLConfigurationException e) { 251 fNotifyCharRefs = false; 252 } 253 254 init(); 255 256 } 258 264 public void setProperty(String propertyId, Object value) 265 throws XMLConfigurationException { 266 267 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 269 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 270 271 if (suffixLength == Constants.SYMBOL_TABLE_PROPERTY.length() && 272 propertyId.endsWith(Constants.SYMBOL_TABLE_PROPERTY)) { 273 fSymbolTable = (SymbolTable)value; 274 } 275 else if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() && 276 propertyId.endsWith(Constants.ERROR_REPORTER_PROPERTY)) { 277 fErrorReporter = (XMLErrorReporter)value; 278 } 279 else if (suffixLength == Constants.ENTITY_MANAGER_PROPERTY.length() && 280 propertyId.endsWith(Constants.ENTITY_MANAGER_PROPERTY)) { 281 fEntityManager = (XMLEntityManager)value; 282 } 283 } 284 285 } 287 290 public void setFeature(String featureId, boolean value) 291 throws XMLConfigurationException { 292 293 if (VALIDATION.equals(featureId)) { 294 fValidation = value; 295 } else if (NOTIFY_CHAR_REFS.equals(featureId)) { 296 fNotifyCharRefs = value; 297 } 298 } 299 300 303 public boolean getFeature(String featureId) 304 throws XMLConfigurationException { 305 306 if (VALIDATION.equals(featureId)) { 307 return fValidation; 308 } else if (NOTIFY_CHAR_REFS.equals(featureId)) { 309 return fNotifyCharRefs; 310 } 311 throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, featureId); 312 } 313 314 318 protected void reset() { 320 init(); 321 322 fValidation = true; 324 fNotifyCharRefs = false; 325 326 } 327 328 330 354 protected void scanXMLDeclOrTextDecl(boolean scanningTextDecl, 355 String [] pseudoAttributeValues) 356 throws IOException , XNIException { 357 358 String version = null; 360 String encoding = null; 361 String standalone = null; 362 363 final int STATE_VERSION = 0; 365 final int STATE_ENCODING = 1; 366 final int STATE_STANDALONE = 2; 367 final int STATE_DONE = 3; 368 int state = STATE_VERSION; 369 370 boolean dataFoundForTarget = false; 371 boolean sawSpace = fEntityScanner.skipDeclSpaces(); 372 XMLEntityManager.ScannedEntity currEnt = fEntityManager.getCurrentEntity(); 380 boolean currLiteral = currEnt.literal; 381 currEnt.literal = false; 382 while (fEntityScanner.peekChar() != '?') { 383 dataFoundForTarget = true; 384 String name = scanPseudoAttribute(scanningTextDecl, fString); 385 switch (state) { 386 case STATE_VERSION: { 387 if (name == fVersionSymbol) { 388 if (!sawSpace) { 389 reportFatalError(scanningTextDecl 390 ? "SpaceRequiredBeforeVersionInTextDecl" 391 : "SpaceRequiredBeforeVersionInXMLDecl", 392 null); 393 } 394 version = fString.toString(); 395 state = STATE_ENCODING; 396 if (!versionSupported(version)) { 397 reportFatalError(getVersionNotSupportedKey(), 398 new Object []{version}); 399 } 400 } 401 else if (name == fEncodingSymbol) { 402 if (!scanningTextDecl) { 403 reportFatalError("VersionInfoRequired", null); 404 } 405 if (!sawSpace) { 406 reportFatalError(scanningTextDecl 407 ? "SpaceRequiredBeforeEncodingInTextDecl" 408 : "SpaceRequiredBeforeEncodingInXMLDecl", 409 null); 410 } 411 encoding = fString.toString(); 412 state = scanningTextDecl ? STATE_DONE : STATE_STANDALONE; 413 } 414 else { 415 if (scanningTextDecl) { 416 reportFatalError("EncodingDeclRequired", null); 417 } 418 else { 419 reportFatalError("VersionInfoRequired", null); 420 } 421 } 422 break; 423 } 424 case STATE_ENCODING: { 425 if (name == fEncodingSymbol) { 426 if (!sawSpace) { 427 reportFatalError(scanningTextDecl 428 ? "SpaceRequiredBeforeEncodingInTextDecl" 429 : "SpaceRequiredBeforeEncodingInXMLDecl", 430 null); 431 } 432 encoding = fString.toString(); 433 state = scanningTextDecl ? STATE_DONE : STATE_STANDALONE; 434 } 437 else if (!scanningTextDecl && name == fStandaloneSymbol) { 438 if (!sawSpace) { 439 reportFatalError("SpaceRequiredBeforeStandalone", 440 null); 441 } 442 standalone = fString.toString(); 443 state = STATE_DONE; 444 if (!standalone.equals("yes") && !standalone.equals("no")) { 445 reportFatalError("SDDeclInvalid", new Object [] {standalone}); 446 } 447 } 448 else { 449 reportFatalError("EncodingDeclRequired", null); 450 } 451 break; 452 } 453 case STATE_STANDALONE: { 454 if (name == fStandaloneSymbol) { 455 if (!sawSpace) { 456 reportFatalError("SpaceRequiredBeforeStandalone", 457 null); 458 } 459 standalone = fString.toString(); 460 state = STATE_DONE; 461 if (!standalone.equals("yes") && !standalone.equals("no")) { 462 reportFatalError("SDDeclInvalid", new Object [] {standalone}); 463 } 464 } 465 else { 466 reportFatalError("EncodingDeclRequired", null); 467 } 468 break; 469 } 470 default: { 471 reportFatalError("NoMorePseudoAttributes", null); 472 } 473 } 474 sawSpace = fEntityScanner.skipDeclSpaces(); 475 } 476 if(currLiteral) 478 currEnt.literal = true; 479 if (scanningTextDecl && state != STATE_DONE) { 481 reportFatalError("MorePseudoAttributes", null); 482 } 483 484 if (scanningTextDecl) { 487 if (!dataFoundForTarget && encoding == null) { 488 reportFatalError("EncodingDeclRequired", null); 489 } 490 } 491 else { 492 if (!dataFoundForTarget && version == null) { 493 reportFatalError("VersionInfoRequired", null); 494 } 495 } 496 497 if (!fEntityScanner.skipChar('?')) { 499 reportFatalError("XMLDeclUnterminated", null); 500 } 501 if (!fEntityScanner.skipChar('>')) { 502 reportFatalError("XMLDeclUnterminated", null); 503 504 } 505 506 pseudoAttributeValues[0] = version; 508 pseudoAttributeValues[1] = encoding; 509 pseudoAttributeValues[2] = standalone; 510 511 } 513 528 public String scanPseudoAttribute(boolean scanningTextDecl, 529 XMLString value) 530 throws IOException , XNIException { 531 532 String name = fEntityScanner.scanName(); 545 XMLEntityManager.print(fEntityManager.getCurrentEntity()); 546 if (name == null) { 547 reportFatalError("PseudoAttrNameExpected", null); 548 } 549 fEntityScanner.skipDeclSpaces(); 550 if (!fEntityScanner.skipChar('=')) { 551 reportFatalError(scanningTextDecl ? "EqRequiredInTextDecl" 552 : "EqRequiredInXMLDecl", new Object []{name}); 553 } 554 fEntityScanner.skipDeclSpaces(); 555 int quote = fEntityScanner.peekChar(); 556 if (quote != '\'' && quote != '"') { 557 reportFatalError(scanningTextDecl ? "QuoteRequiredInTextDecl" 558 : "QuoteRequiredInXMLDecl" , new Object []{name}); 559 } 560 fEntityScanner.scanChar(); 561 int c = fEntityScanner.scanLiteral(quote, value); 562 if (c != quote) { 563 fStringBuffer2.clear(); 564 do { 565 fStringBuffer2.append(value); 566 if (c != -1) { 567 if (c == '&' || c == '%' || c == '<' || c == ']') { 568 fStringBuffer2.append((char)fEntityScanner.scanChar()); 569 } 570 else if (XMLChar.isHighSurrogate(c)) { 574 scanSurrogates(fStringBuffer2); 575 } 576 else if (isInvalidLiteral(c)) { 577 String key = scanningTextDecl 578 ? "InvalidCharInTextDecl" : "InvalidCharInXMLDecl"; 579 reportFatalError(key, 580 new Object [] {Integer.toString(c, 16)}); 581 fEntityScanner.scanChar(); 582 } 583 } 584 c = fEntityScanner.scanLiteral(quote, value); 585 } while (c != quote); 586 fStringBuffer2.append(value); 587 value.setValues(fStringBuffer2); 588 } 589 if (!fEntityScanner.skipChar(quote)) { 590 reportFatalError(scanningTextDecl ? "CloseQuoteMissingInTextDecl" 591 : "CloseQuoteMissingInXMLDecl", 592 new Object []{name}); 593 } 594 595 return name; 597 598 } 600 610 protected void scanPI() throws IOException , XNIException { 611 612 fReportEntity = false; 614 String target = null; 615 if(fNamespaces) { 616 target = fEntityScanner.scanNCName(); 617 } else { 618 target = fEntityScanner.scanName(); 619 } 620 if (target == null) { 621 reportFatalError("PITargetRequired", null); 622 } 623 624 scanPIData(target, fString); 626 fReportEntity = true; 627 628 } 630 641 protected void scanPIData(String target, XMLString data) 642 throws IOException , XNIException { 643 644 if (target.length() == 3) { 646 char c0 = Character.toLowerCase(target.charAt(0)); 647 char c1 = Character.toLowerCase(target.charAt(1)); 648 char c2 = Character.toLowerCase(target.charAt(2)); 649 if (c0 == 'x' && c1 == 'm' && c2 == 'l') { 650 reportFatalError("ReservedPITarget", null); 651 } 652 } 653 654 if (!fEntityScanner.skipSpaces()) { 656 if (fEntityScanner.skipString("?>")) { 657 data.clear(); 659 return; 660 } 661 else { 662 if(fNamespaces && fEntityScanner.peekChar() == ':') { 663 fEntityScanner.scanChar(); 664 XMLStringBuffer colonName = new XMLStringBuffer(target); 665 colonName.append(":"); 666 String str = fEntityScanner.scanName(); 667 if (str != null) 668 colonName.append(str); 669 reportFatalError("ColonNotLegalWithNS", new Object [] {colonName.toString()}); 670 fEntityScanner.skipSpaces(); 671 } else { 672 reportFatalError("SpaceRequiredInPI", null); 674 } 675 } 676 } 677 678 fStringBuffer.clear(); 679 if (fEntityScanner.scanData("?>", fStringBuffer)) { 681 do { 682 int c = fEntityScanner.peekChar(); 683 if (c != -1) { 684 if (XMLChar.isHighSurrogate(c)) { 685 scanSurrogates(fStringBuffer); 686 } 687 else if (isInvalidLiteral(c)) { 688 reportFatalError("InvalidCharInPI", 689 new Object []{Integer.toHexString(c)}); 690 fEntityScanner.scanChar(); 691 } 692 } 693 } while (fEntityScanner.scanData("?>", fStringBuffer)); 694 } 695 data.setValues(fStringBuffer); 696 697 } 699 712 protected void scanComment(XMLStringBuffer text) 713 throws IOException , XNIException { 714 715 text.clear(); 718 while (fEntityScanner.scanData("--", text)) { 719 int c = fEntityScanner.peekChar(); 720 if (c != -1) { 721 if (XMLChar.isHighSurrogate(c)) { 722 scanSurrogates(text); 723 } 724 else if (isInvalidLiteral(c)) { 725 reportFatalError("InvalidCharInComment", 726 new Object [] { Integer.toHexString(c) }); 727 fEntityScanner.scanChar(); 728 } 729 } 730 } 731 if (!fEntityScanner.skipChar('>')) { 732 reportFatalError("DashDashInComment", null); 733 } 734 735 } 737 756 protected boolean scanAttributeValue(XMLString value, 757 XMLString nonNormalizedValue, 758 String atName, 759 boolean checkEntities,String eleName) 760 throws IOException , XNIException 761 { 762 int quote = fEntityScanner.peekChar(); 764 if (quote != '\'' && quote != '"') { 765 reportFatalError("OpenQuoteExpected", new Object []{eleName,atName}); 766 } 767 768 fEntityScanner.scanChar(); 769 int entityDepth = fEntityDepth; 770 771 int c = fEntityScanner.scanLiteral(quote, value); 772 if (DEBUG_ATTR_NORMALIZATION) { 773 System.out.println("** scanLiteral -> \"" 774 + value.toString() + "\""); 775 } 776 777 int fromIndex = 0; 778 if (c == quote && (fromIndex = isUnchangedByNormalization(value)) == -1) { 779 780 nonNormalizedValue.setValues(value); 781 int cquote = fEntityScanner.scanChar(); 782 if (cquote != quote) { 783 reportFatalError("CloseQuoteExpected", new Object []{eleName,atName}); 784 } 785 return true; 786 } 787 fStringBuffer2.clear(); 788 fStringBuffer2.append(value); 789 normalizeWhitespace(value, fromIndex); 790 if (DEBUG_ATTR_NORMALIZATION) { 791 System.out.println("** normalizeWhitespace -> \"" 792 + value.toString() + "\""); 793 } 794 if (c != quote) { 795 fScanningAttribute = true; 796 fStringBuffer.clear(); 797 do { 798 fStringBuffer.append(value); 799 if (DEBUG_ATTR_NORMALIZATION) { 800 System.out.println("** value2: \"" 801 + fStringBuffer.toString() + "\""); 802 } 803 if (c == '&') { 804 fEntityScanner.skipChar('&'); 805 if (entityDepth == fEntityDepth) { 806 fStringBuffer2.append('&'); 807 } 808 if (fEntityScanner.skipChar('#')) { 809 if (entityDepth == fEntityDepth) { 810 fStringBuffer2.append('#'); 811 } 812 int ch = scanCharReferenceValue(fStringBuffer, fStringBuffer2); 813 if (ch != -1) { 814 if (DEBUG_ATTR_NORMALIZATION) { 815 System.out.println("** value3: \"" 816 + fStringBuffer.toString() 817 + "\""); 818 } 819 } 820 } 821 else { 822 String entityName = fEntityScanner.scanName(); 823 if (entityName == null) { 824 reportFatalError("NameRequiredInReference", null); 825 } 826 else if (entityDepth == fEntityDepth) { 827 fStringBuffer2.append(entityName); 828 } 829 if (!fEntityScanner.skipChar(';')) { 830 reportFatalError("SemicolonRequiredInReference", 831 new Object []{entityName}); 832 } 833 else if (entityDepth == fEntityDepth) { 834 fStringBuffer2.append(';'); 835 } 836 if (entityName == fAmpSymbol) { 837 fStringBuffer.append('&'); 838 if (DEBUG_ATTR_NORMALIZATION) { 839 System.out.println("** value5: \"" 840 + fStringBuffer.toString() 841 + "\""); 842 } 843 } 844 else if (entityName == fAposSymbol) { 845 fStringBuffer.append('\''); 846 if (DEBUG_ATTR_NORMALIZATION) { 847 System.out.println("** value7: \"" 848 + fStringBuffer.toString() 849 + "\""); 850 } 851 } 852 else if (entityName == fLtSymbol) { 853 fStringBuffer.append('<'); 854 if (DEBUG_ATTR_NORMALIZATION) { 855 System.out.println("** value9: \"" 856 + fStringBuffer.toString() 857 + "\""); 858 } 859 } 860 else if (entityName == fGtSymbol) { 861 fStringBuffer.append('>'); 862 if (DEBUG_ATTR_NORMALIZATION) { 863 System.out.println("** valueB: \"" 864 + fStringBuffer.toString() 865 + "\""); 866 } 867 } 868 else if (entityName == fQuotSymbol) { 869 fStringBuffer.append('"'); 870 if (DEBUG_ATTR_NORMALIZATION) { 871 System.out.println("** valueD: \"" 872 + fStringBuffer.toString() 873 + "\""); 874 } 875 } 876 else { 877 if (fEntityManager.isExternalEntity(entityName)) { 878 reportFatalError("ReferenceToExternalEntity", 879 new Object [] { entityName }); 880 } 881 else { 882 if (!fEntityManager.isDeclaredEntity(entityName)) { 883 if (checkEntities) { 885 if (fValidation) { 886 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 887 "EntityNotDeclared", 888 new Object []{entityName}, 889 XMLErrorReporter.SEVERITY_ERROR); 890 } 891 } 892 else { 893 reportFatalError("EntityNotDeclared", 894 new Object []{entityName}); 895 } 896 } 897 fEntityManager.startEntity(entityName, true); 898 } 899 } 900 } 901 } 902 else if (c == '<') { 903 reportFatalError("LessthanInAttValue", 904 new Object [] { eleName, atName }); 905 fEntityScanner.scanChar(); 906 if (entityDepth == fEntityDepth) { 907 fStringBuffer2.append((char)c); 908 } 909 } 910 else if (c == '%' || c == ']') { 911 fEntityScanner.scanChar(); 912 fStringBuffer.append((char)c); 913 if (entityDepth == fEntityDepth) { 914 fStringBuffer2.append((char)c); 915 } 916 if (DEBUG_ATTR_NORMALIZATION) { 917 System.out.println("** valueF: \"" 918 + fStringBuffer.toString() + "\""); 919 } 920 } 921 else if (c == '\n' || c == '\r') { 922 fEntityScanner.scanChar(); 923 fStringBuffer.append(' '); 924 if (entityDepth == fEntityDepth) { 925 fStringBuffer2.append('\n'); 926 } 927 } 928 else if (c != -1 && XMLChar.isHighSurrogate(c)) { 929 fStringBuffer3.clear(); 930 if (scanSurrogates(fStringBuffer3)) { 931 fStringBuffer.append(fStringBuffer3); 932 if (entityDepth == fEntityDepth) { 933 fStringBuffer2.append(fStringBuffer3); 934 } 935 if (DEBUG_ATTR_NORMALIZATION) { 936 System.out.println("** valueI: \"" 937 + fStringBuffer.toString() 938 + "\""); 939 } 940 } 941 } 942 else if (c != -1 && isInvalidLiteral(c)) { 943 reportFatalError("InvalidCharInAttValue", 944 new Object [] {eleName, atName, Integer.toString(c, 16)}); 945 fEntityScanner.scanChar(); 946 if (entityDepth == fEntityDepth) { 947 fStringBuffer2.append((char)c); 948 } 949 } 950 c = fEntityScanner.scanLiteral(quote, value); 951 if (entityDepth == fEntityDepth) { 952 fStringBuffer2.append(value); 953 } 954 normalizeWhitespace(value); 955 } while (c != quote || entityDepth != fEntityDepth); 956 fStringBuffer.append(value); 957 if (DEBUG_ATTR_NORMALIZATION) { 958 System.out.println("** valueN: \"" 959 + fStringBuffer.toString() + "\""); 960 } 961 value.setValues(fStringBuffer); 962 fScanningAttribute = false; 963 } 964 nonNormalizedValue.setValues(fStringBuffer2); 965 966 int cquote = fEntityScanner.scanChar(); 968 if (cquote != quote) { 969 reportFatalError("CloseQuoteExpected", new Object []{eleName,atName}); 970 } 971 return nonNormalizedValue.equals(value.ch, value.offset, value.length); 972 973 } 975 976 986 protected void scanExternalID(String [] identifiers, 987 boolean optionalSystemId) 988 throws IOException , XNIException { 989 990 String systemId = null; 991 String publicId = null; 992 if (fEntityScanner.skipString("PUBLIC")) { 993 if (!fEntityScanner.skipSpaces()) { 994 reportFatalError("SpaceRequiredAfterPUBLIC", null); 995 } 996 scanPubidLiteral(fString); 997 publicId = fString.toString(); 998 999 if (!fEntityScanner.skipSpaces() && !optionalSystemId) { 1000 reportFatalError("SpaceRequiredBetweenPublicAndSystem", null); 1001 } 1002 } 1003 1004 if (publicId != null || fEntityScanner.skipString("SYSTEM")) { 1005 if (publicId == null && !fEntityScanner.skipSpaces()) { 1006 reportFatalError("SpaceRequiredAfterSYSTEM", null); 1007 } 1008 int quote = fEntityScanner.peekChar(); 1009 if (quote != '\'' && quote != '"') { 1010 if (publicId != null && optionalSystemId) { 1011 identifiers[0] = null; 1014 identifiers[1] = publicId; 1015 return; 1016 } 1017 reportFatalError("QuoteRequiredInSystemID", null); 1018 } 1019 fEntityScanner.scanChar(); 1020 XMLString ident = fString; 1021 if (fEntityScanner.scanLiteral(quote, ident) != quote) { 1022 fStringBuffer.clear(); 1023 do { 1024 fStringBuffer.append(ident); 1025 int c = fEntityScanner.peekChar(); 1026 if (XMLChar.isMarkup(c) || c == ']') { 1027 fStringBuffer.append((char)fEntityScanner.scanChar()); 1028 } 1029 } while (fEntityScanner.scanLiteral(quote, ident) != quote); 1030 fStringBuffer.append(ident); 1031 ident = fStringBuffer; 1032 } 1033 systemId = ident.toString(); 1034 if (!fEntityScanner.skipChar(quote)) { 1035 reportFatalError("SystemIDUnterminated", null); 1036 } 1037 } 1038 1039 identifiers[0] = systemId; 1041 identifiers[1] = publicId; 1042 } 1043 1044 1045 1064 protected boolean scanPubidLiteral(XMLString literal) 1065 throws IOException , XNIException 1066 { 1067 int quote = fEntityScanner.scanChar(); 1068 if (quote != '\'' && quote != '"') { 1069 reportFatalError("QuoteRequiredInPublicID", null); 1070 return false; 1071 } 1072 1073 fStringBuffer.clear(); 1074 boolean skipSpace = true; 1076 boolean dataok = true; 1077 while (true) { 1078 int c = fEntityScanner.scanChar(); 1079 if (c == ' ' || c == '\n' || c == '\r') { 1080 if (!skipSpace) { 1081 fStringBuffer.append(' '); 1083 skipSpace = true; 1084 } 1085 } 1086 else if (c == quote) { 1087 if (skipSpace) { 1088 fStringBuffer.length--; 1090 } 1091 literal.setValues(fStringBuffer); 1092 break; 1093 } 1094 else if (XMLChar.isPubid(c)) { 1095 fStringBuffer.append((char)c); 1096 skipSpace = false; 1097 } 1098 else if (c == -1) { 1099 reportFatalError("PublicIDUnterminated", null); 1100 return false; 1101 } 1102 else { 1103 dataok = false; 1104 reportFatalError("InvalidCharInPublicID", 1105 new Object []{Integer.toHexString(c)}); 1106 } 1107 } 1108 return dataok; 1109 } 1110 1111 1112 1116 protected void normalizeWhitespace(XMLString value) { 1117 int end = value.offset + value.length; 1118 for (int i = value.offset; i < end; ++i) { 1119 int c = value.ch[i]; 1120 if (c < 0x20) { 1127 value.ch[i] = ' '; 1128 } 1129 } 1130 } 1131 1132 1136 protected void normalizeWhitespace(XMLString value, int fromIndex) { 1137 int end = value.offset + value.length; 1138 for (int i = value.offset + fromIndex; i < end; ++i) { 1139 int c = value.ch[i]; 1140 if (c < 0x20) { 1147 value.ch[i] = ' '; 1148 } 1149 } 1150 } 1151 1152 1159 protected int isUnchangedByNormalization(XMLString value) { 1160 int end = value.offset + value.length; 1161 for (int i = value.offset; i < end; ++i) { 1162 int c = value.ch[i]; 1163 if (c < 0x20) { 1170 return i - value.offset; 1171 } 1172 } 1173 return -1; 1174 } 1175 1176 1180 1197 public void startEntity(String name, 1198 XMLResourceIdentifier identifier, 1199 String encoding, Augmentations augs) throws XNIException { 1200 1201 fEntityDepth++; 1203 fEntityScanner = fEntityManager.getEntityScanner(); 1205 1206 } 1208 1219 public void endEntity(String name, Augmentations augs) throws XNIException { 1220 1221 fEntityDepth--; 1223 1224 } 1226 1243 protected int scanCharReferenceValue(XMLStringBuffer buf, XMLStringBuffer buf2) 1244 throws IOException , XNIException { 1245 1246 boolean hex = false; 1248 if (fEntityScanner.skipChar('x')) { 1249 if (buf2 != null) { buf2.append('x'); } 1250 hex = true; 1251 fStringBuffer3.clear(); 1252 boolean digit = true; 1253 1254 int c = fEntityScanner.peekChar(); 1255 digit = (c >= '0' && c <= '9') || 1256 (c >= 'a' && c <= 'f') || 1257 (c >= 'A' && c <= 'F'); 1258 if (digit) { 1259 if (buf2 != null) { buf2.append((char)c); } 1260 fEntityScanner.scanChar(); 1261 fStringBuffer3.append((char)c); 1262 1263 do { 1264 c = fEntityScanner.peekChar(); 1265 digit = (c >= '0' && c <= '9') || 1266 (c >= 'a' && c <= 'f') || 1267 (c >= 'A' && c <= 'F'); 1268 if (digit) { 1269 if (buf2 != null) { buf2.append((char)c); } 1270 fEntityScanner.scanChar(); 1271 fStringBuffer3.append((char)c); 1272 } 1273 } while (digit); 1274 } 1275 else { 1276 reportFatalError("HexdigitRequiredInCharRef", null); 1277 } 1278 } 1279 1280 else { 1282 fStringBuffer3.clear(); 1283 boolean digit = true; 1284 1285 int c = fEntityScanner.peekChar(); 1286 digit = c >= '0' && c <= '9'; 1287 if (digit) { 1288 if (buf2 != null) { buf2.append((char)c); } 1289 fEntityScanner.scanChar(); 1290 fStringBuffer3.append((char)c); 1291 1292 do { 1293 c = fEntityScanner.peekChar(); 1294 digit = c >= '0' && c <= '9'; 1295 if (digit) { 1296 if (buf2 != null) { buf2.append((char)c); } 1297 fEntityScanner.scanChar(); 1298 fStringBuffer3.append((char)c); 1299 } 1300 } while (digit); 1301 } 1302 else { 1303 reportFatalError("DigitRequiredInCharRef", null); 1304 } 1305 } 1306 1307 if (!fEntityScanner.skipChar(';')) { 1309 reportFatalError("SemicolonRequiredInCharRef", null); 1310 } 1311 if (buf2 != null) { buf2.append(';'); } 1312 1313 int value = -1; 1315 try { 1316 value = Integer.parseInt(fStringBuffer3.toString(), 1317 hex ? 16 : 10); 1318 1319 if (isInvalid(value)) { 1321 StringBuffer errorBuf = new StringBuffer (fStringBuffer3.length + 1); 1322 if (hex) errorBuf.append('x'); 1323 errorBuf.append(fStringBuffer3.ch, fStringBuffer3.offset, fStringBuffer3.length); 1324 reportFatalError("InvalidCharRef", 1325 new Object []{errorBuf.toString()}); 1326 } 1327 } 1328 catch (NumberFormatException e) { 1329 StringBuffer errorBuf = new StringBuffer (fStringBuffer3.length + 1); 1332 if (hex) errorBuf.append('x'); 1333 errorBuf.append(fStringBuffer3.ch, fStringBuffer3.offset, fStringBuffer3.length); 1334 reportFatalError("InvalidCharRef", 1335 new Object []{errorBuf.toString()}); 1336 } 1337 1338 if (!XMLChar.isSupplemental(value)) { 1340 buf.append((char) value); 1341 } 1342 else { 1343 buf.append(XMLChar.highSurrogate(value)); 1345 buf.append(XMLChar.lowSurrogate(value)); 1346 } 1347 1348 if (fNotifyCharRefs && value != -1) { 1350 String literal = "#" + (hex ? "x" : "") + fStringBuffer3.toString(); 1351 if (!fScanningAttribute) { 1352 fCharRefLiteral = literal; 1353 } 1354 } 1355 1356 return value; 1357 } 1358 1359 protected boolean isInvalid(int value) { 1363 return (XMLChar.isInvalid(value)); 1364 } 1366 protected boolean isInvalidLiteral(int value) { 1370 return (XMLChar.isInvalid(value)); 1371 } 1373 protected boolean isValidNameChar(int value) { 1377 return (XMLChar.isName(value)); 1378 } 1380 protected boolean isValidNameStartChar(int value) { 1384 return (XMLChar.isNameStart(value)); 1385 } 1387 protected boolean isValidNCName(int value) { 1391 return (XMLChar.isNCName(value)); 1392 } 1394 protected boolean isValidNameStartHighSurrogate(int value) { 1399 return false; 1400 } 1402 protected boolean versionSupported(String version ) { 1403 return version.equals("1.0"); 1404 } 1406 protected String getVersionNotSupportedKey () { 1410 return "VersionNotSupported"; 1411 } 1413 1422 protected boolean scanSurrogates(XMLStringBuffer buf) 1423 throws IOException , XNIException { 1424 1425 int high = fEntityScanner.scanChar(); 1426 int low = fEntityScanner.peekChar(); 1427 if (!XMLChar.isLowSurrogate(low)) { 1428 reportFatalError("InvalidCharInContent", 1429 new Object [] {Integer.toString(high, 16)}); 1430 return false; 1431 } 1432 fEntityScanner.scanChar(); 1433 1434 int c = XMLChar.supplemental((char)high, (char)low); 1436 1437 if (isInvalid(c)) { 1439 reportFatalError("InvalidCharInContent", 1440 new Object []{Integer.toString(c, 16)}); 1441 return false; 1442 } 1443 1444 buf.append((char)high); 1446 buf.append((char)low); 1447 1448 return true; 1449 1450 } 1452 1453 1456 protected void reportFatalError(String msgId, Object [] args) 1457 throws XNIException { 1458 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 1459 msgId, args, 1460 XMLErrorReporter.SEVERITY_FATAL_ERROR); 1461 } 1462 1463 private void init() { 1465 fEntityScanner = null; 1466 fEntityDepth = 0; 1468 fReportEntity = true; 1469 fResourceIdentifier.clear(); 1470 } 1471 1472} | Popular Tags |