1 57 58 package com.sun.org.apache.xerces.internal.impl; 59 60 import java.io.CharConversionException ; 61 import java.io.EOFException ; 62 import java.io.IOException ; 63 64 import com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException; 65 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 66 import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; 67 import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; 68 import com.sun.org.apache.xerces.internal.util.XMLChar; 69 import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; 70 import com.sun.org.apache.xerces.internal.util.XMLSymbols; 71 import com.sun.org.apache.xerces.internal.xni.Augmentations; 72 import com.sun.org.apache.xerces.internal.xni.QName; 73 import com.sun.org.apache.xerces.internal.xni.XMLAttributes; 74 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; 75 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; 76 import com.sun.org.apache.xerces.internal.xni.XMLString; 77 import com.sun.org.apache.xerces.internal.xni.XNIException; 78 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; 79 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 80 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 81 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner; 82 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 83 import com.sun.org.apache.xerces.internal.util.SecurityManager; 84 85 108 public class XMLDocumentFragmentScannerImpl 109 extends XMLScanner 110 implements XMLDocumentScanner, XMLComponent, XMLEntityHandler { 111 112 116 protected SecurityManager fSecurityManager = null; 117 118 120 121 protected static final int SCANNER_STATE_START_OF_MARKUP = 1; 122 123 124 protected static final int SCANNER_STATE_COMMENT = 2; 125 126 127 protected static final int SCANNER_STATE_PI = 3; 128 129 130 protected static final int SCANNER_STATE_DOCTYPE = 4; 131 132 133 protected static final int SCANNER_STATE_ROOT_ELEMENT = 6; 134 135 136 protected static final int SCANNER_STATE_CONTENT = 7; 137 138 139 protected static final int SCANNER_STATE_REFERENCE = 8; 140 141 142 protected static final int SCANNER_STATE_END_OF_INPUT = 13; 143 144 145 protected static final int SCANNER_STATE_TERMINATED = 14; 146 147 148 protected static final int SCANNER_STATE_CDATA = 15; 149 150 151 protected static final int SCANNER_STATE_TEXT_DECL = 16; 152 153 155 156 protected static final String NAMESPACES = 157 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; 158 159 160 protected static final String NOTIFY_BUILTIN_REFS = 161 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE; 162 163 165 166 protected static final String ENTITY_RESOLVER = 167 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; 168 169 171 172 private static final String [] RECOGNIZED_FEATURES = { 173 NAMESPACES, 174 VALIDATION, 175 NOTIFY_BUILTIN_REFS, 176 NOTIFY_CHAR_REFS, 177 }; 178 179 180 private static final Boolean [] FEATURE_DEFAULTS = { 181 null, 182 null, 183 Boolean.FALSE, 184 Boolean.FALSE, 185 }; 186 187 188 private static final String [] RECOGNIZED_PROPERTIES = { 189 SYMBOL_TABLE, 190 ERROR_REPORTER, 191 ENTITY_MANAGER, 192 ENTITY_RESOLVER, 193 }; 194 195 196 private static final Object [] PROPERTY_DEFAULTS = { 197 null, 198 null, 199 null, 200 null, 201 }; 202 203 205 206 private static final boolean DEBUG_SCANNER_STATE = false; 207 208 209 private static final boolean DEBUG_DISPATCHER = false; 210 211 212 protected static final boolean DEBUG_CONTENT_SCANNING = false; 213 214 218 220 221 protected XMLDocumentHandler fDocumentHandler; 222 223 224 protected int[] fEntityStack = new int[4]; 225 226 227 protected int fMarkupDepth; 228 229 230 protected int fScannerState; 231 232 233 protected boolean fInScanContent = false; 234 235 236 protected boolean fHasExternalDTD; 237 238 239 protected boolean fStandalone; 240 241 protected int fElementAttributeLimit; 243 244 245 246 protected ExternalSubsetResolver fExternalSubsetResolver; 247 248 250 251 protected QName fCurrentElement; 252 253 254 protected ElementStack fElementStack = new ElementStack(); 255 256 258 262 263 265 266 protected boolean fNotifyBuiltInRefs = false; 267 268 270 271 protected Dispatcher fDispatcher; 272 273 274 protected Dispatcher fContentDispatcher = createContentDispatcher(); 275 276 278 279 protected QName fElementQName = new QName(); 280 281 282 protected QName fAttributeQName = new QName(); 283 284 285 protected XMLAttributesImpl fAttributes = new XMLAttributesImpl(); 286 287 288 protected XMLString fTempString = new XMLString(); 289 290 291 protected XMLString fTempString2 = new XMLString(); 292 293 294 private String [] fStrings = new String [3]; 295 296 297 private XMLStringBuffer fStringBuffer = new XMLStringBuffer(); 298 299 300 private XMLStringBuffer fStringBuffer2 = new XMLStringBuffer(); 301 302 303 304 private QName fQName = new QName(); 305 306 307 308 private final char[] fSingleChar = new char[1]; 309 310 311 private XMLEntityManager.ExternalEntity fExternalEntity = new XMLEntityManager.ExternalEntity(); 312 313 320 private boolean fSawSpace; 321 322 326 327 public XMLDocumentFragmentScannerImpl() {} 329 333 340 public void setInputSource(XMLInputSource inputSource) throws IOException { 341 fEntityManager.setEntityHandler(this); 342 fEntityManager.startEntity("$fragment$", inputSource, false, true); 343 } 346 359 public boolean scanDocument(boolean complete) 360 throws IOException , XNIException { 361 362 fEntityScanner = fEntityManager.getEntityScanner(); 364 365 fEntityManager.setEntityHandler(this); 367 do { 368 if (!fDispatcher.dispatch(complete)) { 369 return false; 370 } 371 } while (complete); 372 373 return true; 375 376 } 378 382 396 public void reset(XMLComponentManager componentManager) 397 throws XMLConfigurationException { 398 399 super.reset(componentManager); 400 401 404 fAttributes.setNamespaces(fNamespaces); 406 407 fMarkupDepth = 0; 409 fCurrentElement = null; 410 fElementStack.clear(); 411 fHasExternalDTD = false; 412 fStandalone = false; 413 fInScanContent = false; 414 415 try { 417 fSecurityManager = (SecurityManager )componentManager.getProperty(Constants.SECURITY_MANAGER); 418 } catch (XMLConfigurationException e) { 419 fSecurityManager = null; 420 } 421 422 fElementAttributeLimit = (fSecurityManager != null)?fSecurityManager.getElementAttrLimit():0; 423 setScannerState(SCANNER_STATE_CONTENT); 424 setDispatcher(fContentDispatcher); 425 426 if (fParserSettings) { 427 429 try { 431 fNotifyBuiltInRefs = componentManager.getFeature(NOTIFY_BUILTIN_REFS); 432 } catch (XMLConfigurationException e) { 433 fNotifyBuiltInRefs = false; 434 } 435 436 try { 438 Object resolver = componentManager.getProperty(ENTITY_RESOLVER); 439 fExternalSubsetResolver = (resolver instanceof ExternalSubsetResolver) ? 440 (ExternalSubsetResolver) resolver : null; 441 } 442 catch (XMLConfigurationException e) { 443 fExternalSubsetResolver = null; 444 } 445 } 446 447 } 449 454 public String [] getRecognizedFeatures() { 455 return (String [])(RECOGNIZED_FEATURES.clone()); 456 } 458 473 public void setFeature(String featureId, boolean state) 474 throws XMLConfigurationException { 475 476 super.setFeature(featureId, state); 477 478 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 480 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 481 if (suffixLength == Constants.NOTIFY_BUILTIN_REFS_FEATURE.length() && 482 featureId.endsWith(Constants.NOTIFY_BUILTIN_REFS_FEATURE)) { 483 fNotifyBuiltInRefs = state; 484 } 485 } 486 487 } 489 494 public String [] getRecognizedProperties() { 495 return (String [])(RECOGNIZED_PROPERTIES.clone()); 496 } 498 513 public void setProperty(String propertyId, Object value) 514 throws XMLConfigurationException { 515 516 super.setProperty(propertyId, value); 517 518 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 520 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 521 if (suffixLength == Constants.ENTITY_MANAGER_PROPERTY.length() && 522 propertyId.endsWith(Constants.ENTITY_MANAGER_PROPERTY)) { 523 fEntityManager = (XMLEntityManager)value; 524 return; 525 } 526 if (suffixLength == Constants.ENTITY_RESOLVER_PROPERTY.length() && 527 propertyId.endsWith(Constants.ENTITY_RESOLVER_PROPERTY)) { 528 fExternalSubsetResolver = (value instanceof ExternalSubsetResolver) ? 529 (ExternalSubsetResolver) value : null; 530 return; 531 } 532 } 533 534 } 536 545 public Boolean getFeatureDefault(String featureId) { 546 for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { 547 if (RECOGNIZED_FEATURES[i].equals(featureId)) { 548 return FEATURE_DEFAULTS[i]; 549 } 550 } 551 return null; 552 } 554 563 public Object getPropertyDefault(String propertyId) { 564 for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { 565 if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { 566 return PROPERTY_DEFAULTS[i]; 567 } 568 } 569 return null; 570 } 572 576 581 public void setDocumentHandler(XMLDocumentHandler documentHandler) { 582 fDocumentHandler = documentHandler; 583 } 585 586 587 public XMLDocumentHandler getDocumentHandler(){ 588 return fDocumentHandler; 589 } 590 591 595 611 public void startEntity(String name, 612 XMLResourceIdentifier identifier, 613 String encoding, Augmentations augs) throws XNIException { 614 615 if (fEntityDepth == fEntityStack.length) { 617 int[] entityarray = new int[fEntityStack.length * 2]; 618 System.arraycopy(fEntityStack, 0, entityarray, 0, fEntityStack.length); 619 fEntityStack = entityarray; 620 } 621 fEntityStack[fEntityDepth] = fMarkupDepth; 622 623 super.startEntity(name, identifier, encoding, augs); 624 625 if(fStandalone && fEntityManager.isEntityDeclInExternalSubset(name)) { 627 reportFatalError("MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE", 628 new Object []{name}); 629 } 630 631 if (fDocumentHandler != null && !fScanningAttribute) { 633 if (!name.equals("[xml]")) { 634 fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs); 635 } 636 } 637 638 } 640 650 public void endEntity(String name, Augmentations augs) throws XNIException { 651 652 if (fInScanContent && fStringBuffer.length != 0 654 && fDocumentHandler != null) { 655 fDocumentHandler.characters(fStringBuffer, null); 656 fStringBuffer.length = 0; } 658 659 super.endEntity(name, augs); 660 661 if (fMarkupDepth != fEntityStack[fEntityDepth]) { 663 reportFatalError("MarkupEntityMismatch", null); 664 } 665 666 if (fDocumentHandler != null && !fScanningAttribute) { 668 if (!name.equals("[xml]")) { 669 fDocumentHandler.endGeneralEntity(name, augs); 670 } 671 } 672 673 } 675 679 681 682 protected Dispatcher createContentDispatcher() { 683 return new FragmentContentDispatcher(); 684 } 686 688 706 protected void scanXMLDeclOrTextDecl(boolean scanningTextDecl) 707 throws IOException , XNIException { 708 709 super.scanXMLDeclOrTextDecl(scanningTextDecl, fStrings); 711 fMarkupDepth--; 712 713 String version = fStrings[0]; 715 String encoding = fStrings[1]; 716 String standalone = fStrings[2]; 717 718 fStandalone = standalone != null && standalone.equals("yes"); 720 fEntityManager.setStandalone(fStandalone); 721 722 if (fDocumentHandler != null) { 724 if (scanningTextDecl) { 725 fDocumentHandler.textDecl(version, encoding, null); 726 } 727 else { 728 fDocumentHandler.xmlDecl(version, encoding, standalone, null); 729 } 730 } 731 732 if (encoding != null && !fEntityScanner.fCurrentEntity.isDeclaredEncoding()) { 734 fEntityScanner.setEncoding(encoding); 735 } 736 737 } 739 747 protected void scanPIData(String target, XMLString data) 748 throws IOException , XNIException { 749 750 super.scanPIData(target, data); 751 fMarkupDepth--; 752 753 if (fDocumentHandler != null) { 755 fDocumentHandler.processingInstruction(target, data, null); 756 } 757 758 } 760 769 protected void scanComment() throws IOException , XNIException { 770 771 scanComment(fStringBuffer); 772 fMarkupDepth--; 773 774 if (fDocumentHandler != null) { 776 fDocumentHandler.comment(fStringBuffer, null); 777 } 778 779 } 781 802 protected boolean scanStartElement() 803 throws IOException , XNIException { 804 if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanStartElement()"); 805 806 if (fNamespaces) { 808 fEntityScanner.scanQName(fElementQName); 809 } 810 else { 811 String name = fEntityScanner.scanName(); 812 fElementQName.setValues(null, name, name, null); 813 } 814 String rawname = fElementQName.rawname; 815 816 fCurrentElement = fElementStack.pushElement(fElementQName); 818 819 boolean empty = false; 821 fAttributes.removeAllAttributes(); 822 do { 823 boolean sawSpace = fEntityScanner.skipSpaces(); 825 826 int c = fEntityScanner.peekChar(); 828 if (c == '>') { 829 fEntityScanner.scanChar(); 830 break; 831 } 832 else if (c == '/') { 833 fEntityScanner.scanChar(); 834 if (!fEntityScanner.skipChar('>')) { 835 reportFatalError("ElementUnterminated", 836 new Object []{rawname}); 837 } 838 empty = true; 839 break; 840 } 841 else if (!isValidNameStartChar(c) || !sawSpace) { 842 if (!isValidNameStartHighSurrogate(c) || !sawSpace) { 845 reportFatalError("ElementUnterminated", 846 new Object [] { rawname }); 847 } 848 } 849 850 scanAttribute(fAttributes); 852 if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ 853 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 854 "ElementAttributeLimit", 855 new Object []{rawname, new Integer (fAttributes.getLength()) }, 856 XMLErrorReporter.SEVERITY_FATAL_ERROR ); 857 } 858 } while (true); 859 860 if (fDocumentHandler != null) { 862 if (empty) { 863 864 fMarkupDepth--; 866 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 868 reportFatalError("ElementEntityMismatch", 869 new Object []{fCurrentElement.rawname}); 870 } 871 872 fDocumentHandler.emptyElement(fElementQName, fAttributes, null); 873 874 fElementStack.popElement(fElementQName); 876 } 877 else { 878 fDocumentHandler.startElement(fElementQName, fAttributes, null); 879 } 880 } 881 882 if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanStartElement(): "+empty); 883 return empty; 884 885 } 887 892 protected void scanStartElementName () 893 throws IOException , XNIException { 894 if (fNamespaces) { 896 fEntityScanner.scanQName(fElementQName); 897 } 898 else { 899 String name = fEntityScanner.scanName(); 900 fElementQName.setValues(null, name, name, null); 901 } 902 fSawSpace = fEntityScanner.skipSpaces(); 905 } 907 913 protected boolean scanStartElementAfterName() 914 throws IOException , XNIException { 915 String rawname = fElementQName.rawname; 916 917 fCurrentElement = fElementStack.pushElement(fElementQName); 919 920 boolean empty = false; 922 fAttributes.removeAllAttributes(); 923 do { 924 925 int c = fEntityScanner.peekChar(); 927 if (c == '>') { 928 fEntityScanner.scanChar(); 929 break; 930 } 931 else if (c == '/') { 932 fEntityScanner.scanChar(); 933 if (!fEntityScanner.skipChar('>')) { 934 reportFatalError("ElementUnterminated", 935 new Object []{rawname}); 936 } 937 empty = true; 938 break; 939 } 940 else if (!isValidNameStartChar(c) || !fSawSpace) { 941 if (!isValidNameStartHighSurrogate(c) || !fSawSpace) { 944 reportFatalError("ElementUnterminated", 945 new Object [] { rawname }); 946 } 947 } 948 949 scanAttribute(fAttributes); 951 952 fSawSpace = fEntityScanner.skipSpaces(); 954 955 } while (true); 956 957 if (fDocumentHandler != null) { 959 if (empty) { 960 961 fMarkupDepth--; 963 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 965 reportFatalError("ElementEntityMismatch", 966 new Object []{fCurrentElement.rawname}); 967 } 968 969 fDocumentHandler.emptyElement(fElementQName, fAttributes, null); 970 971 fElementStack.popElement(fElementQName); 973 } 974 else { 975 fDocumentHandler.startElement(fElementQName, fAttributes, null); 976 } 977 } 978 979 if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanStartElementAfterName(): "+empty); 980 return empty; 981 } 983 1000 protected void scanAttribute(XMLAttributes attributes) 1001 throws IOException , XNIException { 1002 if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanAttribute()"); 1003 1004 if (fNamespaces) { 1006 fEntityScanner.scanQName(fAttributeQName); 1007 } 1008 else { 1009 String name = fEntityScanner.scanName(); 1010 fAttributeQName.setValues(null, name, name, null); 1011 } 1012 1013 fEntityScanner.skipSpaces(); 1015 if (!fEntityScanner.skipChar('=')) { 1016 reportFatalError("EqRequiredInAttribute", 1017 new Object []{fCurrentElement.rawname,fAttributeQName.rawname}); 1018 } 1019 fEntityScanner.skipSpaces(); 1020 1021 int oldLen = attributes.getLength(); 1023 int attrIndex = attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null); 1024 1025 if (oldLen == attributes.getLength()) { 1027 reportFatalError("AttributeNotUnique", 1028 new Object []{fCurrentElement.rawname, 1029 fAttributeQName.rawname}); 1030 } 1031 boolean isVC = fHasExternalDTD && !fStandalone; 1033 scanAttributeValue(fTempString, fTempString2, 1034 fAttributeQName.rawname, isVC, 1035 fCurrentElement.rawname); 1036 attributes.setValue(attrIndex, fTempString.toString()); 1037 attributes.setNonNormalizedValue(attrIndex, fTempString2.toString()); 1038 attributes.setSpecified(attrIndex, true); 1039 1040 if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanAttribute()"); 1041 } 1043 1048 protected int scanContent() throws IOException , XNIException { 1049 1050 XMLString content = fTempString; 1051 int c = fEntityScanner.scanContent(content); 1052 if (c == '\r') { 1053 fEntityScanner.scanChar(); 1055 fStringBuffer.clear(); 1056 fStringBuffer.append(fTempString); 1057 fStringBuffer.append((char)c); 1058 content = fStringBuffer; 1059 c = -1; 1060 } 1061 if (fDocumentHandler != null && content.length > 0) { 1062 fDocumentHandler.characters(content, null); 1063 } 1064 1065 if (c == ']' && fTempString.length == 0) { 1066 fStringBuffer.clear(); 1067 fStringBuffer.append((char)fEntityScanner.scanChar()); 1068 fInScanContent = true; 1072 if (fEntityScanner.skipChar(']')) { 1077 fStringBuffer.append(']'); 1078 while (fEntityScanner.skipChar(']')) { 1079 fStringBuffer.append(']'); 1080 } 1081 if (fEntityScanner.skipChar('>')) { 1082 reportFatalError("CDEndInContent", null); 1083 } 1084 } 1085 if (fDocumentHandler != null && fStringBuffer.length != 0) { 1086 fDocumentHandler.characters(fStringBuffer, null); 1087 } 1088 fInScanContent = false; 1089 c = -1; 1090 } 1091 return c; 1092 1093 } 1095 1096 1107 protected boolean scanCDATASection(boolean complete) 1108 throws IOException , XNIException { 1109 1110 if (fDocumentHandler != null) { 1112 fDocumentHandler.startCDATA(null); 1113 } 1114 1115 while (true) { 1116 fStringBuffer.clear(); 1117 if (!fEntityScanner.scanData("]]", fStringBuffer)) { 1118 if (fDocumentHandler != null && fStringBuffer.length > 0) { 1119 fDocumentHandler.characters(fStringBuffer, null); 1120 } 1121 int brackets = 0; 1122 while (fEntityScanner.skipChar(']')) { 1123 brackets++; 1124 } 1125 if (fDocumentHandler != null && brackets > 0) { 1126 fStringBuffer.clear(); 1127 if (brackets > XMLEntityManager.DEFAULT_BUFFER_SIZE) { 1128 int chunks = brackets / XMLEntityManager.DEFAULT_BUFFER_SIZE; 1130 int remainder = brackets % XMLEntityManager.DEFAULT_BUFFER_SIZE; 1131 for (int i = 0; i < XMLEntityManager.DEFAULT_BUFFER_SIZE; i++) { 1132 fStringBuffer.append(']'); 1133 } 1134 for (int i = 0; i < chunks; i++) { 1135 fDocumentHandler.characters(fStringBuffer, null); 1136 } 1137 if (remainder != 0) { 1138 fStringBuffer.length = remainder; 1139 fDocumentHandler.characters(fStringBuffer, null); 1140 } 1141 } 1142 else { 1143 for (int i = 0; i < brackets; i++) { 1144 fStringBuffer.append(']'); 1145 } 1146 fDocumentHandler.characters(fStringBuffer, null); 1147 } 1148 } 1149 if (fEntityScanner.skipChar('>')) { 1150 break; 1151 } 1152 if (fDocumentHandler != null) { 1153 fStringBuffer.clear(); 1154 fStringBuffer.append("]]"); 1155 fDocumentHandler.characters(fStringBuffer, null); 1156 } 1157 } 1158 else { 1159 if (fDocumentHandler != null) { 1160 fDocumentHandler.characters(fStringBuffer, null); 1161 } 1162 int c = fEntityScanner.peekChar(); 1163 if (c != -1 && isInvalidLiteral(c)) { 1164 if (XMLChar.isHighSurrogate(c)) { 1165 fStringBuffer.clear(); 1166 scanSurrogates(fStringBuffer); 1167 if (fDocumentHandler != null) { 1168 fDocumentHandler.characters(fStringBuffer, null); 1169 } 1170 } 1171 else { 1172 reportFatalError("InvalidCharInCDSect", 1173 new Object []{Integer.toString(c,16)}); 1174 fEntityScanner.scanChar(); 1175 } 1176 } 1177 } 1178 } 1179 fMarkupDepth--; 1180 1181 if (fDocumentHandler != null) { 1183 fDocumentHandler.endCDATA(null); 1184 } 1185 1186 return true; 1187 1188 } 1190 1204 protected int scanEndElement() throws IOException , XNIException { 1205 if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanEndElement()"); 1206 1207 fElementStack.popElement(fElementQName) ; 1208 1209 1214 1216 if (!fEntityScanner.skipString(fElementQName.rawname)) { 1219 reportFatalError("ETagRequired", new Object []{fElementQName.rawname}); 1220 } 1221 1222 fEntityScanner.skipSpaces(); 1224 if (!fEntityScanner.skipChar('>')) { 1225 reportFatalError("ETagUnterminated", 1226 new Object []{fElementQName.rawname}); 1227 } 1228 fMarkupDepth--; 1229 1230 fMarkupDepth--; 1232 1233 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 1235 reportFatalError("ElementEntityMismatch", 1236 new Object []{fCurrentElement.rawname}); 1237 } 1238 1239 if (fDocumentHandler != null ) { 1241 fDocumentHandler.endElement(fElementQName, null); 1242 } 1243 1244 return fMarkupDepth; 1245 1246 } 1248 1255 protected void scanCharReference() 1256 throws IOException , XNIException { 1257 1258 fStringBuffer2.clear(); 1259 int ch = scanCharReferenceValue(fStringBuffer2, null); 1260 fMarkupDepth--; 1261 if (ch != -1) { 1262 if (fDocumentHandler != null) { 1264 if (fNotifyCharRefs) { 1265 fDocumentHandler.startGeneralEntity(fCharRefLiteral, null, null, null); 1266 } 1267 Augmentations augs = null; 1268 if (fValidation && ch <= 0x20) { 1269 augs = new AugmentationsImpl(); 1270 augs.putItem(Constants.CHAR_REF_PROBABLE_WS, Boolean.TRUE); 1271 } 1272 fDocumentHandler.characters(fStringBuffer2, augs); 1273 if (fNotifyCharRefs) { 1274 fDocumentHandler.endGeneralEntity(fCharRefLiteral, null); 1275 } 1276 } 1277 } 1278 1279 } 1281 1288 protected void scanEntityReference() throws IOException , XNIException { 1289 1290 String name = fEntityScanner.scanName(); 1292 if (name == null) { 1293 reportFatalError("NameRequiredInReference", null); 1294 return; 1295 } 1296 1297 if (!fEntityScanner.skipChar(';')) { 1299 reportFatalError("SemicolonRequiredInReference", new Object []{name}); 1300 } 1301 fMarkupDepth--; 1302 1303 if (name == fAmpSymbol) { 1305 handleCharacter('&', fAmpSymbol); 1306 } 1307 else if (name == fLtSymbol) { 1308 handleCharacter('<', fLtSymbol); 1309 } 1310 else if (name == fGtSymbol) { 1311 handleCharacter('>', fGtSymbol); 1312 } 1313 else if (name == fQuotSymbol) { 1314 handleCharacter('"', fQuotSymbol); 1315 } 1316 else if (name == fAposSymbol) { 1317 handleCharacter('\'', fAposSymbol); 1318 } 1319 else if (fEntityManager.isUnparsedEntity(name)) { 1321 reportFatalError("ReferenceToUnparsedEntity", new Object []{name}); 1322 } 1323 else { 1324 if (!fEntityManager.isDeclaredEntity(name)) { 1325 if ( fHasExternalDTD && !fStandalone) { 1327 if (fValidation) 1328 fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,"EntityNotDeclared", 1329 new Object []{name}, XMLErrorReporter.SEVERITY_ERROR); 1330 } 1331 else 1332 reportFatalError("EntityNotDeclared", new Object []{name}); 1333 } 1334 fEntityManager.startEntity(name, false); 1335 } 1336 1337 } 1339 1341 1348 private void handleCharacter(char c, String entity) throws XNIException { 1349 if (fDocumentHandler != null) { 1350 if (fNotifyBuiltInRefs) { 1351 fDocumentHandler.startGeneralEntity(entity, null, null, null); 1352 } 1353 1354 fSingleChar[0] = c; 1355 fTempString.setValues(fSingleChar, 0, 1); 1356 fDocumentHandler.characters(fTempString, null); 1357 1358 if (fNotifyBuiltInRefs) { 1359 fDocumentHandler.endGeneralEntity(entity, null); 1360 } 1361 } 1362 } 1364 1381 protected int handleEndElement(QName element, boolean isEmpty) 1384 throws XNIException { 1385 1386 fMarkupDepth--; 1387 if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { 1389 reportFatalError("ElementEntityMismatch", 1390 new Object []{fCurrentElement.rawname}); 1391 } 1392 QName startElement = fQName; 1394 fElementStack.popElement(startElement); 1395 if (element.rawname != startElement.rawname) { 1396 reportFatalError("ETagRequired", 1397 new Object []{startElement.rawname}); 1398 } 1399 1400 if (fNamespaces) { 1402 element.uri = startElement.uri; 1403 } 1404 1405 if (fDocumentHandler != null && !isEmpty) { 1407 fDocumentHandler.endElement(element, null); 1408 } 1409 1410 return fMarkupDepth; 1411 1412 } 1414 1416 1421 protected final void setScannerState(int state) { 1422 1423 fScannerState = state; 1424 if (DEBUG_SCANNER_STATE) { 1425 System.out.print("### setScannerState: "); 1426 System.out.print(getScannerStateName(state)); 1427 System.out.println(); 1428 } 1429 1430 } 1432 1437 protected final void setDispatcher(Dispatcher dispatcher) { 1438 fDispatcher = dispatcher; 1439 if (DEBUG_DISPATCHER) { 1440 System.out.print("%%% setDispatcher: "); 1441 System.out.print(getDispatcherName(dispatcher)); 1442 System.out.println(); 1443 } 1444 } 1445 1446 1450 1451 protected String getScannerStateName(int state) { 1452 1453 switch (state) { 1454 case SCANNER_STATE_DOCTYPE: return "SCANNER_STATE_DOCTYPE"; 1455 case SCANNER_STATE_ROOT_ELEMENT: return "SCANNER_STATE_ROOT_ELEMENT"; 1456 case SCANNER_STATE_START_OF_MARKUP: return "SCANNER_STATE_START_OF_MARKUP"; 1457 case SCANNER_STATE_COMMENT: return "SCANNER_STATE_COMMENT"; 1458 case SCANNER_STATE_PI: return "SCANNER_STATE_PI"; 1459 case SCANNER_STATE_CONTENT: return "SCANNER_STATE_CONTENT"; 1460 case SCANNER_STATE_REFERENCE: return "SCANNER_STATE_REFERENCE"; 1461 case SCANNER_STATE_END_OF_INPUT: return "SCANNER_STATE_END_OF_INPUT"; 1462 case SCANNER_STATE_TERMINATED: return "SCANNER_STATE_TERMINATED"; 1463 case SCANNER_STATE_CDATA: return "SCANNER_STATE_CDATA"; 1464 case SCANNER_STATE_TEXT_DECL: return "SCANNER_STATE_TEXT_DECL"; 1465 } 1466 1467 return "??? ("+state+')'; 1468 1469 } 1471 1472 public String getDispatcherName(Dispatcher dispatcher) { 1473 1474 if (DEBUG_DISPATCHER) { 1475 if (dispatcher != null) { 1476 String name = dispatcher.getClass().getName(); 1477 int index = name.lastIndexOf('.'); 1478 if (index != -1) { 1479 name = name.substring(index + 1); 1480 index = name.lastIndexOf('$'); 1481 if (index != -1) { 1482 name = name.substring(index + 1); 1483 } 1484 } 1485 return name; 1486 } 1487 } 1488 return "null"; 1489 1490 } 1492 1496 1503 protected static class ElementStack { 1504 1505 1509 1510 protected QName[] fElements; 1511 1512 1513 protected int fSize; 1514 1515 1519 1520 public ElementStack() { 1521 fElements = new QName[10]; 1522 for (int i = 0; i < fElements.length; i++) { 1523 fElements[i] = new QName(); 1524 } 1525 } 1527 1531 1544 public QName pushElement(QName element) { 1545 if (fSize == fElements.length) { 1546 QName[] array = new QName[fElements.length * 2]; 1547 System.arraycopy(fElements, 0, array, 0, fSize); 1548 fElements = array; 1549 for (int i = fSize; i < fElements.length; i++) { 1550 fElements[i] = new QName(); 1551 } 1552 } 1553 fElements[fSize].setValues(element); 1554 return fElements[fSize++]; 1555 } 1557 1565 public void popElement(QName element) { 1566 element.setValues(fElements[--fSize]); 1567 } 1569 1570 public void clear() { 1571 fSize = 0; 1572 } 1574 } 1576 1583 protected interface Dispatcher { 1584 1585 1589 1601 public boolean dispatch(boolean complete) 1602 throws IOException , XNIException; 1603 1604 } 1606 1612 protected class FragmentContentDispatcher 1613 implements Dispatcher { 1614 1615 1619 1631 public boolean dispatch(boolean complete) 1632 throws IOException , XNIException { 1633 try { 1634 boolean again; 1635 do { 1636 again = false; 1637 switch (fScannerState) { 1638 case SCANNER_STATE_CONTENT: { 1639 if (fEntityScanner.skipChar('<')) { 1640 setScannerState(SCANNER_STATE_START_OF_MARKUP); 1641 again = true; 1642 } 1643 else if (fEntityScanner.skipChar('&')) { 1644 setScannerState(SCANNER_STATE_REFERENCE); 1645 again = true; 1646 } 1647 else { 1648 do { 1649 int c = scanContent(); 1650 if (c == '<') { 1651 fEntityScanner.scanChar(); 1652 setScannerState(SCANNER_STATE_START_OF_MARKUP); 1653 break; 1654 } 1655 else if (c == '&') { 1656 fEntityScanner.scanChar(); 1657 setScannerState(SCANNER_STATE_REFERENCE); 1658 break; 1659 } 1660 else if (c != -1 && isInvalidLiteral(c)) { 1661 if (XMLChar.isHighSurrogate(c)) { 1662 fStringBuffer.clear(); 1664 if (scanSurrogates(fStringBuffer)) { 1665 if (fDocumentHandler != null) { 1667 fDocumentHandler.characters(fStringBuffer, null); 1668 } 1669 } 1670 } 1671 else { 1672 reportFatalError("InvalidCharInContent", 1673 new Object [] { 1674 Integer.toString(c, 16)}); 1675 fEntityScanner.scanChar(); 1676 } 1677 } 1678 } while (complete); 1679 } 1680 break; 1681 } 1682 case SCANNER_STATE_START_OF_MARKUP: { 1683 fMarkupDepth++; 1684 if (fEntityScanner.skipChar('/')) { 1685 if (scanEndElement() == 0) { 1686 if (elementDepthIsZeroHook()) { 1687 return true; 1688 } 1689 } 1690 setScannerState(SCANNER_STATE_CONTENT); 1691 } 1692 else if (isValidNameStartChar(fEntityScanner.peekChar())) { 1693 scanStartElement(); 1694 setScannerState(SCANNER_STATE_CONTENT); 1695 } 1696 else if (fEntityScanner.skipChar('!')) { 1697 if (fEntityScanner.skipChar('-')) { 1698 if (!fEntityScanner.skipChar('-')) { 1699 reportFatalError("InvalidCommentStart", 1700 null); 1701 } 1702 setScannerState(SCANNER_STATE_COMMENT); 1703 again = true; 1704 } 1705 else if (fEntityScanner.skipString("[CDATA[")) { 1706 setScannerState(SCANNER_STATE_CDATA); 1707 again = true; 1708 } 1709 else if (!scanForDoctypeHook()) { 1710 reportFatalError("MarkupNotRecognizedInContent", 1711 null); 1712 } 1713 } 1714 else if (fEntityScanner.skipChar('?')) { 1715 setScannerState(SCANNER_STATE_PI); 1716 again = true; 1717 } 1718 else if (isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { 1719 scanStartElement(); 1720 setScannerState(SCANNER_STATE_CONTENT); 1721 } 1722 else { 1723 reportFatalError("MarkupNotRecognizedInContent", 1724 null); 1725 setScannerState(SCANNER_STATE_CONTENT); 1726 } 1727 break; 1728 } 1729 case SCANNER_STATE_COMMENT: { 1730 scanComment(); 1731 setScannerState(SCANNER_STATE_CONTENT); 1732 break; 1733 } 1734 case SCANNER_STATE_PI: { 1735 scanPI(); 1736 setScannerState(SCANNER_STATE_CONTENT); 1737 break; 1738 } 1739 case SCANNER_STATE_CDATA: { 1740 scanCDATASection(complete); 1741 setScannerState(SCANNER_STATE_CONTENT); 1742 break; 1743 } 1744 case SCANNER_STATE_REFERENCE: { 1745 fMarkupDepth++; 1746 setScannerState(SCANNER_STATE_CONTENT); 1752 if (fEntityScanner.skipChar('#')) { 1753 scanCharReference(); 1754 } 1755 else { 1756 scanEntityReference(); 1757 } 1758 break; 1759 } 1760 case SCANNER_STATE_TEXT_DECL: { 1761 if (fEntityScanner.skipString("<?xml")) { 1763 fMarkupDepth++; 1764 if (isValidNameChar(fEntityScanner.peekChar())) { 1767 fStringBuffer.clear(); 1768 fStringBuffer.append("xml"); 1769 if (fNamespaces) { 1770 while (isValidNCName(fEntityScanner.peekChar())) { 1771 fStringBuffer.append((char)fEntityScanner.scanChar()); 1772 } 1773 } 1774 else { 1775 while (isValidNameChar(fEntityScanner.peekChar())) { 1776 fStringBuffer.append((char)fEntityScanner.scanChar()); 1777 } 1778 } 1779 String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length); 1780 scanPIData(target, fTempString); 1781 } 1782 1783 else { 1785 scanXMLDeclOrTextDecl(true); 1786 } 1787 } 1788 fEntityManager.fCurrentEntity.mayReadChunks = true; 1790 setScannerState(SCANNER_STATE_CONTENT); 1791 break; 1792 } 1793 case SCANNER_STATE_ROOT_ELEMENT: { 1794 if (scanRootElementHook()) { 1795 return true; 1796 } 1797 setScannerState(SCANNER_STATE_CONTENT); 1798 break; 1799 } 1800 case SCANNER_STATE_DOCTYPE: { 1801 reportFatalError("DoctypeIllegalInContent", 1802 null); 1803 setScannerState(SCANNER_STATE_CONTENT); 1804 } 1805 } 1806 } while (complete || again); 1807 } 1808 catch (MalformedByteSequenceException e) { 1810 fErrorReporter.reportError(e.getDomain(), e.getKey(), 1811 e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR); 1812 return false; 1813 } 1814 catch (CharConversionException e) { 1815 reportFatalError("CharConversionFailure", null); 1816 return false; 1817 } 1818 catch (EOFException e) { 1820 endOfFileHook(e); 1821 return false; 1822 } 1823 1824 return true; 1825 1826 } 1828 1832 1834 1837 1845 protected boolean scanForDoctypeHook() 1846 throws IOException , XNIException { 1847 return false; 1848 } 1850 1863 protected boolean elementDepthIsZeroHook() 1864 throws IOException , XNIException { 1865 return false; 1866 } 1868 1880 protected boolean scanRootElementHook() 1881 throws IOException , XNIException { 1882 return false; 1883 } 1885 1892 protected void endOfFileHook(EOFException e) 1893 throws IOException , XNIException { 1894 1895 if (fMarkupDepth != 0) { 1898 reportFatalError("PrematureEOF", null); 1899 } 1900 1901 } 1903 } 1905} | Popular Tags |