0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package org.apache.xerces.impl;
0019:
0020: import java.io.CharConversionException;
0021: import java.io.EOFException;
0022: import java.io.IOException;
0023:
0024: import org.apache.xerces.impl.dtd.XMLDTDDescription;
0025: import org.apache.xerces.impl.io.MalformedByteSequenceException;
0026: import org.apache.xerces.impl.msg.XMLMessageFormatter;
0027: import org.apache.xerces.impl.validation.ValidationManager;
0028: import org.apache.xerces.util.NamespaceSupport;
0029: import org.apache.xerces.util.XMLChar;
0030: import org.apache.xerces.util.XMLStringBuffer;
0031: import org.apache.xerces.xni.Augmentations;
0032: import org.apache.xerces.xni.NamespaceContext;
0033: import org.apache.xerces.xni.XMLResourceIdentifier;
0034: import org.apache.xerces.xni.XMLString;
0035: import org.apache.xerces.xni.XNIException;
0036: import org.apache.xerces.xni.parser.XMLComponentManager;
0037: import org.apache.xerces.xni.parser.XMLConfigurationException;
0038: import org.apache.xerces.xni.parser.XMLDTDScanner;
0039: import org.apache.xerces.xni.parser.XMLInputSource;
0040:
0041: /**
0042: * This class is responsible for scanning XML document structure
0043: * and content. The scanner acts as the source for the document
0044: * information which is communicated to the document handler.
0045: * <p>
0046: * This component requires the following features and properties from the
0047: * component manager that uses it:
0048: * <ul>
0049: * <li>http://xml.org/sax/features/namespaces</li>
0050: * <li>http://xml.org/sax/features/validation</li>
0051: * <li>http://apache.org/xml/features/nonvalidating/load-external-dtd</li>
0052: * <li>http://apache.org/xml/features/scanner/notify-char-refs</li>
0053: * <li>http://apache.org/xml/features/scanner/notify-builtin-refs</li>
0054: * <li>http://apache.org/xml/properties/internal/symbol-table</li>
0055: * <li>http://apache.org/xml/properties/internal/error-reporter</li>
0056: * <li>http://apache.org/xml/properties/internal/entity-manager</li>
0057: * <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
0058: * </ul>
0059: *
0060: * @xerces.internal
0061: *
0062: * @author Glenn Marcy, IBM
0063: * @author Andy Clark, IBM
0064: * @author Arnaud Le Hors, IBM
0065: * @author Eric Ye, IBM
0066: *
0067: * @version $Id: XMLDocumentScannerImpl.java 572055 2007-09-02 17:55:43Z mrglavas $
0068: */
0069: public class XMLDocumentScannerImpl extends
0070: XMLDocumentFragmentScannerImpl {
0071:
0072: //
0073: // Constants
0074: //
0075:
0076: // scanner states
0077:
0078: /** Scanner state: XML declaration. */
0079: protected static final int SCANNER_STATE_XML_DECL = 0;
0080:
0081: /** Scanner state: prolog. */
0082: protected static final int SCANNER_STATE_PROLOG = 5;
0083:
0084: /** Scanner state: trailing misc. */
0085: protected static final int SCANNER_STATE_TRAILING_MISC = 12;
0086:
0087: /** Scanner state: DTD internal declarations. */
0088: protected static final int SCANNER_STATE_DTD_INTERNAL_DECLS = 17;
0089:
0090: /** Scanner state: open DTD external subset. */
0091: protected static final int SCANNER_STATE_DTD_EXTERNAL = 18;
0092:
0093: /** Scanner state: DTD external declarations. */
0094: protected static final int SCANNER_STATE_DTD_EXTERNAL_DECLS = 19;
0095:
0096: // feature identifiers
0097:
0098: /** Feature identifier: load external DTD. */
0099: protected static final String LOAD_EXTERNAL_DTD = Constants.XERCES_FEATURE_PREFIX
0100: + Constants.LOAD_EXTERNAL_DTD_FEATURE;
0101:
0102: /** Feature identifier: load external DTD. */
0103: protected static final String DISALLOW_DOCTYPE_DECL_FEATURE = Constants.XERCES_FEATURE_PREFIX
0104: + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
0105:
0106: // property identifiers
0107:
0108: /** Property identifier: DTD scanner. */
0109: protected static final String DTD_SCANNER = Constants.XERCES_PROPERTY_PREFIX
0110: + Constants.DTD_SCANNER_PROPERTY;
0111:
0112: /** property identifier: ValidationManager */
0113: protected static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0114: + Constants.VALIDATION_MANAGER_PROPERTY;
0115:
0116: /** property identifier: NamespaceContext */
0117: protected static final String NAMESPACE_CONTEXT = Constants.XERCES_PROPERTY_PREFIX
0118: + Constants.NAMESPACE_CONTEXT_PROPERTY;
0119:
0120: // recognized features and properties
0121:
0122: /** Recognized features. */
0123: private static final String[] RECOGNIZED_FEATURES = {
0124: LOAD_EXTERNAL_DTD, DISALLOW_DOCTYPE_DECL_FEATURE, };
0125:
0126: /** Feature defaults. */
0127: private static final Boolean[] FEATURE_DEFAULTS = { Boolean.TRUE,
0128: Boolean.FALSE, };
0129:
0130: /** Recognized properties. */
0131: private static final String[] RECOGNIZED_PROPERTIES = {
0132: DTD_SCANNER, VALIDATION_MANAGER, NAMESPACE_CONTEXT, };
0133:
0134: /** Property defaults. */
0135: private static final Object[] PROPERTY_DEFAULTS = { null, null,
0136: null, };
0137:
0138: //
0139: // Data
0140: //
0141:
0142: // properties
0143:
0144: /** DTD scanner. */
0145: protected XMLDTDScanner fDTDScanner;
0146: /** Validation manager . */
0147: protected ValidationManager fValidationManager;
0148:
0149: // protected data
0150:
0151: /** Scanning DTD. */
0152: protected boolean fScanningDTD;
0153:
0154: // other info
0155:
0156: /** Doctype name. */
0157: protected String fDoctypeName;
0158:
0159: /** Doctype declaration public identifier. */
0160: protected String fDoctypePublicId;
0161:
0162: /** Doctype declaration system identifier. */
0163: protected String fDoctypeSystemId;
0164:
0165: /** Namespace support. */
0166: protected NamespaceContext fNamespaceContext = new NamespaceSupport();
0167:
0168: // features
0169:
0170: /** Load external DTD. */
0171: protected boolean fLoadExternalDTD = true;
0172:
0173: /** Disallow doctype declaration. */
0174: protected boolean fDisallowDoctype = false;
0175:
0176: // state
0177:
0178: /** Seen doctype declaration. */
0179: protected boolean fSeenDoctypeDecl;
0180:
0181: // dispatchers
0182:
0183: /** XML declaration dispatcher. */
0184: protected final Dispatcher fXMLDeclDispatcher = new XMLDeclDispatcher();
0185:
0186: /** Prolog dispatcher. */
0187: protected final Dispatcher fPrologDispatcher = new PrologDispatcher();
0188:
0189: /** DTD dispatcher. */
0190: protected final Dispatcher fDTDDispatcher = new DTDDispatcher();
0191:
0192: /** Trailing miscellaneous section dispatcher. */
0193: protected final Dispatcher fTrailingMiscDispatcher = new TrailingMiscDispatcher();
0194:
0195: // temporary variables
0196:
0197: /** Array of 3 strings. */
0198: private final String[] fStrings = new String[3];
0199:
0200: /** String. */
0201: private final XMLString fString = new XMLString();
0202:
0203: /** String buffer. */
0204: private final XMLStringBuffer fStringBuffer = new XMLStringBuffer();
0205:
0206: /** External subset source. */
0207: private XMLInputSource fExternalSubsetSource = null;
0208:
0209: /** A DTD Description. */
0210: private final XMLDTDDescription fDTDDescription = new XMLDTDDescription(
0211: null, null, null, null, null);
0212:
0213: //
0214: // Constructors
0215: //
0216:
0217: /** Default constructor. */
0218: public XMLDocumentScannerImpl() {
0219: } // <init>()
0220:
0221: //
0222: // XMLDocumentScanner methods
0223: //
0224:
0225: /**
0226: * Sets the input source.
0227: *
0228: * @param inputSource The input source.
0229: *
0230: * @throws IOException Thrown on i/o error.
0231: */
0232: public void setInputSource(XMLInputSource inputSource)
0233: throws IOException {
0234: fEntityManager.setEntityHandler(this );
0235: fEntityManager.startDocumentEntity(inputSource);
0236: //fDocumentSystemId = fEntityManager.expandSystemId(inputSource.getSystemId());
0237: } // setInputSource(XMLInputSource)
0238:
0239: //
0240: // XMLComponent methods
0241: //
0242:
0243: /**
0244: * Resets the component. The component can query the component manager
0245: * about any features and properties that affect the operation of the
0246: * component.
0247: *
0248: * @param componentManager The component manager.
0249: *
0250: * @throws SAXException Thrown by component on initialization error.
0251: * For example, if a feature or property is
0252: * required for the operation of the component, the
0253: * component manager may throw a
0254: * SAXNotRecognizedException or a
0255: * SAXNotSupportedException.
0256: */
0257: public void reset(XMLComponentManager componentManager)
0258: throws XMLConfigurationException {
0259:
0260: super .reset(componentManager);
0261:
0262: // other settings
0263: fDoctypeName = null;
0264: fDoctypePublicId = null;
0265: fDoctypeSystemId = null;
0266: fSeenDoctypeDecl = false;
0267: fScanningDTD = false;
0268: fExternalSubsetSource = null;
0269:
0270: if (!fParserSettings) {
0271: // parser settings have not been changed
0272: fNamespaceContext.reset();
0273: // setup dispatcher
0274: setScannerState(SCANNER_STATE_XML_DECL);
0275: setDispatcher(fXMLDeclDispatcher);
0276: return;
0277: }
0278:
0279: // xerces features
0280: try {
0281: fLoadExternalDTD = componentManager
0282: .getFeature(LOAD_EXTERNAL_DTD);
0283: } catch (XMLConfigurationException e) {
0284: fLoadExternalDTD = true;
0285: }
0286: try {
0287: fDisallowDoctype = componentManager
0288: .getFeature(DISALLOW_DOCTYPE_DECL_FEATURE);
0289: } catch (XMLConfigurationException e) {
0290: fDisallowDoctype = false;
0291: }
0292:
0293: // xerces properties
0294: fDTDScanner = (XMLDTDScanner) componentManager
0295: .getProperty(DTD_SCANNER);
0296: try {
0297: fValidationManager = (ValidationManager) componentManager
0298: .getProperty(VALIDATION_MANAGER);
0299: } catch (XMLConfigurationException e) {
0300: fValidationManager = null;
0301: }
0302:
0303: try {
0304: fNamespaceContext = (NamespaceContext) componentManager
0305: .getProperty(NAMESPACE_CONTEXT);
0306: } catch (XMLConfigurationException e) {
0307: }
0308: if (fNamespaceContext == null) {
0309: fNamespaceContext = new NamespaceSupport();
0310: }
0311: fNamespaceContext.reset();
0312:
0313: // setup dispatcher
0314: setScannerState(SCANNER_STATE_XML_DECL);
0315: setDispatcher(fXMLDeclDispatcher);
0316:
0317: } // reset(XMLComponentManager)
0318:
0319: /**
0320: * Returns a list of feature identifiers that are recognized by
0321: * this component. This method may return null if no features
0322: * are recognized by this component.
0323: */
0324: public String[] getRecognizedFeatures() {
0325: String[] featureIds = super .getRecognizedFeatures();
0326: int length = featureIds != null ? featureIds.length : 0;
0327: String[] combinedFeatureIds = new String[length
0328: + RECOGNIZED_FEATURES.length];
0329: if (featureIds != null) {
0330: System.arraycopy(featureIds, 0, combinedFeatureIds, 0,
0331: featureIds.length);
0332: }
0333: System.arraycopy(RECOGNIZED_FEATURES, 0, combinedFeatureIds,
0334: length, RECOGNIZED_FEATURES.length);
0335: return combinedFeatureIds;
0336: } // getRecognizedFeatures():String[]
0337:
0338: /**
0339: * Sets the state of a feature. This method is called by the component
0340: * manager any time after reset when a feature changes state.
0341: * <p>
0342: * <strong>Note:</strong> Components should silently ignore features
0343: * that do not affect the operation of the component.
0344: *
0345: * @param featureId The feature identifier.
0346: * @param state The state of the feature.
0347: *
0348: * @throws SAXNotRecognizedException The component should not throw
0349: * this exception.
0350: * @throws SAXNotSupportedException The component should not throw
0351: * this exception.
0352: */
0353: public void setFeature(String featureId, boolean state)
0354: throws XMLConfigurationException {
0355:
0356: super .setFeature(featureId, state);
0357:
0358: // Xerces properties
0359: if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
0360: final int suffixLength = featureId.length()
0361: - Constants.XERCES_FEATURE_PREFIX.length();
0362:
0363: if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE
0364: .length()
0365: && featureId
0366: .endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
0367: fLoadExternalDTD = state;
0368: return;
0369: } else if (suffixLength == Constants.DISALLOW_DOCTYPE_DECL_FEATURE
0370: .length()
0371: && featureId
0372: .endsWith(Constants.DISALLOW_DOCTYPE_DECL_FEATURE)) {
0373: fDisallowDoctype = state;
0374: return;
0375: }
0376: }
0377:
0378: } // setFeature(String,boolean)
0379:
0380: /**
0381: * Returns a list of property identifiers that are recognized by
0382: * this component. This method may return null if no properties
0383: * are recognized by this component.
0384: */
0385: public String[] getRecognizedProperties() {
0386: String[] propertyIds = super .getRecognizedProperties();
0387: int length = propertyIds != null ? propertyIds.length : 0;
0388: String[] combinedPropertyIds = new String[length
0389: + RECOGNIZED_PROPERTIES.length];
0390: if (propertyIds != null) {
0391: System.arraycopy(propertyIds, 0, combinedPropertyIds, 0,
0392: propertyIds.length);
0393: }
0394: System.arraycopy(RECOGNIZED_PROPERTIES, 0, combinedPropertyIds,
0395: length, RECOGNIZED_PROPERTIES.length);
0396: return combinedPropertyIds;
0397: } // getRecognizedProperties():String[]
0398:
0399: /**
0400: * Sets the value of a property. This method is called by the component
0401: * manager any time after reset when a property changes value.
0402: * <p>
0403: * <strong>Note:</strong> Components should silently ignore properties
0404: * that do not affect the operation of the component.
0405: *
0406: * @param propertyId The property identifier.
0407: * @param value The value of the property.
0408: *
0409: * @throws SAXNotRecognizedException The component should not throw
0410: * this exception.
0411: * @throws SAXNotSupportedException The component should not throw
0412: * this exception.
0413: */
0414: public void setProperty(String propertyId, Object value)
0415: throws XMLConfigurationException {
0416:
0417: super .setProperty(propertyId, value);
0418:
0419: // Xerces properties
0420: if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
0421: final int suffixLength = propertyId.length()
0422: - Constants.XERCES_PROPERTY_PREFIX.length();
0423:
0424: if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length()
0425: && propertyId
0426: .endsWith(Constants.DTD_SCANNER_PROPERTY)) {
0427: fDTDScanner = (XMLDTDScanner) value;
0428: }
0429: if (suffixLength == Constants.NAMESPACE_CONTEXT_PROPERTY
0430: .length()
0431: && propertyId
0432: .endsWith(Constants.NAMESPACE_CONTEXT_PROPERTY)) {
0433: if (value != null) {
0434: fNamespaceContext = (NamespaceContext) value;
0435: }
0436: }
0437:
0438: return;
0439: }
0440:
0441: } // setProperty(String,Object)
0442:
0443: /**
0444: * Returns the default state for a feature, or null if this
0445: * component does not want to report a default value for this
0446: * feature.
0447: *
0448: * @param featureId The feature identifier.
0449: *
0450: * @since Xerces 2.2.0
0451: */
0452: public Boolean getFeatureDefault(String featureId) {
0453:
0454: for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
0455: if (RECOGNIZED_FEATURES[i].equals(featureId)) {
0456: return FEATURE_DEFAULTS[i];
0457: }
0458: }
0459: return super .getFeatureDefault(featureId);
0460: } // getFeatureDefault(String):Boolean
0461:
0462: /**
0463: * Returns the default state for a property, or null if this
0464: * component does not want to report a default value for this
0465: * property.
0466: *
0467: * @param propertyId The property identifier.
0468: *
0469: * @since Xerces 2.2.0
0470: */
0471: public Object getPropertyDefault(String propertyId) {
0472: for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
0473: if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
0474: return PROPERTY_DEFAULTS[i];
0475: }
0476: }
0477: return super .getPropertyDefault(propertyId);
0478: } // getPropertyDefault(String):Object
0479:
0480: //
0481: // XMLEntityHandler methods
0482: //
0483:
0484: /**
0485: * This method notifies of the start of an entity. The DTD has the
0486: * pseudo-name of "[dtd]" parameter entity names start with '%'; and
0487: * general entities are just specified by their name.
0488: *
0489: * @param name The name of the entity.
0490: * @param identifier The resource identifier.
0491: * @param encoding The auto-detected IANA encoding name of the entity
0492: * stream. This value will be null in those situations
0493: * where the entity encoding is not auto-detected (e.g.
0494: * internal entities or a document entity that is
0495: * parsed from a java.io.Reader).
0496: *
0497: * @throws XNIException Thrown by handler to signal an error.
0498: */
0499: public void startEntity(String name,
0500: XMLResourceIdentifier identifier, String encoding,
0501: Augmentations augs) throws XNIException {
0502:
0503: super .startEntity(name, identifier, encoding, augs);
0504:
0505: // prepare to look for a TextDecl if external general entity
0506: if (!name.equals("[xml]") && fEntityScanner.isExternal()) {
0507: setScannerState(SCANNER_STATE_TEXT_DECL);
0508: }
0509:
0510: // call handler
0511: if (fDocumentHandler != null && name.equals("[xml]")) {
0512: fDocumentHandler.startDocument(fEntityScanner, encoding,
0513: fNamespaceContext, null);
0514: }
0515:
0516: } // startEntity(String,identifier,String)
0517:
0518: /**
0519: * This method notifies the end of an entity. The DTD has the pseudo-name
0520: * of "[dtd]" parameter entity names start with '%'; and general entities
0521: * are just specified by their name.
0522: *
0523: * @param name The name of the entity.
0524: *
0525: * @throws XNIException Thrown by handler to signal an error.
0526: */
0527: public void endEntity(String name, Augmentations augs)
0528: throws XNIException {
0529:
0530: super .endEntity(name, augs);
0531:
0532: // call handler
0533: if (fDocumentHandler != null && name.equals("[xml]")) {
0534: fDocumentHandler.endDocument(null);
0535: }
0536:
0537: } // endEntity(String)
0538:
0539: //
0540: // Protected methods
0541: //
0542:
0543: // dispatcher factory methods
0544:
0545: /** Creates a content dispatcher. */
0546: protected Dispatcher createContentDispatcher() {
0547: return new ContentDispatcher();
0548: } // createContentDispatcher():Dispatcher
0549:
0550: // scanning methods
0551:
0552: /** Scans a doctype declaration. */
0553: protected boolean scanDoctypeDecl() throws IOException,
0554: XNIException {
0555:
0556: // spaces
0557: if (!fEntityScanner.skipSpaces()) {
0558: reportFatalError(
0559: "MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL",
0560: null);
0561: }
0562:
0563: // root element name
0564: fDoctypeName = fEntityScanner.scanName();
0565: if (fDoctypeName == null) {
0566: reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null);
0567: }
0568:
0569: // external id
0570: if (fEntityScanner.skipSpaces()) {
0571: scanExternalID(fStrings, false);
0572: fDoctypeSystemId = fStrings[0];
0573: fDoctypePublicId = fStrings[1];
0574: fEntityScanner.skipSpaces();
0575: }
0576:
0577: fHasExternalDTD = fDoctypeSystemId != null;
0578:
0579: // Attempt to locate an external subset with an external subset resolver.
0580: if (!fHasExternalDTD && fExternalSubsetResolver != null) {
0581: fDTDDescription.setValues(null, null, fEntityManager
0582: .getCurrentResourceIdentifier()
0583: .getExpandedSystemId(), null);
0584: fDTDDescription.setRootName(fDoctypeName);
0585: fExternalSubsetSource = fExternalSubsetResolver
0586: .getExternalSubset(fDTDDescription);
0587: fHasExternalDTD = fExternalSubsetSource != null;
0588: }
0589:
0590: // call handler
0591: if (fDocumentHandler != null) {
0592: // NOTE: I don't like calling the doctypeDecl callback until
0593: // end of the *full* doctype line (including internal
0594: // subset) is parsed correctly but SAX2 requires that
0595: // it knows the root element name and public and system
0596: // identifier for the startDTD call. -Ac
0597: if (fExternalSubsetSource == null) {
0598: fDocumentHandler.doctypeDecl(fDoctypeName,
0599: fDoctypePublicId, fDoctypeSystemId, null);
0600: } else {
0601: fDocumentHandler.doctypeDecl(fDoctypeName,
0602: fExternalSubsetSource.getPublicId(),
0603: fExternalSubsetSource.getSystemId(), null);
0604: }
0605: }
0606:
0607: // is there an internal subset?
0608: boolean internalSubset = true;
0609: if (!fEntityScanner.skipChar('[')) {
0610: internalSubset = false;
0611: fEntityScanner.skipSpaces();
0612: if (!fEntityScanner.skipChar('>')) {
0613: reportFatalError("DoctypedeclUnterminated",
0614: new Object[] { fDoctypeName });
0615: }
0616: fMarkupDepth--;
0617: }
0618:
0619: return internalSubset;
0620:
0621: } // scanDoctypeDecl():boolean
0622:
0623: //
0624: // Private methods
0625: //
0626:
0627: /** Returns the scanner state name. */
0628: protected String getScannerStateName(int state) {
0629:
0630: switch (state) {
0631: case SCANNER_STATE_XML_DECL:
0632: return "SCANNER_STATE_XML_DECL";
0633: case SCANNER_STATE_PROLOG:
0634: return "SCANNER_STATE_PROLOG";
0635: case SCANNER_STATE_TRAILING_MISC:
0636: return "SCANNER_STATE_TRAILING_MISC";
0637: case SCANNER_STATE_DTD_INTERNAL_DECLS:
0638: return "SCANNER_STATE_DTD_INTERNAL_DECLS";
0639: case SCANNER_STATE_DTD_EXTERNAL:
0640: return "SCANNER_STATE_DTD_EXTERNAL";
0641: case SCANNER_STATE_DTD_EXTERNAL_DECLS:
0642: return "SCANNER_STATE_DTD_EXTERNAL_DECLS";
0643: }
0644: return super .getScannerStateName(state);
0645:
0646: } // getScannerStateName(int):String
0647:
0648: //
0649: // Classes
0650: //
0651:
0652: /**
0653: * Dispatcher to handle XMLDecl scanning.
0654: *
0655: * @author Andy Clark, IBM
0656: */
0657: protected final class XMLDeclDispatcher implements Dispatcher {
0658:
0659: //
0660: // Dispatcher methods
0661: //
0662:
0663: /**
0664: * Dispatch an XML "event".
0665: *
0666: * @param complete True if this dispatcher is intended to scan
0667: * and dispatch as much as possible.
0668: *
0669: * @return True if there is more to dispatch either from this
0670: * or a another dispatcher.
0671: *
0672: * @throws IOException Thrown on i/o error.
0673: * @throws XNIException Thrown on parse error.
0674: */
0675: public boolean dispatch(boolean complete) throws IOException,
0676: XNIException {
0677:
0678: // next dispatcher is prolog regardless of whether there
0679: // is an XMLDecl in this document
0680: setScannerState(SCANNER_STATE_PROLOG);
0681: setDispatcher(fPrologDispatcher);
0682:
0683: // scan XMLDecl
0684: try {
0685: if (fEntityScanner.skipString("<?xml")) {
0686: fMarkupDepth++;
0687: // NOTE: special case where document starts with a PI
0688: // whose name starts with "xml" (e.g. "xmlfoo")
0689: if (XMLChar.isName(fEntityScanner.peekChar())) {
0690: fStringBuffer.clear();
0691: fStringBuffer.append("xml");
0692: if (fNamespaces) {
0693: while (XMLChar.isNCName(fEntityScanner
0694: .peekChar())) {
0695: fStringBuffer
0696: .append((char) fEntityScanner
0697: .scanChar());
0698: }
0699: } else {
0700: while (XMLChar.isName(fEntityScanner
0701: .peekChar())) {
0702: fStringBuffer
0703: .append((char) fEntityScanner
0704: .scanChar());
0705: }
0706: }
0707: String target = fSymbolTable.addSymbol(
0708: fStringBuffer.ch, fStringBuffer.offset,
0709: fStringBuffer.length);
0710: scanPIData(target, fString);
0711: }
0712:
0713: // standard XML declaration
0714: else {
0715: scanXMLDeclOrTextDecl(false);
0716: }
0717: }
0718: fEntityManager.fCurrentEntity.mayReadChunks = true;
0719:
0720: // if no XMLDecl, then scan piece of prolog
0721: return true;
0722: }
0723: // encoding errors
0724: catch (MalformedByteSequenceException e) {
0725: fErrorReporter.reportError(e.getDomain(), e.getKey(), e
0726: .getArguments(),
0727: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0728: return false;
0729: } catch (CharConversionException e) {
0730: fErrorReporter.reportError(
0731: XMLMessageFormatter.XML_DOMAIN,
0732: "CharConversionFailure", null,
0733: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0734: return false;
0735: }
0736: // premature end of file
0737: catch (EOFException e) {
0738: reportFatalError("PrematureEOF", null);
0739: return false;
0740: //throw e;
0741: }
0742:
0743: } // dispatch(boolean):boolean
0744:
0745: } // class XMLDeclDispatcher
0746:
0747: /**
0748: * Dispatcher to handle prolog scanning.
0749: *
0750: * @author Andy Clark, IBM
0751: */
0752: protected final class PrologDispatcher implements Dispatcher {
0753:
0754: //
0755: // Dispatcher methods
0756: //
0757:
0758: /**
0759: * Dispatch an XML "event".
0760: *
0761: * @param complete True if this dispatcher is intended to scan
0762: * and dispatch as much as possible.
0763: *
0764: * @return True if there is more to dispatch either from this
0765: * or a another dispatcher.
0766: *
0767: * @throws IOException Thrown on i/o error.
0768: * @throws XNIException Thrown on parse error.
0769: */
0770: public boolean dispatch(boolean complete) throws IOException,
0771: XNIException {
0772:
0773: try {
0774: boolean again;
0775: do {
0776: again = false;
0777: switch (fScannerState) {
0778: case SCANNER_STATE_PROLOG: {
0779: fEntityScanner.skipSpaces();
0780: if (fEntityScanner.skipChar('<')) {
0781: setScannerState(SCANNER_STATE_START_OF_MARKUP);
0782: again = true;
0783: } else if (fEntityScanner.skipChar('&')) {
0784: setScannerState(SCANNER_STATE_REFERENCE);
0785: again = true;
0786: } else {
0787: setScannerState(SCANNER_STATE_CONTENT);
0788: again = true;
0789: }
0790: break;
0791: }
0792: case SCANNER_STATE_START_OF_MARKUP: {
0793: fMarkupDepth++;
0794: if (fEntityScanner.skipChar('!')) {
0795: if (fEntityScanner.skipChar('-')) {
0796: if (!fEntityScanner.skipChar('-')) {
0797: reportFatalError(
0798: "InvalidCommentStart", null);
0799: }
0800: setScannerState(SCANNER_STATE_COMMENT);
0801: again = true;
0802: } else if (fEntityScanner
0803: .skipString("DOCTYPE")) {
0804: setScannerState(SCANNER_STATE_DOCTYPE);
0805: again = true;
0806: } else {
0807: reportFatalError(
0808: "MarkupNotRecognizedInProlog",
0809: null);
0810: }
0811: } else if (isValidNameStartChar(fEntityScanner
0812: .peekChar())) {
0813: setScannerState(SCANNER_STATE_ROOT_ELEMENT);
0814: setDispatcher(fContentDispatcher);
0815: return true;
0816: } else if (fEntityScanner.skipChar('?')) {
0817: setScannerState(SCANNER_STATE_PI);
0818: again = true;
0819: } else if (isValidNameStartHighSurrogate(fEntityScanner
0820: .peekChar())) {
0821: setScannerState(SCANNER_STATE_ROOT_ELEMENT);
0822: setDispatcher(fContentDispatcher);
0823: return true;
0824: } else {
0825: reportFatalError(
0826: "MarkupNotRecognizedInProlog", null);
0827: }
0828: break;
0829: }
0830: case SCANNER_STATE_COMMENT: {
0831: scanComment();
0832: setScannerState(SCANNER_STATE_PROLOG);
0833: break;
0834: }
0835: case SCANNER_STATE_PI: {
0836: scanPI();
0837: setScannerState(SCANNER_STATE_PROLOG);
0838: break;
0839: }
0840: case SCANNER_STATE_DOCTYPE: {
0841: if (fDisallowDoctype) {
0842: reportFatalError("DoctypeNotAllowed", null);
0843: }
0844: if (fSeenDoctypeDecl) {
0845: reportFatalError("AlreadySeenDoctype", null);
0846: }
0847: fSeenDoctypeDecl = true;
0848:
0849: // scanDoctypeDecl() sends XNI doctypeDecl event that
0850: // in SAX is converted to startDTD() event.
0851: if (scanDoctypeDecl()) {
0852: setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS);
0853: setDispatcher(fDTDDispatcher);
0854: return true;
0855: }
0856:
0857: // handle external subset
0858: if (fDoctypeSystemId != null) {
0859: fIsEntityDeclaredVC = !fStandalone;
0860: if (((fValidation || fLoadExternalDTD) && (fValidationManager == null || !fValidationManager
0861: .isCachedDTD()))) {
0862: setScannerState(SCANNER_STATE_DTD_EXTERNAL);
0863: setDispatcher(fDTDDispatcher);
0864: return true;
0865: }
0866: } else if (fExternalSubsetSource != null) {
0867: fIsEntityDeclaredVC = !fStandalone;
0868: if (((fValidation || fLoadExternalDTD) && (fValidationManager == null || !fValidationManager
0869: .isCachedDTD()))) {
0870: // This handles the case of a DOCTYPE that had neither an internal subset or an external subset.
0871: fDTDScanner
0872: .setInputSource(fExternalSubsetSource);
0873: fExternalSubsetSource = null;
0874: setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
0875: setDispatcher(fDTDDispatcher);
0876: return true;
0877: }
0878: }
0879:
0880: // Send endDTD() call if:
0881: // a) systemId is null or if an external subset resolver could not locate an external subset.
0882: // b) "load-external-dtd" and validation are false
0883: // c) DTD grammar is cached
0884:
0885: // in XNI this results in 3 events: doctypeDecl, startDTD, endDTD
0886: // in SAX this results in 2 events: startDTD, endDTD
0887: fDTDScanner.setInputSource(null);
0888: setScannerState(SCANNER_STATE_PROLOG);
0889: break;
0890: }
0891: case SCANNER_STATE_CONTENT: {
0892: reportFatalError("ContentIllegalInProlog", null);
0893: fEntityScanner.scanChar();
0894: }
0895: case SCANNER_STATE_REFERENCE: {
0896: reportFatalError("ReferenceIllegalInProlog",
0897: null);
0898: }
0899: }
0900: } while (complete || again);
0901:
0902: if (complete) {
0903: if (fEntityScanner.scanChar() != '<') {
0904: reportFatalError("RootElementRequired", null);
0905: }
0906: setScannerState(SCANNER_STATE_ROOT_ELEMENT);
0907: setDispatcher(fContentDispatcher);
0908: }
0909: }
0910: // encoding errors
0911: catch (MalformedByteSequenceException e) {
0912: fErrorReporter.reportError(e.getDomain(), e.getKey(), e
0913: .getArguments(),
0914: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0915: return false;
0916: } catch (CharConversionException e) {
0917: fErrorReporter.reportError(
0918: XMLMessageFormatter.XML_DOMAIN,
0919: "CharConversionFailure", null,
0920: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0921: return false;
0922: }
0923: // premature end of file
0924: catch (EOFException e) {
0925: reportFatalError("PrematureEOF", null);
0926: return false;
0927: //throw e;
0928: }
0929:
0930: return true;
0931:
0932: } // dispatch(boolean):boolean
0933:
0934: } // class PrologDispatcher
0935:
0936: /**
0937: * Dispatcher to handle the internal and external DTD subsets.
0938: *
0939: * @author Andy Clark, IBM
0940: */
0941: protected final class DTDDispatcher implements Dispatcher {
0942:
0943: //
0944: // Dispatcher methods
0945: //
0946:
0947: /**
0948: * Dispatch an XML "event".
0949: *
0950: * @param complete True if this dispatcher is intended to scan
0951: * and dispatch as much as possible.
0952: *
0953: * @return True if there is more to dispatch either from this
0954: * or a another dispatcher.
0955: *
0956: * @throws IOException Thrown on i/o error.
0957: * @throws XNIException Thrown on parse error.
0958: */
0959: public boolean dispatch(boolean complete) throws IOException,
0960: XNIException {
0961: fEntityManager.setEntityHandler(null);
0962: try {
0963: boolean again;
0964: do {
0965: again = false;
0966: switch (fScannerState) {
0967: case SCANNER_STATE_DTD_INTERNAL_DECLS: {
0968: // REVISIT: Should there be a feature for
0969: // the "complete" parameter?
0970: boolean completeDTD = true;
0971: boolean readExternalSubset = (fValidation || fLoadExternalDTD)
0972: && (fValidationManager == null || !fValidationManager
0973: .isCachedDTD());
0974: boolean moreToScan = fDTDScanner
0975: .scanDTDInternalSubset(completeDTD,
0976: fStandalone, fHasExternalDTD
0977: && readExternalSubset);
0978: if (!moreToScan) {
0979: // end doctype declaration
0980: if (!fEntityScanner.skipChar(']')) {
0981: reportFatalError(
0982: "EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET",
0983: null);
0984: }
0985: fEntityScanner.skipSpaces();
0986: if (!fEntityScanner.skipChar('>')) {
0987: reportFatalError(
0988: "DoctypedeclUnterminated",
0989: new Object[] { fDoctypeName });
0990: }
0991: fMarkupDepth--;
0992:
0993: // scan external subset next
0994: if (fDoctypeSystemId != null) {
0995: fIsEntityDeclaredVC = !fStandalone;
0996: if (readExternalSubset) {
0997: setScannerState(SCANNER_STATE_DTD_EXTERNAL);
0998: break;
0999: }
1000: } else if (fExternalSubsetSource != null) {
1001: fIsEntityDeclaredVC = !fStandalone;
1002: if (readExternalSubset) {
1003: // This handles the case of a DOCTYPE that only had an internal subset.
1004: fDTDScanner
1005: .setInputSource(fExternalSubsetSource);
1006: fExternalSubsetSource = null;
1007: setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
1008: break;
1009: }
1010: }
1011: // This document only has an internal subset. If it contains parameter entity
1012: // references and standalone="no" then [Entity Declared] is a validity constraint.
1013: else {
1014: fIsEntityDeclaredVC = fEntityManager
1015: .hasPEReferences()
1016: && !fStandalone;
1017: }
1018:
1019: // break out of this dispatcher.
1020: setScannerState(SCANNER_STATE_PROLOG);
1021: setDispatcher(fPrologDispatcher);
1022: fEntityManager
1023: .setEntityHandler(XMLDocumentScannerImpl.this );
1024: return true;
1025: }
1026: break;
1027: }
1028: case SCANNER_STATE_DTD_EXTERNAL: {
1029: fDTDDescription.setValues(fDoctypePublicId,
1030: fDoctypeSystemId, null, null);
1031: fDTDDescription.setRootName(fDoctypeName);
1032: XMLInputSource xmlInputSource = fEntityManager
1033: .resolveEntity(fDTDDescription);
1034: fDTDScanner.setInputSource(xmlInputSource);
1035: setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
1036: again = true;
1037: break;
1038: }
1039: case SCANNER_STATE_DTD_EXTERNAL_DECLS: {
1040: // REVISIT: Should there be a feature for
1041: // the "complete" parameter?
1042: boolean completeDTD = true;
1043: boolean moreToScan = fDTDScanner
1044: .scanDTDExternalSubset(completeDTD);
1045: if (!moreToScan) {
1046: setScannerState(SCANNER_STATE_PROLOG);
1047: setDispatcher(fPrologDispatcher);
1048: fEntityManager
1049: .setEntityHandler(XMLDocumentScannerImpl.this );
1050: return true;
1051: }
1052: break;
1053: }
1054: default: {
1055: throw new XNIException(
1056: "DTDDispatcher#dispatch: scanner state="
1057: + fScannerState
1058: + " ("
1059: + getScannerStateName(fScannerState)
1060: + ')');
1061: }
1062: }
1063: } while (complete || again);
1064: }
1065: // encoding errors
1066: catch (MalformedByteSequenceException e) {
1067: fErrorReporter.reportError(e.getDomain(), e.getKey(), e
1068: .getArguments(),
1069: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1070: return false;
1071: } catch (CharConversionException e) {
1072: fErrorReporter.reportError(
1073: XMLMessageFormatter.XML_DOMAIN,
1074: "CharConversionFailure", null,
1075: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1076: return false;
1077: }
1078: // premature end of file
1079: catch (EOFException e) {
1080: reportFatalError("PrematureEOF", null);
1081: return false;
1082: //throw e;
1083: }
1084:
1085: // cleanup
1086: finally {
1087: fEntityManager
1088: .setEntityHandler(XMLDocumentScannerImpl.this );
1089: }
1090:
1091: return true;
1092:
1093: } // dispatch(boolean):boolean
1094:
1095: } // class DTDDispatcher
1096:
1097: /**
1098: * Dispatcher to handle content scanning.
1099: *
1100: * @author Andy Clark, IBM
1101: * @author Eric Ye, IBM
1102: */
1103: protected class ContentDispatcher extends FragmentContentDispatcher {
1104:
1105: //
1106: // Protected methods
1107: //
1108:
1109: // hooks
1110:
1111: // NOTE: These hook methods are added so that the full document
1112: // scanner can share the majority of code with this class.
1113:
1114: /**
1115: * Scan for DOCTYPE hook. This method is a hook for subclasses
1116: * to add code to handle scanning for a the "DOCTYPE" string
1117: * after the string "<!" has been scanned.
1118: *
1119: * @return True if the "DOCTYPE" was scanned; false if "DOCTYPE"
1120: * was not scanned.
1121: */
1122: protected boolean scanForDoctypeHook() throws IOException,
1123: XNIException {
1124:
1125: if (fEntityScanner.skipString("DOCTYPE")) {
1126: setScannerState(SCANNER_STATE_DOCTYPE);
1127: return true;
1128: }
1129: return false;
1130:
1131: } // scanForDoctypeHook():boolean
1132:
1133: /**
1134: * Element depth iz zero. This methos is a hook for subclasses
1135: * to add code to handle when the element depth hits zero. When
1136: * scanning a document fragment, an element depth of zero is
1137: * normal. However, when scanning a full XML document, the
1138: * scanner must handle the trailing miscellanous section of
1139: * the document after the end of the document's root element.
1140: *
1141: * @return True if the caller should stop and return true which
1142: * allows the scanner to switch to a new scanning
1143: * dispatcher. A return value of false indicates that
1144: * the content dispatcher should continue as normal.
1145: */
1146: protected boolean elementDepthIsZeroHook() throws IOException,
1147: XNIException {
1148:
1149: setScannerState(SCANNER_STATE_TRAILING_MISC);
1150: setDispatcher(fTrailingMiscDispatcher);
1151: return true;
1152:
1153: } // elementDepthIsZeroHook():boolean
1154:
1155: /**
1156: * Scan for root element hook. This method is a hook for
1157: * subclasses to add code that handles scanning for the root
1158: * element. When scanning a document fragment, there is no
1159: * "root" element. However, when scanning a full XML document,
1160: * the scanner must handle the root element specially.
1161: *
1162: * @return True if the caller should stop and return true which
1163: * allows the scanner to switch to a new scanning
1164: * dispatcher. A return value of false indicates that
1165: * the content dispatcher should continue as normal.
1166: */
1167: protected boolean scanRootElementHook() throws IOException,
1168: XNIException {
1169:
1170: if (fExternalSubsetResolver != null && !fSeenDoctypeDecl
1171: && !fDisallowDoctype
1172: && (fValidation || fLoadExternalDTD)) {
1173: scanStartElementName();
1174: resolveExternalSubsetAndRead();
1175: if (scanStartElementAfterName()) {
1176: setScannerState(SCANNER_STATE_TRAILING_MISC);
1177: setDispatcher(fTrailingMiscDispatcher);
1178: return true;
1179: }
1180: } else if (scanStartElement()) {
1181: setScannerState(SCANNER_STATE_TRAILING_MISC);
1182: setDispatcher(fTrailingMiscDispatcher);
1183: return true;
1184: }
1185: return false;
1186:
1187: } // scanRootElementHook():boolean
1188:
1189: /**
1190: * End of file hook. This method is a hook for subclasses to
1191: * add code that handles the end of file. The end of file in
1192: * a document fragment is OK if the markup depth is zero.
1193: * However, when scanning a full XML document, an end of file
1194: * is always premature.
1195: */
1196: protected void endOfFileHook(EOFException e)
1197: throws IOException, XNIException {
1198:
1199: reportFatalError("PrematureEOF", null);
1200: // in case continue-after-fatal-error set, should not do this...
1201: //throw e;
1202:
1203: } // endOfFileHook()
1204:
1205: /**
1206: * <p>Attempt to locate an external subset for a document that does not otherwise
1207: * have one. If an external subset is located, then it is scanned.</p>
1208: */
1209: protected void resolveExternalSubsetAndRead()
1210: throws IOException, XNIException {
1211:
1212: fDTDDescription.setValues(null, null, fEntityManager
1213: .getCurrentResourceIdentifier()
1214: .getExpandedSystemId(), null);
1215: fDTDDescription.setRootName(fElementQName.rawname);
1216: XMLInputSource src = fExternalSubsetResolver
1217: .getExternalSubset(fDTDDescription);
1218:
1219: if (src != null) {
1220: fDoctypeName = fElementQName.rawname;
1221: fDoctypePublicId = src.getPublicId();
1222: fDoctypeSystemId = src.getSystemId();
1223: // call document handler
1224: if (fDocumentHandler != null) {
1225: // This inserts a doctypeDecl event into the stream though no
1226: // DOCTYPE existed in the instance document.
1227: fDocumentHandler.doctypeDecl(fDoctypeName,
1228: fDoctypePublicId, fDoctypeSystemId, null);
1229: }
1230: try {
1231: if (fValidationManager == null
1232: || !fValidationManager.isCachedDTD()) {
1233: fDTDScanner.setInputSource(src);
1234: while (fDTDScanner.scanDTDExternalSubset(true))
1235: ;
1236: } else {
1237: // This sends startDTD and endDTD calls down the pipeline.
1238: fDTDScanner.setInputSource(null);
1239: }
1240: } finally {
1241: fEntityManager
1242: .setEntityHandler(XMLDocumentScannerImpl.this );
1243: }
1244: }
1245: } // resolveExternalSubsetAndRead()
1246:
1247: } // class ContentDispatcher
1248:
1249: /**
1250: * Dispatcher to handle trailing miscellaneous section scanning.
1251: *
1252: * @author Andy Clark, IBM
1253: * @author Eric Ye, IBM
1254: */
1255: protected final class TrailingMiscDispatcher implements Dispatcher {
1256:
1257: //
1258: // Dispatcher methods
1259: //
1260:
1261: /**
1262: * Dispatch an XML "event".
1263: *
1264: * @param complete True if this dispatcher is intended to scan
1265: * and dispatch as much as possible.
1266: *
1267: * @return True if there is more to dispatch either from this
1268: * or a another dispatcher.
1269: *
1270: * @throws IOException Thrown on i/o error.
1271: * @throws XNIException Thrown on parse error.
1272: */
1273: public boolean dispatch(boolean complete) throws IOException,
1274: XNIException {
1275:
1276: try {
1277: boolean again;
1278: do {
1279: again = false;
1280: switch (fScannerState) {
1281: case SCANNER_STATE_TRAILING_MISC: {
1282: fEntityScanner.skipSpaces();
1283: if (fEntityScanner.skipChar('<')) {
1284: setScannerState(SCANNER_STATE_START_OF_MARKUP);
1285: again = true;
1286: } else {
1287: setScannerState(SCANNER_STATE_CONTENT);
1288: again = true;
1289: }
1290: break;
1291: }
1292: case SCANNER_STATE_START_OF_MARKUP: {
1293: fMarkupDepth++;
1294: if (fEntityScanner.skipChar('?')) {
1295: setScannerState(SCANNER_STATE_PI);
1296: again = true;
1297: } else if (fEntityScanner.skipChar('!')) {
1298: setScannerState(SCANNER_STATE_COMMENT);
1299: again = true;
1300: } else if (fEntityScanner.skipChar('/')) {
1301: reportFatalError(
1302: "MarkupNotRecognizedInMisc", null);
1303: again = true;
1304: } else if (isValidNameStartChar(fEntityScanner
1305: .peekChar())) {
1306: reportFatalError(
1307: "MarkupNotRecognizedInMisc", null);
1308: scanStartElement();
1309: setScannerState(SCANNER_STATE_CONTENT);
1310: } else if (isValidNameStartHighSurrogate(fEntityScanner
1311: .peekChar())) {
1312: reportFatalError(
1313: "MarkupNotRecognizedInMisc", null);
1314: scanStartElement();
1315: setScannerState(SCANNER_STATE_CONTENT);
1316: } else {
1317: reportFatalError(
1318: "MarkupNotRecognizedInMisc", null);
1319: }
1320: break;
1321: }
1322: case SCANNER_STATE_PI: {
1323: scanPI();
1324: setScannerState(SCANNER_STATE_TRAILING_MISC);
1325: break;
1326: }
1327: case SCANNER_STATE_COMMENT: {
1328: if (!fEntityScanner.skipString("--")) {
1329: reportFatalError("InvalidCommentStart",
1330: null);
1331: }
1332: scanComment();
1333: setScannerState(SCANNER_STATE_TRAILING_MISC);
1334: break;
1335: }
1336: case SCANNER_STATE_CONTENT: {
1337: int ch = fEntityScanner.peekChar();
1338: if (ch == -1) {
1339: setScannerState(SCANNER_STATE_TERMINATED);
1340: return false;
1341: }
1342: reportFatalError(
1343: "ContentIllegalInTrailingMisc", null);
1344: fEntityScanner.scanChar();
1345: setScannerState(SCANNER_STATE_TRAILING_MISC);
1346: break;
1347: }
1348: case SCANNER_STATE_REFERENCE: {
1349: reportFatalError(
1350: "ReferenceIllegalInTrailingMisc", null);
1351: setScannerState(SCANNER_STATE_TRAILING_MISC);
1352: break;
1353: }
1354: case SCANNER_STATE_TERMINATED: {
1355: return false;
1356: }
1357: }
1358: } while (complete || again);
1359: }
1360: // encoding errors
1361: catch (MalformedByteSequenceException e) {
1362: fErrorReporter.reportError(e.getDomain(), e.getKey(), e
1363: .getArguments(),
1364: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1365: return false;
1366: } catch (CharConversionException e) {
1367: fErrorReporter.reportError(
1368: XMLMessageFormatter.XML_DOMAIN,
1369: "CharConversionFailure", null,
1370: XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1371: return false;
1372: } catch (EOFException e) {
1373: // NOTE: This is the only place we're allowed to reach
1374: // the real end of the document stream. Unless the
1375: // end of file was reached prematurely.
1376: if (fMarkupDepth != 0) {
1377: reportFatalError("PrematureEOF", null);
1378: return false;
1379: //throw e;
1380: }
1381:
1382: setScannerState(SCANNER_STATE_TERMINATED);
1383: return false;
1384: }
1385:
1386: return true;
1387:
1388: } // dispatch(boolean):boolean
1389:
1390: } // class TrailingMiscDispatcher
1391:
1392: } // class XMLDocumentScannerImpl
|