public boolean dispatch(boolean complete) throws IOException, XNIException {
fEntityManager.setEntityHandler(null);
try {
boolean again;
do {
again = false;
switch (fScannerState) {
case SCANNER_STATE_DTD_INTERNAL_DECLS: {
// REVISIT: Should there be a feature for
// the "complete" parameter?
boolean completeDTD = true;
boolean readExternalSubset = (fValidation || fLoadExternalDTD) && (fValidationManager == null || !fValidationManager.isCachedDTD());
boolean moreToScan = fDTDScanner.scanDTDInternalSubset(completeDTD, fStandalone, fHasExternalDTD && readExternalSubset);
if (!moreToScan) {
// end doctype declaration
if (!fEntityScanner.skipChar(']")) {
reportFatalError("EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET",
null);
}
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar(' >")) {
reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
}
fMarkupDepth--;
// scan external subset next
if (fDoctypeSystemId != null) {
fIsEntityDeclaredVC = !fStandalone;
if (readExternalSubset) {
setScannerState(SCANNER_STATE_DTD_EXTERNAL);
break;
}
}
else if (fExternalSubsetSource != null) {
fIsEntityDeclaredVC = !fStandalone;
if (readExternalSubset) {
// This handles the case of a DOCTYPE that only had an internal subset.
fDTDScanner.setInputSource(fExternalSubsetSource);
fExternalSubsetSource = null;
setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
break;
}
}
// This document only has an internal subset. If it contains parameter entity
// references and standalone="no" then [Entity Declared] is a validity constraint.
else {
fIsEntityDeclaredVC = fEntityManager.hasPEReferences() && !fStandalone;
}
// break out of this dispatcher.
setScannerState(SCANNER_STATE_PROLOG);
setDispatcher(fPrologDispatcher);
fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
return true;
}
break;
}
case SCANNER_STATE_DTD_EXTERNAL: {
fDTDDescription.setValues(fDoctypePublicId, fDoctypeSystemId, null, null);
fDTDDescription.setRootName(fDoctypeName);
XMLInputSource xmlInputSource =
fEntityManager.resolveEntity(fDTDDescription);
fDTDScanner.setInputSource(xmlInputSource);
setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
again = true;
break;
}
case SCANNER_STATE_DTD_EXTERNAL_DECLS: {
// REVISIT: Should there be a feature for
// the "complete" parameter?
boolean completeDTD = true;
boolean moreToScan = fDTDScanner.scanDTDExternalSubset(completeDTD);
if (!moreToScan) {
setScannerState(SCANNER_STATE_PROLOG);
setDispatcher(fPrologDispatcher);
fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
return true;
}
break;
}
default: {
throw new XNIException("DTDDispatcher#dispatch: scanner state="+fScannerState+" ("+getScannerStateName(fScannerState)+')");
}
}
} while (complete || again);
}
// encoding errors
catch (MalformedByteSequenceException e) {
fErrorReporter.reportError(e.getDomain(), e.getKey(),
e.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
return false;
}
catch (CharConversionException e) {
fErrorReporter.reportError(
XMLMessageFormatter.XML_DOMAIN,
"CharConversionFailure",
null,
XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
return false;
}
// premature end of file
catch (EOFException e) {
reportFatalError("PrematureEOF", null);
return false;
//throw e;
}
// cleanup
finally {
fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
}
return true;
}
|