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.io.MalformedByteSequenceException; 24 import org.apache.xerces.impl.msg.XMLMessageFormatter; 25 import org.apache.xerces.util.AugmentationsImpl; 26 import org.apache.xerces.util.XMLAttributesImpl; 27 import org.apache.xerces.util.XMLChar; 28 import org.apache.xerces.util.XMLStringBuffer; 29 import org.apache.xerces.util.XMLSymbols; 30 import org.apache.xerces.xni.Augmentations; 31 import org.apache.xerces.xni.QName; 32 import org.apache.xerces.xni.XMLAttributes; 33 import org.apache.xerces.xni.XMLDocumentHandler; 34 import org.apache.xerces.xni.XMLResourceIdentifier; 35 import org.apache.xerces.xni.XMLString; 36 import org.apache.xerces.xni.XNIException; 37 import org.apache.xerces.xni.parser.XMLComponent; 38 import org.apache.xerces.xni.parser.XMLComponentManager; 39 import org.apache.xerces.xni.parser.XMLConfigurationException; 40 import org.apache.xerces.xni.parser.XMLDocumentScanner; 41 import org.apache.xerces.xni.parser.XMLInputSource; 42 43 68 public class XMLDocumentFragmentScannerImpl 69 extends XMLScanner 70 implements XMLDocumentScanner, XMLComponent, XMLEntityHandler { 71 72 76 78 79 protected static final int SCANNER_STATE_START_OF_MARKUP = 1; 80 81 82 protected static final int SCANNER_STATE_COMMENT = 2; 83 84 85 protected static final int SCANNER_STATE_PI = 3; 86 87 88 protected static final int SCANNER_STATE_DOCTYPE = 4; 89 90 91 protected static final int SCANNER_STATE_ROOT_ELEMENT = 6; 92 93 94 protected static final int SCANNER_STATE_CONTENT = 7; 95 96 97 protected static final int SCANNER_STATE_REFERENCE = 8; 98 99 100 protected static final int SCANNER_STATE_END_OF_INPUT = 13; 101 102 103 protected static final int SCANNER_STATE_TERMINATED = 14; 104 105 106 protected static final int SCANNER_STATE_CDATA = 15; 107 108 109 protected static final int SCANNER_STATE_TEXT_DECL = 16; 110 111 113 114 protected static final String NAMESPACES = 115 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; 116 117 118 protected static final String NOTIFY_BUILTIN_REFS = 119 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE; 120 121 123 124 protected static final String ENTITY_RESOLVER = 125 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; 126 127 129 130 private static final String [] RECOGNIZED_FEATURES = { 131 NAMESPACES, 132 VALIDATION, 133 NOTIFY_BUILTIN_REFS, 134 NOTIFY_CHAR_REFS, 135 }; 136 137 138 private static final Boolean [] FEATURE_DEFAULTS = { 139 null, 140 null, 141 Boolean.FALSE, 142 Boolean.FALSE, 143 }; 144 145 146 private static final String [] RECOGNIZED_PROPERTIES = { 147 SYMBOL_TABLE, 148 ERROR_REPORTER, 149 ENTITY_MANAGER, 150 ENTITY_RESOLVER, 151 }; 152 153 154 private static final Object [] PROPERTY_DEFAULTS = { 155 null, 156 null, 157 null, 158 null, 159 }; 160 161 163 164 private static final boolean DEBUG_SCANNER_STATE = false; 165 166 167 private static final boolean DEBUG_DISPATCHER = false; 168 169 170 protected static final boolean DEBUG_CONTENT_SCANNING = false; 171 172 176 178 179 protected XMLDocumentHandler fDocumentHandler; 180 181 182 protected int[] fEntityStack = new int[4]; 183 184 185 protected int fMarkupDepth; 186 187 188 protected int fScannerState; 189 190 191 protected boolean fInScanContent = false; 192 193 194 protected boolean fHasExternalDTD; 195 196 197 protected boolean fStandalone; 198 199 200 protected ExternalSubsetResolver fExternalSubsetResolver; 201 202 204 205 protected QName fCurrentElement; 206 207 208 protected ElementStack fElementStack = new ElementStack(); 209 210 212 216 217 219 220 protected boolean fNotifyBuiltInRefs = false; 221 222 224 225 protected Dispatcher fDispatcher; 226 227 228 protected Dispatcher fContentDispatcher = createContentDispatcher(); 229 230 232 233 protected final QName fElementQName = new QName(); 234 235 236 protected final QName fAttributeQName = new QName(); 237 238 239 protected final XMLAttributesImpl fAttributes = new XMLAttributesImpl(); 240 241 242 protected final XMLString fTempString = new XMLString(); 243 244 245 protected final XMLString fTempString2 = new XMLString(); 246 247 248 private final String [] fStrings = new String [3]; 249 250 251 private final XMLStringBuffer fStringBuffer = new XMLStringBuffer(); 252 253 254 private final XMLStringBuffer fStringBuffer2 = new XMLStringBuffer(); 255 256 257 private final QName fQName = new QName(); 258 259 260 private final char[] fSingleChar = new char[1]; 261 262 263 private final XMLEntityManager.ExternalEntity fExternalEntity = new XMLEntityManager.ExternalEntity(); 264 265 272 private boolean fSawSpace; 273 274 275 private Augmentations fTempAugmentations = null; 276 277 281 282 public XMLDocumentFragmentScannerImpl() {} 284 288 295 public void setInputSource(XMLInputSource inputSource) throws IOException { 296 fEntityManager.setEntityHandler(this); 297 fEntityManager.startEntity("$fragment$", inputSource, false, true); 298 } 301 314 public boolean scanDocument(boolean complete) 315 throws IOException , XNIException { 316 317 fEntityScanner = fEntityManager.getEntityScanner(); 319 320 fEntityManager.setEntityHandler(this); 322 do { 323 if (!fDispatcher.dispatch(complete)) { 324 return false; 325 } 326 } while (complete); 327 328 return true; 330 331 } 333 337 351 public void reset(XMLComponentManager componentManager) 352 throws XMLConfigurationException { 353 354 super.reset(componentManager); 355 356 359 fAttributes.setNamespaces(fNamespaces); 361 362 fMarkupDepth = 0; 364 fCurrentElement = null; 365 fElementStack.clear(); 366 fHasExternalDTD = false; 367 fStandalone = false; 368 fInScanContent = false; 369 370 setScannerState(SCANNER_STATE_CONTENT); 372 setDispatcher(fContentDispatcher); 373 374 375 if (fParserSettings) { 376 378 try { 380 fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS); 381 } catch (XMLConfigurationException e) { 382 fNotifyBuiltInRefs = false; 383 } 384 385 try { 387 Object resolver = componentManager.getProperty(ENTITY_RESOLVER); 388 fExternalSubsetResolver = (resolver instanceof ExternalSubsetResolver) ? 389 (ExternalSubsetResolver) resolver : null; 390 } 391 catch (XMLConfigurationException e) { 392 fExternalSubsetResolver = null; 393 } 394 } 395 396 } 398 403 public String [] getRecognizedFeatures() { 404 return (String [])(RECOGNIZED_FEATURES.clone()); 405 } 407 422 public void setFeature(String featureId, boolean state) 423 throws XMLConfigurationException { 424 425 super.setFeature(featureId, state); 426 427 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 429 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 430 if (suffixLength == Constants.NOTIFY_BUILTIN_REFS_FEATURE.length() && 431 featureId.endsWith(Constants.NOTIFY_BUILTIN_REFS_FEATURE)) { 432 fNotifyBuiltInRefs = state; 433 } 434 } 435 436 } 438 443 public String [] getRecognizedProperties() { 444 return (String [])(RECOGNIZED_PROPERTIES.clone()); 445 } 447 462 public void setProperty(String propertyId, Object value) 463 throws XMLConfigurationException { 464 465 super.setProperty(propertyId, value); 466 467 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 469 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 470 if (suffixLength == Constants.ENTITY_MANAGER_PROPERTY.length() && 471 propertyId.endsWith(Constants.ENTITY_MANAGER_PROPERTY)) { 472 fEntityManager = (XMLEntityManager)value; 473 return; 474 } 475 if (suffixLength == Constants.ENTITY_RESOLVER_PROPERTY.length() && 476 propertyId.endsWith(Constants.ENTITY_RESOLVER_PROPERTY)) { 477 fExternalSubsetResolver = (value instanceof ExternalSubsetResolver) ? 478 (ExternalSubsetResolver) value : null; 479 return; 480 } 481 } 482 483 } 485 494 public Boolean getFeatureDefault(String featureId) { 495 for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { 496 if (RECOGNIZED_FEATURES[i].equals(featureId)) { 497 return FEATURE_DEFAULTS[i]; 498 } 499 } 500 return null; 501 } 503 512 public Object getPropertyDefault(String propertyId) { 513 for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { 514 if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { 515 return PROPERTY_DEFAULTS[i]; 516 } 517 } 518 return null; 519 } 521 525 530 public void setDocumentHandler(XMLDocumentHandler documentHandler) { 531 fDocumentHandler = documentHandler; 532 } 534 535 536 public XMLDocumentHandler getDocumentHandler(){ 537 return fDocumentHandler; 538 } 539 540 544 560 public void startEntity(String name, 561 XMLResourceIdentifier identifier, 562 String encoding, Augmentations augs) throws XNIException { 563 564 if (fEntityDepth == fEntityStack.length) { 566 int[] entityarray = new int[fEntityStack.length * 2]; 567 System.arraycopy(fEntityStack, 0, entityarray, 0, fEntityStack.length); 568 fEntityStack = entityarray; 569 } 570 fEntityStack[fEntityDepth] = fMarkupDepth; 571 572 super.startEntity(name, identifier, encoding, augs); 573 574 if(fStandalone && fEntityManager.isEntityDeclInExternalSubset(name)) { 576 reportFatalError("MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE", 577 new Object []{name}); 578 } 579 580 if (fDocumentHandler != null && !fScanningAttribute) { 582 if (!name.equals("[xml]")) { 583 fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs); 584 } 585 } 586 587 } 589 599 public void endEntity(String name, Augmentations augs) throws XNIException { 600 601 if (fInScanContent && fStringBuffer.length != 0 603 && fDocumentHandler != null) { 604 fDocumentHandler.characters(fStringBuffer, null); 605 fStringBuffer.length = 0; } 607 608 super.endEntity(name, augs); 609 610 if (fMarkupDepth != fEntityStack[fEntityDepth]) { 612 reportFatalError("MarkupEntityMismatch", null); 613 } 614 615 if (fDocumentHandler != null && !fScanningAttribute) { 617 if (!name.equals("[xml]")) { 618 fDocumentHandler.endGeneralEntity(name, augs); 619 } 620 } 621 622 } 624 628 630 631 protected Dispatcher createContentDispatcher() { 632 return new FragmentContentDispatcher(); 633 } 635 637 655 protected void scanXMLDeclOrTextDecl(boolean scanningTextDecl) 656 throws IOException , XNIException { 657 658 super.scanXMLDeclOrTextDecl(scanningTextDecl, fStrings); 660 fMarkupDepth--; 661 662 String version = fStrings[0]; 664 String encoding = fStrings[1]; 665 String standalone = fStrings[2]; 666 667 fStandalone = standalone != null && standalone.equals("yes"); 669 fEntityManager.setStandalone(fStandalone); 670 671 fEntityScanner.setXMLVersion(version); 673 674 if (fDocumentHandler != null) { 676 if (scanningTextDecl) { 677 fDocumentHandler.textDecl(version, encoding, null); 678 } 679 else { 680 fDocumentHandler.xmlDecl(version, encoding, standalone, null); 681 } 682 } 683 684 if (encoding != null && !fEntityScanner.fCurrentEntity.isEncodingExternallySpecified()) { 686 fEntityScanner.setEncoding(encoding); 687 } 688 689 } 691 699 protected void scanPIData(String target, XMLString data) 700 throws IOException , XNIException { 701 702 super.scanPIData(target, data); 703 fMarkupDepth--; 704 705 if (fDocumentHandler != null) { 707 fDocumentHandler.processingInstruction(target, data, null); 708 } 709 710 } 712 721 protected void scanComment() throws IOException , XNIException { 722 723 scanComment(fStringBuffer); 724 fMarkupDepth--; 725 726 if (fDocumentHandler != null) { 728 fDocumentHandler.comment(fStringBuffer, null); 729 } 730 731 } 733 754 protected boolean scanStartElement() 755 throws IOException , XNIException { 756 if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanStartElement()"); 757 758 if (fNamespaces) { 760 fEntityScanner.scanQName(fElementQName); 761 } 762 else { 763 String name = fEntityScanner.scanName(); 764 fElementQName.setValues(null, name, name, null); 765 } 766 String rawname = fElementQName.rawname; 767 768 fCurrentElement = fElementStack.pushElement(fElementQName); 770 771 boolean empty = false; 773 fAttributes.removeAllAttributes(); 774 do { 775 boolean sawSpace = fEntityScanner.skipSpaces(); 777 778 int c = fEntityScanner.peekChar(); 780 if (c == '>') { 781 fEntityScanner.scanChar(); 782 break; 783 } 784 else if (c == '/') { 785 fEntityScanner.scanChar(); 786 if (!fEntityScanner.skipChar('>')) { 787 reportFatalError("ElementUnterminated", 788 new Object []{rawname}); 789 } 790 empty = true; 791 break; 792 } 793 else if (!isValidNameStartChar(c) || !sawSpace) { 794 if (!isValidNameStartHighSurrogate(c) || !sawSpace) { 797 reportFatalError("ElementUnterminated", 798 new Object [] { rawname }); 799 } 800 } 801 802 scanAttribute(fAttributes); 804 805 } while (true); 806 807 if (fDocumentHandler != null) { 809 if (empty) { 810 811 fMarkupDepth--; 813 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 815 reportFatalError("ElementEntityMismatch", 816 new Object []{fCurrentElement.rawname}); 817 } 818 819 fDocumentHandler.emptyElement(fElementQName, fAttributes, null); 820 821 fElementStack.popElement(fElementQName); 823 } 824 else { 825 fDocumentHandler.startElement(fElementQName, fAttributes, null); 826 } 827 } 828 829 if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanStartElement(): "+empty); 830 return empty; 831 832 } 834 839 protected void scanStartElementName () 840 throws IOException , XNIException { 841 if (fNamespaces) { 843 fEntityScanner.scanQName(fElementQName); 844 } 845 else { 846 String name = fEntityScanner.scanName(); 847 fElementQName.setValues(null, name, name, null); 848 } 849 fSawSpace = fEntityScanner.skipSpaces(); 852 } 854 860 protected boolean scanStartElementAfterName() 861 throws IOException , XNIException { 862 String rawname = fElementQName.rawname; 863 864 fCurrentElement = fElementStack.pushElement(fElementQName); 866 867 boolean empty = false; 869 fAttributes.removeAllAttributes(); 870 do { 871 872 int c = fEntityScanner.peekChar(); 874 if (c == '>') { 875 fEntityScanner.scanChar(); 876 break; 877 } 878 else if (c == '/') { 879 fEntityScanner.scanChar(); 880 if (!fEntityScanner.skipChar('>')) { 881 reportFatalError("ElementUnterminated", 882 new Object []{rawname}); 883 } 884 empty = true; 885 break; 886 } 887 else if (!isValidNameStartChar(c) || !fSawSpace) { 888 if (!isValidNameStartHighSurrogate(c) || !fSawSpace) { 891 reportFatalError("ElementUnterminated", 892 new Object [] { rawname }); 893 } 894 } 895 896 scanAttribute(fAttributes); 898 899 fSawSpace = fEntityScanner.skipSpaces(); 901 902 } while (true); 903 904 if (fDocumentHandler != null) { 906 if (empty) { 907 908 fMarkupDepth--; 910 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 912 reportFatalError("ElementEntityMismatch", 913 new Object []{fCurrentElement.rawname}); 914 } 915 916 fDocumentHandler.emptyElement(fElementQName, fAttributes, null); 917 918 fElementStack.popElement(fElementQName); 920 } 921 else { 922 fDocumentHandler.startElement(fElementQName, fAttributes, null); 923 } 924 } 925 926 if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanStartElementAfterName(): "+empty); 927 return empty; 928 } 930 947 protected void scanAttribute(XMLAttributes attributes) 948 throws IOException , XNIException { 949 if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanAttribute()"); 950 951 if (fNamespaces) { 953 fEntityScanner.scanQName(fAttributeQName); 954 } 955 else { 956 String name = fEntityScanner.scanName(); 957 fAttributeQName.setValues(null, name, name, null); 958 } 959 960 fEntityScanner.skipSpaces(); 962 if (!fEntityScanner.skipChar('=')) { 963 reportFatalError("EqRequiredInAttribute", 964 new Object []{fCurrentElement.rawname,fAttributeQName.rawname}); 965 } 966 fEntityScanner.skipSpaces(); 967 968 int oldLen = attributes.getLength(); 970 int attrIndex = attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null); 971 972 if (oldLen == attributes.getLength()) { 974 reportFatalError("AttributeNotUnique", 975 new Object []{fCurrentElement.rawname, 976 fAttributeQName.rawname}); 977 } 978 boolean isVC = fHasExternalDTD && !fStandalone; 980 981 boolean isSameNormalizedAttr = scanAttributeValue(fTempString, fTempString2, 983 fAttributeQName.rawname, isVC, fCurrentElement.rawname); 984 985 attributes.setValue(attrIndex, fTempString.toString()); 986 if (!isSameNormalizedAttr) { 988 attributes.setNonNormalizedValue(attrIndex, fTempString2.toString()); 989 } 990 attributes.setSpecified(attrIndex, true); 991 992 if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanAttribute()"); 993 } 995 1000 protected int scanContent() throws IOException , XNIException { 1001 1002 XMLString content = fTempString; 1003 int c = fEntityScanner.scanContent(content); 1004 if (c == '\r') { 1005 fEntityScanner.scanChar(); 1007 fStringBuffer.clear(); 1008 fStringBuffer.append(fTempString); 1009 fStringBuffer.append((char)c); 1010 content = fStringBuffer; 1011 c = -1; 1012 } 1013 if (fDocumentHandler != null && content.length > 0) { 1014 fDocumentHandler.characters(content, null); 1015 } 1016 1017 if (c == ']' && fTempString.length == 0) { 1018 fStringBuffer.clear(); 1019 fStringBuffer.append((char)fEntityScanner.scanChar()); 1020 fInScanContent = true; 1024 if (fEntityScanner.skipChar(']')) { 1029 fStringBuffer.append(']'); 1030 while (fEntityScanner.skipChar(']')) { 1031 fStringBuffer.append(']'); 1032 } 1033 if (fEntityScanner.skipChar('>')) { 1034 reportFatalError("CDEndInContent", null); 1035 } 1036 } 1037 if (fDocumentHandler != null && fStringBuffer.length != 0) { 1038 fDocumentHandler.characters(fStringBuffer, null); 1039 } 1040 fInScanContent = false; 1041 c = -1; 1042 } 1043 return c; 1044 1045 } 1047 1048 1059 protected boolean scanCDATASection(boolean complete) 1060 throws IOException , XNIException { 1061 1062 if (fDocumentHandler != null) { 1064 fDocumentHandler.startCDATA(null); 1065 } 1066 1067 while (true) { 1068 fStringBuffer.clear(); 1069 if (!fEntityScanner.scanData("]]", fStringBuffer)) { 1070 if (fDocumentHandler != null && fStringBuffer.length > 0) { 1071 fDocumentHandler.characters(fStringBuffer, null); 1072 } 1073 int brackets = 0; 1074 while (fEntityScanner.skipChar(']')) { 1075 brackets++; 1076 } 1077 if (fDocumentHandler != null && brackets > 0) { 1078 fStringBuffer.clear(); 1079 if (brackets > XMLEntityManager.DEFAULT_BUFFER_SIZE) { 1080 int chunks = brackets / XMLEntityManager.DEFAULT_BUFFER_SIZE; 1082 int remainder = brackets % XMLEntityManager.DEFAULT_BUFFER_SIZE; 1083 for (int i = 0; i < XMLEntityManager.DEFAULT_BUFFER_SIZE; i++) { 1084 fStringBuffer.append(']'); 1085 } 1086 for (int i = 0; i < chunks; i++) { 1087 fDocumentHandler.characters(fStringBuffer, null); 1088 } 1089 if (remainder != 0) { 1090 fStringBuffer.length = remainder; 1091 fDocumentHandler.characters(fStringBuffer, null); 1092 } 1093 } 1094 else { 1095 for (int i = 0; i < brackets; i++) { 1096 fStringBuffer.append(']'); 1097 } 1098 fDocumentHandler.characters(fStringBuffer, null); 1099 } 1100 } 1101 if (fEntityScanner.skipChar('>')) { 1102 break; 1103 } 1104 if (fDocumentHandler != null) { 1105 fStringBuffer.clear(); 1106 fStringBuffer.append("]]"); 1107 fDocumentHandler.characters(fStringBuffer, null); 1108 } 1109 } 1110 else { 1111 if (fDocumentHandler != null) { 1112 fDocumentHandler.characters(fStringBuffer, null); 1113 } 1114 int c = fEntityScanner.peekChar(); 1115 if (c != -1 && isInvalidLiteral(c)) { 1116 if (XMLChar.isHighSurrogate(c)) { 1117 fStringBuffer.clear(); 1118 scanSurrogates(fStringBuffer); 1119 if (fDocumentHandler != null) { 1120 fDocumentHandler.characters(fStringBuffer, null); 1121 } 1122 } 1123 else { 1124 reportFatalError("InvalidCharInCDSect", 1125 new Object []{Integer.toString(c,16)}); 1126 fEntityScanner.scanChar(); 1127 } 1128 } 1129 } 1130 } 1131 fMarkupDepth--; 1132 1133 if (fDocumentHandler != null) { 1135 fDocumentHandler.endCDATA(null); 1136 } 1137 1138 return true; 1139 1140 } 1142 1156 protected int scanEndElement() throws IOException , XNIException { 1157 if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanEndElement()"); 1158 1159 fElementStack.popElement(fElementQName) ; 1160 1161 1166 1168 if (!fEntityScanner.skipString(fElementQName.rawname)) { 1171 reportFatalError("ETagRequired", new Object []{fElementQName.rawname}); 1172 } 1173 1174 fEntityScanner.skipSpaces(); 1176 if (!fEntityScanner.skipChar('>')) { 1177 reportFatalError("ETagUnterminated", 1178 new Object []{fElementQName.rawname}); 1179 } 1180 fMarkupDepth--; 1181 1182 fMarkupDepth--; 1184 1185 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 1187 reportFatalError("ElementEntityMismatch", 1188 new Object []{fCurrentElement.rawname}); 1189 } 1190 1191 if (fDocumentHandler != null ) { 1193 fDocumentHandler.endElement(fElementQName, null); 1194 } 1195 1196 return fMarkupDepth; 1197 1198 } 1200 1207 protected void scanCharReference() 1208 throws IOException , XNIException { 1209 1210 fStringBuffer2.clear(); 1211 int ch = scanCharReferenceValue(fStringBuffer2, null); 1212 fMarkupDepth--; 1213 if (ch != -1) { 1214 if (fDocumentHandler != null) { 1216 if (fNotifyCharRefs) { 1217 fDocumentHandler.startGeneralEntity(fCharRefLiteral, null, null, null); 1218 } 1219 Augmentations augs = null; 1220 if (fValidation && ch <= 0x20) { 1221 if (fTempAugmentations != null) { 1222 fTempAugmentations.removeAllItems(); 1223 } 1224 else { 1225 fTempAugmentations = new AugmentationsImpl(); 1226 } 1227 augs = fTempAugmentations; 1228 augs.putItem(Constants.CHAR_REF_PROBABLE_WS, Boolean.TRUE); 1229 } 1230 fDocumentHandler.characters(fStringBuffer2, augs); 1231 if (fNotifyCharRefs) { 1232 fDocumentHandler.endGeneralEntity(fCharRefLiteral, null); 1233 } 1234 } 1235 } 1236 1237 } 1239 1246 protected void scanEntityReference() throws IOException , XNIException { 1247 1248 String name = fEntityScanner.scanName(); 1250 if (name == null) { 1251 reportFatalError("NameRequiredInReference", null); 1252 return; 1253 } 1254 1255 if (!fEntityScanner.skipChar(';')) { 1257 reportFatalError("SemicolonRequiredInReference", new Object []{name}); 1258 } 1259 fMarkupDepth--; 1260 1261 if (name == fAmpSymbol) { 1263 handleCharacter('&', fAmpSymbol); 1264 } 1265 else if (name == fLtSymbol) { 1266 handleCharacter('<', fLtSymbol); 1267 } 1268 else if (name == fGtSymbol) { 1269 handleCharacter('>', fGtSymbol); 1270 } 1271 else if (name == fQuotSymbol) { 1272 handleCharacter('"', fQuotSymbol); 1273 } 1274 else if (name == fAposSymbol) { 1275 handleCharacter('\'', fAposSymbol); 1276 } 1277 else if (fEntityManager.isUnparsedEntity(name)) { 1279 reportFatalError("ReferenceToUnparsedEntity", new Object []{name}); 1280 } 1281 else { 1282 if (!fEntityManager.isDeclaredEntity(name)) { 1283 if ( fHasExternalDTD && !fStandalone) { 1285 if (fValidation) 1286 fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,"EntityNotDeclared", 1287 new Object []{name}, XMLErrorReporter.SEVERITY_ERROR); 1288 } 1289 else 1290 reportFatalError("EntityNotDeclared", new Object []{name}); 1291 } 1292 fEntityManager.startEntity(name, false); 1293 } 1294 1295 } 1297 1299 1306 private void handleCharacter(char c, String entity) throws XNIException { 1307 if (fDocumentHandler != null) { 1308 if (fNotifyBuiltInRefs) { 1309 fDocumentHandler.startGeneralEntity(entity, null, null, null); 1310 } 1311 1312 fSingleChar[0] = c; 1313 fTempString.setValues(fSingleChar, 0, 1); 1314 fDocumentHandler.characters(fTempString, null); 1315 1316 if (fNotifyBuiltInRefs) { 1317 fDocumentHandler.endGeneralEntity(entity, null); 1318 } 1319 } 1320 } 1322 1339 protected int handleEndElement(QName element, boolean isEmpty) 1342 throws XNIException { 1343 1344 fMarkupDepth--; 1345 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 1347 reportFatalError("ElementEntityMismatch", 1348 new Object []{fCurrentElement.rawname}); 1349 } 1350 QName startElement = fQName; 1352 fElementStack.popElement(startElement); 1353 if (element.rawname != startElement.rawname) { 1354 reportFatalError("ETagRequired", 1355 new Object []{startElement.rawname}); 1356 } 1357 1358 if (fNamespaces) { 1360 element.uri = startElement.uri; 1361 } 1362 1363 if (fDocumentHandler != null && !isEmpty) { 1365 fDocumentHandler.endElement(element, null); 1366 } 1367 1368 return fMarkupDepth; 1369 1370 } 1372 1374 1379 protected final void setScannerState(int state) { 1380 1381 fScannerState = state; 1382 if (DEBUG_SCANNER_STATE) { 1383 System.out.print("### setScannerState: "); 1384 System.out.print(getScannerStateName(state)); 1385 System.out.println(); 1386 } 1387 1388 } 1390 1395 protected final void setDispatcher(Dispatcher dispatcher) { 1396 fDispatcher = dispatcher; 1397 if (DEBUG_DISPATCHER) { 1398 System.out.print("%%% setDispatcher: "); 1399 System.out.print(getDispatcherName(dispatcher)); 1400 System.out.println(); 1401 } 1402 } 1403 1404 1408 1409 protected String getScannerStateName(int state) { 1410 1411 switch (state) { 1412 case SCANNER_STATE_DOCTYPE: return "SCANNER_STATE_DOCTYPE"; 1413 case SCANNER_STATE_ROOT_ELEMENT: return "SCANNER_STATE_ROOT_ELEMENT"; 1414 case SCANNER_STATE_START_OF_MARKUP: return "SCANNER_STATE_START_OF_MARKUP"; 1415 case SCANNER_STATE_COMMENT: return "SCANNER_STATE_COMMENT"; 1416 case SCANNER_STATE_PI: return "SCANNER_STATE_PI"; 1417 case SCANNER_STATE_CONTENT: return "SCANNER_STATE_CONTENT"; 1418 case SCANNER_STATE_REFERENCE: return "SCANNER_STATE_REFERENCE"; 1419 case SCANNER_STATE_END_OF_INPUT: return "SCANNER_STATE_END_OF_INPUT"; 1420 case SCANNER_STATE_TERMINATED: return "SCANNER_STATE_TERMINATED"; 1421 case SCANNER_STATE_CDATA: return "SCANNER_STATE_CDATA"; 1422 case SCANNER_STATE_TEXT_DECL: return "SCANNER_STATE_TEXT_DECL"; 1423 } 1424 1425 return "??? ("+state+')'; 1426 1427 } 1429 1430 public String getDispatcherName(Dispatcher dispatcher) { 1431 1432 if (DEBUG_DISPATCHER) { 1433 if (dispatcher != null) { 1434 String name = dispatcher.getClass().getName(); 1435 int index = name.lastIndexOf('.'); 1436 if (index != -1) { 1437 name = name.substring(index + 1); 1438 index = name.lastIndexOf('$'); 1439 if (index != -1) { 1440 name = name.substring(index + 1); 1441 } 1442 } 1443 return name; 1444 } 1445 } 1446 return "null"; 1447 1448 } 1450 1454 1461 protected static class ElementStack { 1462 1463 1467 1468 protected QName[] fElements; 1469 1470 1471 protected int fSize; 1472 1473 1477 1478 public ElementStack() { 1479 fElements = new QName[10]; 1480 for (int i = 0; i < fElements.length; i++) { 1481 fElements[i] = new QName(); 1482 } 1483 } 1485 1489 1502 public QName pushElement(QName element) { 1503 if (fSize == fElements.length) { 1504 QName[] array = new QName[fElements.length * 2]; 1505 System.arraycopy(fElements, 0, array, 0, fSize); 1506 fElements = array; 1507 for (int i = fSize; i < fElements.length; i++) { 1508 fElements[i] = new QName(); 1509 } 1510 } 1511 fElements[fSize].setValues(element); 1512 return fElements[fSize++]; 1513 } 1515 1523 public void popElement(QName element) { 1524 element.setValues(fElements[--fSize]); 1525 } 1527 1528 public void clear() { 1529 fSize = 0; 1530 } 1532 } 1534 1543 protected interface Dispatcher { 1544 1545 1549 1561 public boolean dispatch(boolean complete) 1562 throws IOException , XNIException; 1563 1564 } 1566 1572 protected class FragmentContentDispatcher 1573 implements Dispatcher { 1574 1575 1579 1591 public boolean dispatch(boolean complete) 1592 throws IOException , XNIException { 1593 try { 1594 boolean again; 1595 do { 1596 again = false; 1597 switch (fScannerState) { 1598 case SCANNER_STATE_CONTENT: { 1599 if (fEntityScanner.skipChar('<')) { 1600 setScannerState(SCANNER_STATE_START_OF_MARKUP); 1601 again = true; 1602 } 1603 else if (fEntityScanner.skipChar('&')) { 1604 setScannerState(SCANNER_STATE_REFERENCE); 1605 again = true; 1606 } 1607 else { 1608 do { 1609 int c = scanContent(); 1610 if (c == '<') { 1611 fEntityScanner.scanChar(); 1612 setScannerState(SCANNER_STATE_START_OF_MARKUP); 1613 break; 1614 } 1615 else if (c == '&') { 1616 fEntityScanner.scanChar(); 1617 setScannerState(SCANNER_STATE_REFERENCE); 1618 break; 1619 } 1620 else if (c != -1 && isInvalidLiteral(c)) { 1621 if (XMLChar.isHighSurrogate(c)) { 1622 fStringBuffer.clear(); 1624 if (scanSurrogates(fStringBuffer)) { 1625 if (fDocumentHandler != null) { 1627 fDocumentHandler.characters(fStringBuffer, null); 1628 } 1629 } 1630 } 1631 else { 1632 reportFatalError("InvalidCharInContent", 1633 new Object [] { 1634 Integer.toString(c, 16)}); 1635 fEntityScanner.scanChar(); 1636 } 1637 } 1638 } while (complete); 1639 } 1640 break; 1641 } 1642 case SCANNER_STATE_START_OF_MARKUP: { 1643 fMarkupDepth++; 1644 if (fEntityScanner.skipChar('/')) { 1645 if (scanEndElement() == 0) { 1646 if (elementDepthIsZeroHook()) { 1647 return true; 1648 } 1649 } 1650 setScannerState(SCANNER_STATE_CONTENT); 1651 } 1652 else if (isValidNameStartChar(fEntityScanner.peekChar())) { 1653 scanStartElement(); 1654 setScannerState(SCANNER_STATE_CONTENT); 1655 } 1656 else if (fEntityScanner.skipChar('!')) { 1657 if (fEntityScanner.skipChar('-')) { 1658 if (!fEntityScanner.skipChar('-')) { 1659 reportFatalError("InvalidCommentStart", 1660 null); 1661 } 1662 setScannerState(SCANNER_STATE_COMMENT); 1663 again = true; 1664 } 1665 else if (fEntityScanner.skipString("[CDATA[")) { 1666 setScannerState(SCANNER_STATE_CDATA); 1667 again = true; 1668 } 1669 else if (!scanForDoctypeHook()) { 1670 reportFatalError("MarkupNotRecognizedInContent", 1671 null); 1672 } 1673 } 1674 else if (fEntityScanner.skipChar('?')) { 1675 setScannerState(SCANNER_STATE_PI); 1676 again = true; 1677 } 1678 else if (isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { 1679 scanStartElement(); 1680 setScannerState(SCANNER_STATE_CONTENT); 1681 } 1682 else { 1683 reportFatalError("MarkupNotRecognizedInContent", 1684 null); 1685 setScannerState(SCANNER_STATE_CONTENT); 1686 } 1687 break; 1688 } 1689 case SCANNER_STATE_COMMENT: { 1690 scanComment(); 1691 setScannerState(SCANNER_STATE_CONTENT); 1692 break; 1693 } 1694 case SCANNER_STATE_PI: { 1695 scanPI(); 1696 setScannerState(SCANNER_STATE_CONTENT); 1697 break; 1698 } 1699 case SCANNER_STATE_CDATA: { 1700 scanCDATASection(complete); 1701 setScannerState(SCANNER_STATE_CONTENT); 1702 break; 1703 } 1704 case SCANNER_STATE_REFERENCE: { 1705 fMarkupDepth++; 1706 setScannerState(SCANNER_STATE_CONTENT); 1712 if (fEntityScanner.skipChar('#')) { 1713 scanCharReference(); 1714 } 1715 else { 1716 scanEntityReference(); 1717 } 1718 break; 1719 } 1720 case SCANNER_STATE_TEXT_DECL: { 1721 if (fEntityScanner.skipString("<?xml")) { 1723 fMarkupDepth++; 1724 if (isValidNameChar(fEntityScanner.peekChar())) { 1727 fStringBuffer.clear(); 1728 fStringBuffer.append("xml"); 1729 if (fNamespaces) { 1730 while (isValidNCName(fEntityScanner.peekChar())) { 1731 fStringBuffer.append((char)fEntityScanner.scanChar()); 1732 } 1733 } 1734 else { 1735 while (isValidNameChar(fEntityScanner.peekChar())) { 1736 fStringBuffer.append((char)fEntityScanner.scanChar()); 1737 } 1738 } 1739 String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length); 1740 scanPIData(target, fTempString); 1741 } 1742 1743 else { 1745 scanXMLDeclOrTextDecl(true); 1746 } 1747 } 1748 fEntityManager.fCurrentEntity.mayReadChunks = true; 1750 setScannerState(SCANNER_STATE_CONTENT); 1751 break; 1752 } 1753 case SCANNER_STATE_ROOT_ELEMENT: { 1754 if (scanRootElementHook()) { 1755 return true; 1756 } 1757 setScannerState(SCANNER_STATE_CONTENT); 1758 break; 1759 } 1760 case SCANNER_STATE_DOCTYPE: { 1761 reportFatalError("DoctypeIllegalInContent", 1762 null); 1763 setScannerState(SCANNER_STATE_CONTENT); 1764 } 1765 } 1766 } while (complete || again); 1767 } 1768 catch (MalformedByteSequenceException e) { 1770 fErrorReporter.reportError(e.getDomain(), e.getKey(), 1771 e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR); 1772 return false; 1773 } 1774 catch (CharConversionException e) { 1775 reportFatalError("CharConversionFailure", null); 1776 return false; 1777 } 1778 catch (EOFException e) { 1780 endOfFileHook(e); 1781 return false; 1782 } 1783 1784 return true; 1785 1786 } 1788 1792 1794 1797 1805 protected boolean scanForDoctypeHook() 1806 throws IOException , XNIException { 1807 return false; 1808 } 1810 1823 protected boolean elementDepthIsZeroHook() 1824 throws IOException , XNIException { 1825 return false; 1826 } 1828 1840 protected boolean scanRootElementHook() 1841 throws IOException , XNIException { 1842 return false; 1843 } 1845 1852 protected void endOfFileHook(EOFException e) 1853 throws IOException , XNIException { 1854 1855 if (fMarkupDepth != 0) { 1858 reportFatalError("PrematureEOF", null); 1859 } 1860 1861 } 1863 } 1865} | Popular Tags |