| Method from org.apache.xerces.impl.XMLDTDScannerImpl Detail: |
public void endEntity(String name,
Augmentations augs) throws XNIException {
super.endEntity(name, augs);
// if there is no data after the doctype
//
if (fScannerState == SCANNER_STATE_END_OF_INPUT)
return;
// Handle end of PE
boolean reportEntity = fReportEntity;
if (name.startsWith("%")) {
reportEntity = peekReportEntity();
// check well-formedness of the enity
int startMarkUpDepth = popPEStack();
// throw fatalError if this entity was incomplete and
// was a freestanding decl
if(startMarkUpDepth == 0 &&
startMarkUpDepth < fMarkUpDepth) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"ILL_FORMED_PARAMETER_ENTITY_WHEN_USED_IN_DECL",
new Object[]{ fEntityManager.fCurrentEntity.name},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
if (startMarkUpDepth != fMarkUpDepth) {
reportEntity = false;
if (fValidation) {
// Proper nesting of parameter entities is a Validity Constraint
// and must not be enforced when validation is off
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"ImproperDeclarationNesting",
new Object[]{ name },
XMLErrorReporter.SEVERITY_ERROR);
}
}
if (fEntityScanner.isExternal()) {
fExtEntityDepth--;
}
// call handler
if (fDTDHandler != null && reportEntity) {
fDTDHandler.endParameterEntity(name, augs);
}
}
// end DTD
else if (name.equals("[dtd]")) {
if (fIncludeSectDepth != 0) {
reportFatalError("IncludeSectUnterminated", null);
}
fScannerState = SCANNER_STATE_END_OF_INPUT;
// call handler
fEntityManager.endExternalSubset();
if (fDTDHandler != null) {
fDTDHandler.endExternalSubset(null);
fDTDHandler.endDTD(null);
}
fExtEntityDepth--;
}
}
This method notifies the end of an entity. The DTD has the pseudo-name
of "[dtd]" parameter entity names start with '%'; and general entities
are just specified by their name. |
public XMLDTDContentModelHandler getDTDContentModelHandler() {
return fDTDContentModelHandler ;
}
getDTDContentModelHandler |
public XMLDTDHandler getDTDHandler() {
return fDTDHandler;
}
|
public Boolean getFeatureDefault(String featureId) {
for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
if (RECOGNIZED_FEATURES[i].equals(featureId)) {
return FEATURE_DEFAULTS[i];
}
}
return null;
}
Returns the default state for a feature, or null if this
component does not want to report a default value for this
feature. |
public Object getPropertyDefault(String propertyId) {
for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
return PROPERTY_DEFAULTS[i];
}
}
return null;
}
Returns the default state for a property, or null if this
component does not want to report a default value for this
property. |
public String[] getRecognizedFeatures() {
return (String[])(RECOGNIZED_FEATURES.clone());
}
Returns a list of feature identifiers that are recognized by
this component. This method may return null if no features
are recognized by this component. |
public String[] getRecognizedProperties() {
return (String[])(RECOGNIZED_PROPERTIES.clone());
}
Returns a list of property identifiers that are recognized by
this component. This method may return null if no properties
are recognized by this component. |
public void reset() {
super.reset();
init();
}
|
public void reset(XMLComponentManager componentManager) throws XMLConfigurationException {
super.reset(componentManager);
init();
}
|
protected final String scanAttDefaultDecl(String elName,
String atName,
String type,
XMLString defaultVal,
XMLString nonNormalizedDefaultVal) throws IOException, XNIException {
String defaultType = null;
fString.clear();
defaultVal.clear();
if (fEntityScanner.skipString("#REQUIRED")) {
defaultType = "#REQUIRED";
}
else if (fEntityScanner.skipString("#IMPLIED")) {
defaultType = "#IMPLIED";
}
else {
if (fEntityScanner.skipString("#FIXED")) {
defaultType = "#FIXED";
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL",
new Object[]{elName, atName});
}
}
// AttValue
boolean isVC = !fStandalone && (fSeenExternalDTD || fSeenPEReferences);
scanAttributeValue(defaultVal, nonNormalizedDefaultVal, atName, isVC, elName);
}
return defaultType;
}
Scans an attribute default declaration
[60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
|
protected final void scanAttlistDecl() throws IOException, XNIException {
// spaces
fReportEntity = false;
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL",
null);
}
// element name
String elName = fEntityScanner.scanName();
if (elName == null) {
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL",
null);
}
// call handler
if (fDTDHandler != null) {
fDTDHandler.startAttlist(elName, null);
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
// no space, is it the end yet?
if (fEntityScanner.skipChar(' >")) {
// yes, stop here
// call handler
if (fDTDHandler != null) {
fDTDHandler.endAttlist(null);
}
fMarkUpDepth--;
return;
}
else {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF",
new Object[]{elName});
}
}
// definitions
while (!fEntityScanner.skipChar(' >")) {
String name = fEntityScanner.scanName();
if (name == null) {
reportFatalError("AttNameRequiredInAttDef",
new Object[]{elName});
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF",
new Object[]{elName, name});
}
// type
String type = scanAttType(elName, name);
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF",
new Object[]{elName, name});
}
// default decl
String defaultType = scanAttDefaultDecl(elName, name,
type,
fLiteral, fLiteral2);
// REVISIT: Should we do anything with the non-normalized
// default attribute value? -Ac
// yes--according to bug 5073. - neilg
// call handler
if (fDTDHandler != null) {
String[] enumeration = null;
if (fEnumerationCount != 0) {
enumeration = new String[fEnumerationCount];
System.arraycopy(fEnumeration, 0, enumeration,
0, fEnumerationCount);
}
// Determine whether the default value to be passed should be null.
// REVISIT: should probably check whether fLiteral.ch is null instead. LM.
if (defaultType!=null && (defaultType.equals("#REQUIRED") ||
defaultType.equals("#IMPLIED"))) {
fDTDHandler.attributeDecl(elName, name, type, enumeration,
defaultType, null, null, null);
}
else {
fDTDHandler.attributeDecl(elName, name, type, enumeration,
defaultType, fLiteral, fLiteral2, null);
}
}
skipSeparator(false, !scanningInternalSubset());
}
// call handler
if (fDTDHandler != null) {
fDTDHandler.endAttlist(null);
}
fMarkUpDepth--;
fReportEntity = true;
}
Scans an attlist declaration
[52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
[53] AttDef ::= S Name S AttType S DefaultDecl
Note: Called after scanning past '<!ATTLIST' |
protected final void scanComment() throws IOException, XNIException {
fReportEntity = false;
scanComment(fStringBuffer);
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
fDTDHandler.comment(fStringBuffer, null);
}
fReportEntity = true;
}
[15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
Note: Called after scanning past '<!--' |
public boolean scanDTDExternalSubset(boolean complete) throws IOException, XNIException {
fEntityManager.setEntityHandler(this);
if (fScannerState == SCANNER_STATE_TEXT_DECL) {
fSeenExternalDTD = true;
boolean textDecl = scanTextDecl();
if (fScannerState == SCANNER_STATE_END_OF_INPUT) {
return false;
}
else {
// next state is markup decls regardless of whether there
// is a TextDecl or not
setScannerState(SCANNER_STATE_MARKUP_DECL);
if (textDecl && !complete) {
return true;
}
}
}
// keep dispatching "events"
do {
if (!scanDecls(complete)) {
return false;
}
} while (complete);
// return that there is more to scan
return true;
}
Scans the external subset of the document. |
public boolean scanDTDInternalSubset(boolean complete,
boolean standalone,
boolean hasExternalSubset) throws IOException, XNIException {
// reset entity scanner
fEntityScanner = fEntityManager.getEntityScanner();
fEntityManager.setEntityHandler(this);
fStandalone = standalone;
if (fScannerState == SCANNER_STATE_TEXT_DECL) {
// call handler
if (fDTDHandler != null) {
fDTDHandler.startDTD(fEntityScanner, null);
fStartDTDCalled = true;
}
// set starting state for internal subset
setScannerState(SCANNER_STATE_MARKUP_DECL);
}
// keep dispatching "events"
do {
if (!scanDecls(complete)) {
// call handler
if (fDTDHandler != null && hasExternalSubset == false) {
fDTDHandler.endDTD(null);
}
// we're done, set starting state for external subset
setScannerState(SCANNER_STATE_TEXT_DECL);
return false;
}
} while (complete);
// return that there is more to scan
return true;
}
Scans the internal subset of the document. |
protected final boolean scanDecls(boolean complete) throws IOException, XNIException {
skipSeparator(false, true);
boolean again = true;
while (again && fScannerState == SCANNER_STATE_MARKUP_DECL) {
again = complete;
if (fEntityScanner.skipChar('< ")) {
fMarkUpDepth++;
if (fEntityScanner.skipChar('?")) {
scanPI();
}
else if (fEntityScanner.skipChar('!")) {
if (fEntityScanner.skipChar('-")) {
if (!fEntityScanner.skipChar('-")) {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
null);
} else {
scanComment();
}
}
else if (fEntityScanner.skipString("ELEMENT")) {
scanElementDecl();
}
else if (fEntityScanner.skipString("ATTLIST")) {
scanAttlistDecl();
}
else if (fEntityScanner.skipString("ENTITY")) {
scanEntityDecl();
}
else if (fEntityScanner.skipString("NOTATION")) {
scanNotationDecl();
}
else if (fEntityScanner.skipChar('[") &&
!scanningInternalSubset()) {
scanConditionalSect(fPEDepth);
}
else {
fMarkUpDepth--;
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
null);
}
}
else {
fMarkUpDepth--;
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
}
}
else if (fIncludeSectDepth > 0 && fEntityScanner.skipChar(']")) {
// end of conditional section?
if (!fEntityScanner.skipChar(']")
|| !fEntityScanner.skipChar(' >")) {
reportFatalError("IncludeSectUnterminated", null);
}
// call handler
if (fDTDHandler != null) {
fDTDHandler.endConditional(null);
}
// decreaseMarkupDepth();
fIncludeSectDepth--;
fMarkUpDepth--;
}
else if (scanningInternalSubset() &&
fEntityScanner.peekChar() == ']") {
// this is the end of the internal subset, let's stop here
return false;
}
else if (fEntityScanner.skipSpaces()) {
// simply skip
}
else {
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
// Skip the part in error
int ch;
do {
// Ignore the current character
fEntityScanner.scanChar();
// Skip any separators
skipSeparator(false, true);
// Keeping getting the next character,
// until it's one of the expected ones
ch = fEntityScanner.peekChar();
} while (ch != '< " && ch != ']" && !XMLChar.isSpace(ch));
}
skipSeparator(false, true);
}
return fScannerState != SCANNER_STATE_END_OF_INPUT;
}
|
protected final void scanElementDecl() throws IOException, XNIException {
// spaces
fReportEntity = false;
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL",
null);
}
// element name
String name = fEntityScanner.scanName();
if (name == null) {
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL",
null);
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL",
new Object[]{name});
}
// content model
if (fDTDContentModelHandler != null) {
fDTDContentModelHandler.startContentModel(name, null);
}
String contentModel = null;
fReportEntity = true;
if (fEntityScanner.skipString("EMPTY")) {
contentModel = "EMPTY";
// call handler
if (fDTDContentModelHandler != null) {
fDTDContentModelHandler.empty(null);
}
}
else if (fEntityScanner.skipString("ANY")) {
contentModel = "ANY";
// call handler
if (fDTDContentModelHandler != null) {
fDTDContentModelHandler.any(null);
}
}
else {
if (!fEntityScanner.skipChar('(")) {
reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN",
new Object[]{name});
}
if (fDTDContentModelHandler != null) {
fDTDContentModelHandler.startGroup(null);
}
fStringBuffer.clear();
fStringBuffer.append('(");
fMarkUpDepth++;
skipSeparator(false, !scanningInternalSubset());
// Mixed content model
if (fEntityScanner.skipString("#PCDATA")) {
scanMixed(name);
}
else { // children content
scanChildren(name);
}
contentModel = fStringBuffer.toString();
}
// call handler
if (fDTDContentModelHandler != null) {
fDTDContentModelHandler.endContentModel(null);
}
fReportEntity = false;
skipSeparator(false, !scanningInternalSubset());
// end
if (!fEntityScanner.skipChar(' >")) {
reportFatalError("ElementDeclUnterminated", new Object[]{name});
}
fReportEntity = true;
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
fDTDHandler.elementDecl(name, contentModel, null);
}
}
Scans an element declaration
[45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
[46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
Note: Called after scanning past '<!ELEMENT' |
protected final void scanEntityValue(XMLString value,
XMLString nonNormalizedValue) throws IOException, XNIException {
int quote = fEntityScanner.scanChar();
if (quote != '\'" && quote != '"") {
reportFatalError("OpenQuoteMissingInDecl", null);
}
// store at which depth of entities we start
int entityDepth = fEntityDepth;
XMLString literal = fString;
XMLString literal2 = fString;
if (fEntityScanner.scanLiteral(quote, fString) != quote) {
fStringBuffer.clear();
fStringBuffer2.clear();
do {
fStringBuffer.append(fString);
fStringBuffer2.append(fString);
if (fEntityScanner.skipChar('&")) {
if (fEntityScanner.skipChar('#")) {
fStringBuffer2.append("");
scanCharReferenceValue(fStringBuffer, fStringBuffer2);
}
else {
fStringBuffer.append('&");
fStringBuffer2.append('&");
String eName = fEntityScanner.scanName();
if (eName == null) {
reportFatalError("NameRequiredInReference",
null);
}
else {
fStringBuffer.append(eName);
fStringBuffer2.append(eName);
}
if (!fEntityScanner.skipChar(';")) {
reportFatalError("SemicolonRequiredInReference",
new Object[]{eName});
}
else {
fStringBuffer.append(';");
fStringBuffer2.append(';");
}
}
}
else if (fEntityScanner.skipChar('%")) {
while (true) {
fStringBuffer2.append('%");
String peName = fEntityScanner.scanName();
if (peName == null) {
reportFatalError("NameRequiredInPEReference",
null);
}
else if (!fEntityScanner.skipChar(';")) {
reportFatalError("SemicolonRequiredInPEReference",
new Object[]{peName});
}
else {
if (scanningInternalSubset()) {
reportFatalError("PEReferenceWithinMarkup",
new Object[]{peName});
}
fStringBuffer2.append(peName);
fStringBuffer2.append(';");
}
startPE(peName, true);
// REVISIT: [Q] Why do we skip spaces here? -Ac
// REVISIT: This will make returning the non-
// normalized value harder. -Ac
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('%"))
break;
}
}
else {
int c = fEntityScanner.peekChar();
if (XMLChar.isHighSurrogate(c)) {
scanSurrogates(fStringBuffer2);
}
else if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInLiteral",
new Object[]{Integer.toHexString(c)});
fEntityScanner.scanChar();
}
// if it's not the delimiting quote or if it is but from a
// different entity than the one this literal started from,
// simply append the character to our buffer
else if (c != quote || entityDepth != fEntityDepth) {
fStringBuffer.append((char)c);
fStringBuffer2.append((char)c);
fEntityScanner.scanChar();
}
}
} while (fEntityScanner.scanLiteral(quote, fString) != quote);
fStringBuffer.append(fString);
fStringBuffer2.append(fString);
literal = fStringBuffer;
literal2 = fStringBuffer2;
}
value.setValues(literal);
nonNormalizedValue.setValues(literal2);
if (!fEntityScanner.skipChar(quote)) {
reportFatalError("CloseQuoteMissingInDecl", null);
}
}
|
protected final void scanPIData(String target,
XMLString data) throws IOException, XNIException {
super.scanPIData(target, data);
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
fDTDHandler.processingInstruction(target, data, null);
}
}
Scans a processing data. This is needed to handle the situation
where a document starts with a processing instruction whose
target name starts with "xml". (e.g. xmlfoo) |
protected final boolean scanTextDecl() throws IOException, XNIException {
// scan XMLDecl
boolean textDecl = false;
if (fEntityScanner.skipString("< ?xml")) {
fMarkUpDepth++;
// NOTE: special case where document starts with a PI
// whose name starts with "xml" (e.g. "xmlfoo")
if (isValidNameChar(fEntityScanner.peekChar())) {
fStringBuffer.clear();
fStringBuffer.append("xml");
if (fNamespaces) {
while (isValidNCName(fEntityScanner.peekChar())) {
fStringBuffer.append((char)fEntityScanner.scanChar());
}
}
else {
while (isValidNameChar(fEntityScanner.peekChar())) {
fStringBuffer.append((char)fEntityScanner.scanChar());
}
}
String target =
fSymbolTable.addSymbol(fStringBuffer.ch,
fStringBuffer.offset,
fStringBuffer.length);
scanPIData(target, fString);
}
// standard Text declaration
else {
// pseudo-attribute values
String version = null;
String encoding = null;
scanXMLDeclOrTextDecl(true, fStrings);
textDecl = true;
fMarkUpDepth--;
version = fStrings[0];
encoding = fStrings[1];
fEntityScanner.setXMLVersion(version);
if (!fEntityScanner.fCurrentEntity.isEncodingExternallySpecified()) {
fEntityScanner.setEncoding(encoding);
}
// call handler
if (fDTDHandler != null) {
fDTDHandler.textDecl(version, encoding, null);
}
}
}
fEntityManager.fCurrentEntity.mayReadChunks = true;
return textDecl;
}
|
protected final boolean scanningInternalSubset() {
return fExtEntityDepth == 0;
}
|
public void setDTDContentModelHandler(XMLDTDContentModelHandler dtdContentModelHandler) {
fDTDContentModelHandler = dtdContentModelHandler;
}
setDTDContentModelHandler |
public void setDTDHandler(XMLDTDHandler dtdHandler) {
fDTDHandler = dtdHandler;
}
|
public void setInputSource(XMLInputSource inputSource) throws IOException {
if (inputSource == null) {
// no system id was available
if (fDTDHandler != null) {
fDTDHandler.startDTD(null, null);
fDTDHandler.endDTD(null);
}
return;
}
fEntityManager.setEntityHandler(this);
fEntityManager.startDTDEntity(inputSource);
}
|
protected final void setScannerState(int state) {
fScannerState = state;
if (DEBUG_SCANNER_STATE) {
System.out.print("### setScannerState: ");
System.out.print(getScannerStateName(state));
System.out.println();
}
}
|
public void startEntity(String name,
XMLResourceIdentifier identifier,
String encoding,
Augmentations augs) throws XNIException {
super.startEntity(name, identifier, encoding, augs);
boolean dtdEntity = name.equals("[dtd]");
if (dtdEntity) {
// call handler
if (fDTDHandler != null && !fStartDTDCalled ) {
fDTDHandler.startDTD(fEntityScanner, null);
}
if (fDTDHandler != null) {
fDTDHandler.startExternalSubset(identifier,null);
}
fEntityManager.startExternalSubset();
fExtEntityDepth++;
}
else if (name.charAt(0) == '%") {
pushPEStack(fMarkUpDepth, fReportEntity);
if (fEntityScanner.isExternal()) {
fExtEntityDepth++;
}
}
// call handler
if (fDTDHandler != null && !dtdEntity && fReportEntity) {
fDTDHandler.startParameterEntity(name, identifier, encoding, augs);
}
}
This method notifies of the start of an entity. The DTD has the
pseudo-name of "[dtd]" parameter entity names start with '%'; and
general entities are just specified by their name. |
protected void startPE(String name,
boolean literal) throws IOException, XNIException {
int depth = fPEDepth;
String pName = "%"+name;
if (!fSeenPEReferences) {
fSeenPEReferences = true;
fEntityManager.notifyHasPEReferences();
}
if (fValidation && !fEntityManager.isDeclaredEntity(pName)) {
fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,"EntityNotDeclared",
new Object[]{name}, XMLErrorReporter.SEVERITY_ERROR);
}
fEntityManager.startEntity(fSymbolTable.addSymbol(pName),
literal);
// if we actually got a new entity and it's external
// parse text decl if there is any
if (depth != fPEDepth && fEntityScanner.isExternal()) {
scanTextDecl();
}
}
start a parameter entity dealing with the textdecl if there is any |