/*
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class is responsible for scanning the declarations found
* in the internal and external subsets of a DTD in an XML document.
* The scanner acts as the sources for the DTD information which is
* communicated to the DTD handlers.
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://xml.org/sax/features/validation</li>
* </ul>
*
* @author Arnaud Le Hors, IBM
* @author Andy Clark, IBM
* @author Glenn Marcy, IBM
* @author Eric Ye, IBM
*
* @version $Id: XMLDTDScannerImpl.java,v 1.7 2007/09/26 12:52:40 ndw Exp $
*/
public class XMLDTDScannerImpl
extends XMLScanner
//
// Constants
//
// scanner states
/** Scanner state: end of input. */
/** Scanner state: text declaration. */
/** Scanner state: markup declaration. */
// recognized features and properties
/** Recognized features. */
};
/** Feature defaults. */
null,
};
/** Recognized properties. */
};
/** Property defaults. */
null,
null,
null,
};
// debugging
/** Debug scanner state. */
private static final boolean DEBUG_SCANNER_STATE = false;
//
// Data
//
// handlers
/** DTD handler. */
/** DTD content model handler. */
// state
/** Scanner state. */
protected int fScannerState;
/** Standalone. */
protected boolean fStandalone;
/** Seen external DTD. */
protected boolean fSeenExternalDTD;
/** Seen external parameter entity. */
protected boolean fSeenExternalPE;
// private data
/** Start DTD called. */
private boolean fStartDTDCalled;
/** Default attribute */
/**
* Stack of content operators (either '|' or ',') in children
* content.
*/
/** Size of content stack. */
private int fContentDepth;
/** Parameter entity stack to check well-formedness. */
/** Number of opened parameter entities. */
private int fPEDepth;
/** Markup depth. */
private int fMarkUpDepth;
/** Number of opened external entities. */
private int fExtEntityDepth;
/** Number of opened include sections. */
private int fIncludeSectDepth;
// temporary variables
/** Array of 3 strings. */
/** String. */
/** String buffer. */
/** String buffer. */
/** Literal text. */
/** Literal text. */
/** Enumeration values. */
/** Enumeration values count. */
private int fEnumerationCount;
/** Ignore conditional section buffer. */
/** Object contains grammar information for a non-validaing parser. */
boolean nonValidatingMode = false;
//
// Constructors
//
/** Default constructor. */
public XMLDTDScannerImpl() {
} // <init>()
/** Constructor for he use of non-XMLComponentManagers. */
}
//
// XMLDTDScanner methods
//
/**
* Sets the input source.
*
* @param inputSource The input source or null.
*
* @throws IOException Thrown on i/o error.
*/
if (inputSource == null) {
// no system id was available
if (fDTDHandler != null) {
}
if (nonValidatingMode){
}
return;
}
fEntityManager.setEntityHandler(this);
} // setInputSource(XMLInputSource)
/**
* Scans the external subset of the document.
*
* @param complete True if the scanner should scan the document
* completely, pushing all events to the registered
* document handler. A value of false indicates that
* that the scanner should only scan the next portion
* of the document and return. A scanner instance is
* permitted to completely scan a document if it does
* not support this "pull" scanning model.
*
* @return True if there is more to scan, false otherwise.
*/
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
return true;
}
}
}
// keep dispatching "events"
do {
return false;
}
} while (complete);
// return that there is more to scan
return true;
} // scanDTDExternalSubset(boolean):boolean
/**
* Scans the internal subset of the document.
*
* @param complete True if the scanner should scan the document
* completely, pushing all events to the registered
* document handler. A value of false indicates that
* that the scanner should only scan the next portion
* of the document and return. A scanner instance is
* permitted to completely scan a document if it does
* not support this "pull" scanning model.
* @param standalone True if the document was specified as standalone.
* This value is important for verifying certain
* well-formedness constraints.
* @param hasExternalDTD True if the document has an external DTD.
* This allows the scanner to properly notify
* the handler of the end of the DTD in the
* absence of an external subset.
*
* @return True if there is more to scan, false otherwise.
*/
boolean hasExternalSubset)
throws IOException, XNIException {
// reset entity scanner
//xxx:stax getText() is supposed to return only DTD internal subset
//shouldn't we record position here before we go ahead ??
fEntityManager.setEntityHandler(this);
//System.out.println("state"+fScannerState);
if (fScannerState == SCANNER_STATE_TEXT_DECL) {
// call handler
if (fDTDHandler != null) {
fStartDTDCalled = true;
}
if (nonValidatingMode){
fStartDTDCalled = true;
}
// set starting state for internal subset
}
// keep dispatching "events"
do {
// call handler
}
if (nonValidatingMode && hasExternalSubset == false ){
}
// we're done, set starting state for external subset
return false;
}
} while (complete);
// return that there is more to scan
return true;
} // scanDTDInternalSubset(boolean,boolean,boolean):boolean
//
// XMLComponent methods
//
/**
* reset
*
* @param componentManager
*/
throws XMLConfigurationException {
super.reset(componentManager);
init();
} // reset(XMLComponentManager)
// this is made for something like XMLDTDLoader--XMLComponentManager-free operation...
public void reset() {
super.reset();
init();
}
init() ;
nonValidatingMode = true;
//Revisit : Create new grammar until we implement GrammarPool.
}
/**
* 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.
*/
} // getRecognizedFeatures():String[]
/**
* 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.
*/
} // getRecognizedProperties():String[]
/**
* Returns the default state for a feature, or null if this
* component does not want to report a default value for this
* feature.
*
* @param featureId The feature identifier.
*
* @since Xerces 2.2.0
*/
return FEATURE_DEFAULTS[i];
}
}
return null;
} // getFeatureDefault(String):Boolean
/**
* Returns the default state for a property, or null if this
* component does not want to report a default value for this
* property.
*
* @param propertyId The property identifier.
*
* @since Xerces 2.2.0
*/
return PROPERTY_DEFAULTS[i];
}
}
return null;
} // getPropertyDefault(String):Object
//
// XMLDTDSource methods
//
/**
* setDTDHandler
*
* @param dtdHandler
*/
} // setDTDHandler(XMLDTDHandler)
/**
* getDTDHandler
*
* @return the XMLDTDHandler
*/
return fDTDHandler;
} // getDTDHandler(): XMLDTDHandler
//
// XMLDTDContentModelSource methods
//
/**
* setDTDContentModelHandler
*
* @param dtdContentModelHandler
*/
} // setDTDContentModelHandler
/**
* getDTDContentModelHandler
*
* @return XMLDTDContentModelHandler
*/
return fDTDContentModelHandler ;
} // setDTDContentModelHandler
//
// XMLEntityHandler methods
//
/**
* 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.
*
* @param name The name of the entity.
* @param identifier The resource identifier.
* @param encoding The auto-detected IANA encoding name of the entity
* stream. This value will be null in those situations
* where the entity encoding is not auto-detected (e.g.
* internal entities or a document entity that is
* parsed from a java.io.Reader).
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
if (dtdEntity) {
// call handler
}
if (fDTDHandler != null) {
}
}
if (fEntityScanner.isExternal()) {
}
}
// call handler
}
} // startEntity(String,XMLResourceIdentifier,String)
/**
* 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.
*
* @param name The name of the entity.
*
* @throws XNIException Thrown by handler to signal an error.
*/
throws XNIException, IOException {
// if there is no data after the doctype
//
return;
// Handle end of PE
boolean reportEntity = fReportEntity;
// check well-formedness of the enity
int startMarkUpDepth = popPEStack();
// throw fatalError if this entity was incomplete and
// was a freestanding decl
if(startMarkUpDepth == 0 &&
"ILL_FORMED_PARAMETER_ENTITY_WHEN_USED_IN_DECL",
}
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
"ImproperDeclarationNesting",
}
}
if (fEntityScanner.isExternal()) {
}
}
// call handler
}
// end DTD
if (dtdEntity) {
if (fIncludeSectDepth != 0) {
}
// call handler
if (fDTDHandler != null) {
}
}
//XML (Document Entity) is the last opened entity, however
//if for some reason DTD Scanner receives this callback
//there is something wrong (probably invalid XML), throw exception.
//or
//For standalone DTD loader, it might be the last opened entity
//and if this is the last opened entity and fMarkUpDepth != 0 or
//fIncludeSectDepth != 0 or fExtEntityDepth != 0 throw Exception
throw new EOFException();
}
} // endEntity(String)
// helper methods
/**
* Sets the scanner state.
*
* @param state The new scanner state.
*/
if (DEBUG_SCANNER_STATE) {
//System.out.println();
}
} // setScannerState(int)
//
// Private methods
//
/** Returns the scanner state name. */
if (DEBUG_SCANNER_STATE) {
switch (state) {
case SCANNER_STATE_END_OF_INPUT: return "SCANNER_STATE_END_OF_INPUT";
case SCANNER_STATE_TEXT_DECL: return "SCANNER_STATE_TEXT_DECL";
case SCANNER_STATE_MARKUP_DECL: return "SCANNER_STATE_MARKUP_DECL";
}
}
} // getScannerStateName(int):String
protected final boolean scanningInternalSubset() {
return fExtEntityDepth == 0;
}
/**
* start a parameter entity dealing with the textdecl if there is any
*
* @param name The name of the parameter entity to start (without the '%')
* @param literal Whether this is happening within a literal
*/
throws IOException, XNIException {
}
literal);
// if we actually got a new entity and it's external
// parse text decl if there is any
scanTextDecl();
}
}
/**
* Dispatch an XML "event".
*
* @param complete True if this method is intended to scan
* and dispatch as much as possible.
*
* @return True if a TextDecl was scanned.
*
* @throws IOException Thrown on i/o error.
* @throws XNIException Thrown on parse error.
*
*/
protected final boolean scanTextDecl()
throws IOException, XNIException {
// scan XMLDecl
boolean textDecl = false;
fMarkUpDepth++;
// NOTE: special case where document starts with a PI
// whose name starts with "xml" (e.g. "xmlfoo")
}
}
// standard Text declaration
else {
// pseudo-attribute values
scanXMLDeclOrTextDecl(true, fStrings);
textDecl = true;
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
}
}
}
return textDecl;
} // scanTextDecl(boolean):boolean
/**
* Scans a processing data. This is needed to handle the situation
* where a document starts with a processing instruction whose
* target name <em>starts with</em> "xml". (e.g. xmlfoo)
*
* @param target The PI target
* @param data The string to fill in with the data
*/
throws IOException, XNIException {
//Venu REVISIT
// super.scanPIData(target, data);
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
}
} // scanPIData(String)
/**
* Scans a comment.
* <p>
* <pre>
* [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
* </pre>
* <p>
* <strong>Note:</strong> Called after scanning past '<!--'
*/
fReportEntity = false;
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
}
fReportEntity = true;
} // scanComment()
/**
* Scans an element declaration
* <p>
* <pre>
* [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
* [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
* </pre>
* <p>
* <strong>Note:</strong> Called after scanning past '<!ELEMENT'
*/
// spaces
fReportEntity = false;
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL",
null);
}
// element name
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL",
null);
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL",
}
// content model
if (fDTDContentModelHandler != null) {
}
fReportEntity = true;
contentModel = "EMPTY";
// call handler
if (fDTDContentModelHandler != null) {
}
}
contentModel = "ANY";
// call handler
if (fDTDContentModelHandler != null) {
}
}
else {
reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN",
}
if (fDTDContentModelHandler != null) {
}
fMarkUpDepth++;
skipSeparator(false, !scanningInternalSubset());
// Mixed content model
}
else { // children content
}
}
// call handler
if (fDTDContentModelHandler != null) {
}
fReportEntity = false;
skipSeparator(false, !scanningInternalSubset());
// end
}
fReportEntity = true;
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
}
} // scanElementDecl()
/**
* scan Mixed content model
* This assumes the content model has been parsed up to #PCDATA and
* can simply append to fStringBuffer.
* <pre>
* [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
* | '(' S? '#PCDATA' S? ')'
* </pre>
*
* @param elName The element type name this declaration is about.
*
* <strong>Note:</strong> Called after scanning past '(#PCDATA'.
*/
throws IOException, XNIException {
// call handler
if (fDTDContentModelHandler != null) {
}
skipSeparator(false, !scanningInternalSubset());
// call handler
if (fDTDContentModelHandler != null) {
null);
}
skipSeparator(false, !scanningInternalSubset());
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT",
}
// call handler
if (fDTDContentModelHandler != null) {
}
skipSeparator(false, !scanningInternalSubset());
}
// The following check must be done in a single call (as opposed to one
// for ')' and then one for '*') to guarantee that callbacks are
// properly nested. We do not want to trigger endEntity too early in
// case we cross the boundary of an entity between the two characters.
// call handler
if (fDTDContentModelHandler != null) {
null);
}
}
reportFatalError("MixedContentUnterminated",
}
// call handler
if (fDTDContentModelHandler != null) {
}
}
else {
reportFatalError("MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN",
}
fMarkUpDepth--;
// we are done
}
/**
* scan children content model
* This assumes it can simply append to fStringBuffer.
* <pre>
* [47] children ::= (choice | seq) ('?' | '*' | '+')?
* [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
* [49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')'
* [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
* </pre>
*
* @param elName The element type name this declaration is about.
*
* <strong>Note:</strong> Called after scanning past the first open
* paranthesis.
*/
throws IOException, XNIException {
fContentDepth = 0;
pushContentStack(0);
int currentOp = 0;
int c;
while (true) {
fMarkUpDepth++;
// call handler
if (fDTDContentModelHandler != null) {
}
// push current op on stack and reset it
currentOp = 0;
skipSeparator(false, !scanningInternalSubset());
continue;
}
skipSeparator(false, !scanningInternalSubset());
reportFatalError("MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN",
return;
}
// call handler
if (fDTDContentModelHandler != null) {
}
c = fEntityScanner.peekChar();
if (c == '?' || c == '*' || c == '+') {
// call handler
if (fDTDContentModelHandler != null) {
short oc;
if (c == '?') {
}
else if (c == '*') {
}
else {
}
}
fStringBuffer.append((char)c);
}
while (true) {
skipSeparator(false, !scanningInternalSubset());
c = fEntityScanner.peekChar();
currentOp = c;
// call handler
if (fDTDContentModelHandler != null) {
null);
}
break;
}
currentOp = c;
// call handler
if (fDTDContentModelHandler != null) {
null);
}
break;
}
else if (c != ')') {
reportFatalError("MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN",
}
// call handler
if (fDTDContentModelHandler != null) {
}
// restore previous op
currentOp = popContentStack();
short oc;
// The following checks must be done in a single call (as
// opposed to one for ')' and then one for '?', '*', and '+')
// to guarantee that callbacks are properly nested. We do not
// want to trigger endEntity too early in case we cross the
// boundary of an entity between the two characters.
// call handler
if (fDTDContentModelHandler != null) {
}
}
// call handler
if (fDTDContentModelHandler != null) {
}
}
// call handler
if (fDTDContentModelHandler != null) {
}
}
else {
// no occurrence specified
}
fMarkUpDepth--;
if (fContentDepth == 0) {
return;
}
}
skipSeparator(false, !scanningInternalSubset());
}
}
/**
* Scans an attlist declaration
* <p>
* <pre>
* [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
* [53] AttDef ::= S Name S AttType S DefaultDecl
* </pre>
* <p>
* <strong>Note:</strong> Called after scanning past '<!ATTLIST'
*/
// spaces
fReportEntity = false;
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL",
null);
}
// element name
reportFatalError("MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL",
null);
}
// call handler
if (fDTDHandler != null) {
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
// no space, is it the end yet?
// yes, stop here
// call handler
if (fDTDHandler != null) {
}
fMarkUpDepth--;
return;
}
else {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF",
}
}
// definitions
reportFatalError("AttNameRequiredInAttDef",
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF",
}
// type
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF",
}
// default decl
type,
// REVISIT: Should we do anything with the non-normalized
// default attribute value? -Ac
// yes--according to bug 5073. - neilg
if (fEnumerationCount != 0) {
0, fEnumerationCount);
}
}
// call handler
// Determine whether the default value to be passed should be null.
// REVISIT: should probably check whether fLiteral.ch is null instead. LM.
if (fDTDHandler != null){
}
if(nonValidatingMode){
}
}
else {
if (fDTDHandler != null){
}
if(nonValidatingMode){
}
}
skipSeparator(false, !scanningInternalSubset());
}
// call handler
if (fDTDHandler != null) {
}
fMarkUpDepth--;
fReportEntity = true;
} // scanAttlistDecl()
/**
* Scans an attribute type definition
* <p>
* <pre>
* [54] AttType ::= StringType | TokenizedType | EnumeratedType
* [55] StringType ::= 'CDATA'
* [56] TokenizedType ::= 'ID'
* | 'IDREF'
* | 'IDREFS'
* | 'ENTITY'
* | 'ENTITIES'
* | 'NMTOKEN'
* | 'NMTOKENS'
* [57] EnumeratedType ::= NotationType | Enumeration
* [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
* [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
* </pre>
* <p>
* <strong>Note:</strong> Called after scanning past '<!ATTLIST'
*
* @param elName The element type name this declaration is about.
* @param atName The attribute name this declaration is about.
*/
throws IOException, XNIException {
fEnumerationCount = 0;
/*
* Watchout: the order here is important: when a string happens to
* be a substring of another string, the longer one needs to be
* looked for first!!
*/
type = "CDATA";
}
type = "IDREFS";
}
type = "IDREF";
}
type = "ID";
}
type = "ENTITY";
}
type = "ENTITIES";
}
type = "NMTOKENS";
}
type = "NMTOKEN";
}
type = "NOTATION";
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE",
}
// open paren
int c = fEntityScanner.scanChar();
if (c != '(') {
reportFatalError("MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE",
}
fMarkUpDepth++;
do {
skipSeparator(false, !scanningInternalSubset());
reportFatalError("MSG_NAME_REQUIRED_IN_NOTATIONTYPE",
}
skipSeparator(false, !scanningInternalSubset());
c = fEntityScanner.scanChar();
} while (c == '|');
if (c != ')') {
reportFatalError("NotationTypeUnterminated",
}
fMarkUpDepth--;
}
else { // Enumeration
type = "ENUMERATION";
// open paren
int c = fEntityScanner.scanChar();
if (c != '(') {
// "OPEN_PAREN_REQUIRED_BEFORE_ENUMERATION_IN_ATTRDECL",
reportFatalError("AttTypeRequiredInAttDef",
}
fMarkUpDepth++;
do {
skipSeparator(false, !scanningInternalSubset());
reportFatalError("MSG_NMTOKEN_REQUIRED_IN_ENUMERATION",
}
skipSeparator(false, !scanningInternalSubset());
c = fEntityScanner.scanChar();
} while (c == '|');
if (c != ')') {
reportFatalError("EnumerationUnterminated",
}
fMarkUpDepth--;
}
return type;
} // scanAttType():String
/**
* Scans an attribute default declaration
* <p>
* <pre>
* [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
* </pre>
*
* @param name The name of the attribute being scanned.
* @param defaultVal The string to fill in with the default value.
*/
throws IOException, XNIException {
defaultVal.clear();
defaultType = "#REQUIRED";
}
defaultType = "#IMPLIED";
}
else {
defaultType = "#FIXED";
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL",
}
}
// AttValue
}
return defaultType;
} // ScanAttDefaultDecl
/**
* Scans an entity declaration
* <p>
* <pre>
* [70] EntityDecl ::= GEDecl | PEDecl
* [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
* [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
* [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
* [74] PEDef ::= EntityValue | ExternalID
* [75] ExternalID ::= 'SYSTEM' S SystemLiteral
* | 'PUBLIC' S PubidLiteral S SystemLiteral
* [76] NDataDecl ::= S 'NDATA' S Name
* </pre>
* <p>
* <strong>Note:</strong> Called after scanning past '<!ENTITY'
*/
boolean isPEDecl = false;
boolean sawPERef = false;
fReportEntity = false;
if (fEntityScanner.skipSpaces()) {
isPEDecl = false; // <!ENTITY x "x">
}
else if (skipSeparator(true, !scanningInternalSubset())) {
// <!ENTITY % x "x">
isPEDecl = true;
}
else if (scanningInternalSubset()) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL",
null);
isPEDecl = true;
}
// <!ENTITY %%x; "x"> is legal
skipSeparator(false, !scanningInternalSubset());
isPEDecl = true;
}
else {
sawPERef = true;
}
}
// <!ENTITY[^ ]...> or <!ENTITY[^ %]...>
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL",
null);
isPEDecl = false;
}
else if (fEntityScanner.skipSpaces()) {
// <!ENTITY% ...>
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL",
null);
isPEDecl = false;
}
else {
sawPERef = true;
}
if (sawPERef) {
while (true) {
}
reportFatalError("SemicolonRequiredInPEReference",
}
else {
}
break;
if (!isPEDecl) {
if (skipSeparator(true, !scanningInternalSubset())) {
isPEDecl = true;
break;
}
}
}
}
// name
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL",
}
// external id
scanExternalID(fStrings, false);
fSeenExternalPE = true;
}
// NDATA
// check whether there was space before NDATA
if (!sawSpace) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_NDATA_IN_UNPARSED_ENTITYDECL",
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL",
}
reportFatalError("MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL",
}
}
// internal entity
// since we need it's value anyway, let's snag it so it doesn't get corrupted
// if a new load takes place before we store the entity values
}
// skip possible trailing space
skipSeparator(false, !scanningInternalSubset());
// end
}
fMarkUpDepth--;
// register entity and make callback
if (isPEDecl) {
}
}
else {
}
if (fDTDHandler != null) {
//Venu Revisit : why false has been removed in expandSYstem
fResourceIdentifier.setValues(publicId, systemId, baseSystemId, XMLEntityManager.expandSystemId(systemId, baseSystemId ));
}
else {
}
}
}
else {
if (fDTDHandler != null) {
}
}
fReportEntity = true;
} // scanEntityDecl()
/**
* Scans an entity value.
*
* @param value The string to fill in with the value.
* @param nonNormalizedValue The string to fill in with the
* non-normalized value.
*
* <strong>Note:</strong> This method uses fString, fStringBuffer (through
* the use of scanCharReferenceValue), and fStringBuffer2, anything in them
* at the time of calling is lost.
*/
throws IOException, XNIException {
}
// store at which depth of entities we start
int entityDepth = fEntityDepth;
do {
}
else {
reportFatalError("NameRequiredInReference",
null);
}
else {
}
reportFatalError("SemicolonRequiredInReference",
}
else {
}
}
}
while (true) {
reportFatalError("NameRequiredInPEReference",
null);
}
reportFatalError("SemicolonRequiredInPEReference",
}
else {
if (scanningInternalSubset()) {
reportFatalError("PEReferenceWithinMarkup",
}
}
// REVISIT: [Q] Why do we skip spaces here? -Ac
// REVISIT: This will make returning the non-
// normalized value harder. -Ac
break;
}
}
else {
int c = fEntityScanner.peekChar();
if (XMLChar.isHighSurrogate(c)) {
}
else if (isInvalidLiteral(c)) {
reportFatalError("InvalidCharInLiteral",
}
// 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
fStringBuffer.append((char)c);
fStringBuffer2.append((char)c);
}
}
}
}
} // scanEntityValue(XMLString,XMLString):void
/**
* Scans a notation declaration
* <p>
* <pre>
* [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID|PublicID) S? '>'
* [83] PublicID ::= 'PUBLIC' S PubidLiteral
* </pre>
* <p>
* <strong>Note:</strong> Called after scanning past '<!NOTATION'
*/
// spaces
fReportEntity = false;
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL",
null);
}
// notation name
reportFatalError("MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL",
null);
}
// spaces
if (!skipSeparator(true, !scanningInternalSubset())) {
reportFatalError("MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL",
}
// external id
scanExternalID(fStrings, true);
reportFatalError("ExternalIDorPublicIDRequired",
}
// skip possible trailing space
skipSeparator(false, !scanningInternalSubset());
// end
}
fMarkUpDepth--;
fResourceIdentifier.setValues(publicId, systemId, baseSystemId, XMLEntityManager.expandSystemId(systemId, baseSystemId ));
// call handler
if (fDTDHandler != null) {
//Venu Revisit wby false has been removed.
//fResourceIdentifier.setValues(publicId, systemId, baseSystemId, XMLEntityManager.expandSystemId(systemId, baseSystemId, false));
}
fReportEntity = true;
} // scanNotationDecl()
/**
* Scans a conditional section. If it's a section to ignore the whole
* section gets scanned through and this method only returns after the
* closing bracket has been found. When it's an include section though, it
* returns to let the main loop take care of scanning it. In that case the
* end of the section if handled by the main loop (scanDecls).
* <p>
* <pre>
* [61] conditionalSect ::= includeSect | ignoreSect
* [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
* [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
* [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
* [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
* </pre>
* <p>
* <strong>Note:</strong> Called after scanning past '<![' */
throws IOException, XNIException {
fReportEntity = false;
skipSeparator(false, !scanningInternalSubset());
skipSeparator(false, !scanningInternalSubset());
"INVALID_PE_IN_CONDITIONAL",
}
// call handler
}
if (fDTDHandler != null) {
null);
}
// just stop there and go back to the main loop
fReportEntity = true;
}
skipSeparator(false, !scanningInternalSubset());
"INVALID_PE_IN_CONDITIONAL",
}
// call handler
if (fDTDHandler != null) {
null);
}
}
fReportEntity = true;
int initialDepth = ++fIncludeSectDepth;
if (fDTDHandler != null) {
}
while (true) {
if (fDTDHandler != null) {
}
//
// These tests are split so that we handle cases like
// '<<![' and '<!<![' which we might otherwise miss.
//
if (fDTDHandler != null) {
}
} else {
if (fDTDHandler != null) {
}
}
}
}
if (fDTDHandler != null) {
}
//
// The same thing goes for ']<![' and '<]]>', etc.
//
if (fDTDHandler != null) {
}
/* empty loop body */
if (fDTDHandler != null) {
}
}
if (fIncludeSectDepth-- == initialDepth) {
fMarkUpDepth--;
// call handler
if (fDTDHandler != null) {
}
return;
} else if(fDTDHandler != null) {
}
}
}
}
else {
int c = fEntityScanner.scanChar();
if (fScannerState == SCANNER_STATE_END_OF_INPUT) {
return;
}
if (fDTDHandler != null) {
fIgnoreConditionalBuffer.append((char)c);
}
}
}
}
else {
}
} // scanConditionalSect()
/**
* Dispatch an XML "event".
*
* @param complete True if this method is intended to scan
* and dispatch as much as possible.
*
* @return True if there is more to scan.
*
* @throws IOException Thrown on i/o error.
* @throws XNIException Thrown on parse error.
*
*/
throws IOException, XNIException {
skipSeparator(false, true);
boolean again = true;
//System.out.println("scanDecls"+fScannerState);
fMarkUpDepth++;
fMarkUpDepth--; // we're done with this decl
}
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
null);
} else {
scanComment();
}
}
}
}
}
}
!scanningInternalSubset()) {
}
else {
fMarkUpDepth--;
reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
null);
}
}
else {
fMarkUpDepth--;
}
}
// end of conditional section?
}
// call handler
if (fDTDHandler != null) {
}
// decreaseMarkupDepth();
fMarkUpDepth--;
}
else if (scanningInternalSubset() &&
// this is the end of the internal subset, let's stop here
return false;
}
else if (fEntityScanner.skipSpaces()) {
// simply skip
}
else {
}
skipSeparator(false, true);
}
return fScannerState != SCANNER_STATE_END_OF_INPUT;
}
/**
* Skip separator. This is typically just whitespace but it can also be one
* or more parameter entity references.
* <p>
* If there are some it "expands them" by calling the corresponding entity
* from the entity manager.
* <p>
* This is recursive and will process has many refs as possible.
*
* @param spaceRequired Specify whether some leading whitespace should be
* found
* @param lookForPERefs Specify whether parameter entity references should
* be looked for
* @return True if any leading whitespace was found or the end of a
* parameter entity was crossed.
*/
throws IOException, XNIException {
}
while (true) {
}
reportFatalError("SemicolonRequiredInPEReference",
}
return true;
}
}
/*
* Element Children Content Stack
*/
private final void pushContentStack(int c) {
}
fContentStack[fContentDepth++] = c;
}
private final int popContentStack() {
return fContentStack[--fContentDepth];
}
/*
* Parameter Entity Stack
*/
}
}
/** pop the stack */
private final int popPEStack() {
}
/** look at the top of the stack */
private final boolean peekReportEntity() {
}
/*
* Utility method
*/
}
}
// private methods
private void init() {
// reset state related data
fStartDTDCalled = false;
fExtEntityDepth = 0;
fIncludeSectDepth = 0;
fMarkUpDepth = 0;
fPEDepth = 0;
fStandalone = false;
fSeenExternalDTD = false;
fSeenExternalPE = false;
// set starting state
//new SymbolTable());
}
return nvGrammarInfo;
}
} // class XMLDTDScannerImpl