You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by le...@locus.apache.org on 2000/11/01 03:03:01 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/impl XMLDTDScanner.java XMLDocumentScanner.java XMLScanner.java
lehors 00/10/31 18:03:00
Modified: java/src/org/apache/xerces/impl Tag: xerces_j_2
XMLDTDScanner.java XMLDocumentScanner.java
XMLScanner.java
Log:
moved the code to scan an attribute value from XMLDocumentScanner
to XMLScanner, so that it can be shared with the DTDScanner which needs it
to parse default attribute values.
Revision Changes Path
No revision
No revision
1.1.2.58 +20 -44 xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLDTDScanner.java
Index: XMLDTDScanner.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLDTDScanner.java,v
retrieving revision 1.1.2.57
retrieving revision 1.1.2.58
diff -u -r1.1.2.57 -r1.1.2.58
--- XMLDTDScanner.java 2000/10/31 22:57:31 1.1.2.57
+++ XMLDTDScanner.java 2000/11/01 02:02:54 1.1.2.58
@@ -65,6 +65,7 @@
import org.apache.xerces.impl.msg.XMLMessageFormatter;
import org.apache.xerces.impl.validation.GrammarPool;
+import org.apache.xerces.util.XMLAttributesImpl;
import org.apache.xerces.util.XMLChar;
import org.apache.xerces.util.XMLStringBuffer;
import org.apache.xerces.util.SymbolTable;
@@ -87,7 +88,7 @@
* @author Andy Clark, IBM
* @author Glenn Marcy, IBM
*
- * @version $Id: XMLDTDScanner.java,v 1.1.2.57 2000/10/31 22:57:31 lehors Exp $
+ * @version $Id: XMLDTDScanner.java,v 1.1.2.58 2000/11/01 02:02:54 lehors Exp $
*/
public class XMLDTDScanner
extends XMLScanner
@@ -143,6 +144,9 @@
private String[] fPseudoAttributeValues = new String[3];
+ /** Default attribute */
+ private XMLAttributesImpl fAttributes = new XMLAttributesImpl();
+
// stack of operators (either '|' or ',') in children content
private int[] fContentStack = new int[5];
private int fContentDepth; // size of the stack
@@ -155,18 +159,10 @@
private int fExtEntityDepth;// number of opened external entities
private int fIncludeSectDepth; // number of opened include sections
- private XMLStringBuffer fStringBuffer2 = new XMLStringBuffer();
private XMLString fLiteral = new XMLString();
private String[] fEnumeration = new String[5];
private int fEnumerationCount;
- // symbols
-
- private String fXmlSymbol;
- private String fXmlSpace;
- private String fDefault;
- private String fPreserve;
-
//
// Constructors
//
@@ -314,12 +310,6 @@
fMarkUpDepth = 0;
fPEDepth = 0;
- // save built-in symbols
- fXmlSymbol = fSymbolTable.addSymbol("xml");
- fXmlSpace = fSymbolTable.addSymbol("xml:space");
- fDefault = fSymbolTable.addSymbol("default");
- fPreserve = fSymbolTable.addSymbol("preserve");
-
} // reset
/**
@@ -700,8 +690,7 @@
skipSeparator(false, !scanningInternalSubset());
// end
if (!fEntityScanner.skipChar('>')) {
- reportFatalError("ElementDeclUnterminated",
- new Object[]{name});
+ reportFatalError("ElementDeclUnterminated", new Object[]{name});
}
fMarkUpDepth--;
@@ -1164,7 +1153,7 @@
}
}
// AttValue
- scanLiteral(defaultVal, false);
+ scanAttributeValue(defaultVal, atName, fAttributes, 0);
}
return defaultType;
@@ -1231,8 +1220,7 @@
while (true) {
String peName = fEntityScanner.scanName();
if (peName == null) {
- reportFatalError("NameRequiredInPEReference",
- null);
+ reportFatalError("NameRequiredInPEReference", null);
}
else if (!fEntityScanner.skipChar(';')) {
reportFatalError("SemicolonRequiredInPEReference",
@@ -1257,8 +1245,7 @@
// name
String name = fEntityScanner.scanName();
if (name == null) {
- reportFatalError("MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL",
- null);
+ reportFatalError("MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL", null);
}
// spaces
@@ -1324,8 +1311,7 @@
// end
if (!fEntityScanner.skipChar('>')) {
- reportFatalError("EntityDeclUnterminated",
- new Object[]{name});
+ reportFatalError("EntityDeclUnterminated", new Object[]{name});
}
fMarkUpDepth--;
@@ -1427,8 +1413,7 @@
// end
if (!fEntityScanner.skipChar('>')) {
- reportFatalError("NotationDeclUnterminated",
- new Object[]{name});
+ reportFatalError("NotationDeclUnterminated", new Object[]{name});
}
fMarkUpDepth--;
@@ -1467,8 +1452,7 @@
}
skipSeparator(false, !scanningInternalSubset());
if (!fEntityScanner.skipChar('[')) {
- reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
- null);
+ reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
}
fIncludeSectDepth++;
// just stop there and go back to the main loop
@@ -1480,8 +1464,7 @@
}
skipSeparator(false, !scanningInternalSubset());
if (!fEntityScanner.skipChar('[')) {
- reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
- null);
+ reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
}
int initialDepth = ++fIncludeSectDepth;
while (true) {
@@ -1524,8 +1507,7 @@
}
}
else {
- reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
- null);
+ reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
}
} // scanConditionalSect()
@@ -1584,16 +1566,14 @@
}
else {
fMarkUpDepth--;
- reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
- null);
+ 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);
+ reportFatalError("IncludeSectUnterminated", null);
}
// call handler
if (fDTDHandler != null) {
@@ -1612,8 +1592,7 @@
// simply skip
}
else {
- reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD",
- null);
+ reportFatalError("MSG_MARKUP_NOT_RECOGNIZED_IN_DTD", null);
}
skipSeparator(false, true);
}
@@ -1647,8 +1626,7 @@
while (true) {
String name = fEntityScanner.scanName();
if (name == null) {
- reportFatalError("NameRequiredInPEReference",
- null);
+ reportFatalError("NameRequiredInPEReference", null);
}
else if (!fEntityScanner.skipChar(';')) {
reportFatalError("SemicolonRequiredInPEReference",
@@ -1666,8 +1644,7 @@
{
int quote = fEntityScanner.scanChar();
if (quote != '\'' && quote != '"') {
- reportFatalError("OpenQuoteMissingInDecl",
- null);
+ reportFatalError("OpenQuoteMissingInDecl", null);
}
XMLString value = fString;
if (fEntityScanner.scanLiteral(quote, fString) != quote) {
@@ -1729,8 +1706,7 @@
}
literal.setValues(value);
if (!fEntityScanner.skipChar(quote)) {
- reportFatalError("REVISIT: CloseQuoteMissingInDecl",
- null);
+ reportFatalError("CloseQuoteMissingInDecl", null);
}
}
1.1.2.56 +15 -288 xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLDocumentScanner.java
Index: XMLDocumentScanner.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLDocumentScanner.java,v
retrieving revision 1.1.2.55
retrieving revision 1.1.2.56
diff -u -r1.1.2.55 -r1.1.2.56
--- XMLDocumentScanner.java 2000/10/31 22:58:57 1.1.2.55
+++ XMLDocumentScanner.java 2000/11/01 02:02:55 1.1.2.56
@@ -102,7 +102,7 @@
* @author Andy Clark, IBM
* @author Arnaud Le Hors, IBM
*
- * @version $Id: XMLDocumentScanner.java,v 1.1.2.55 2000/10/31 22:58:57 lehors Exp $
+ * @version $Id: XMLDocumentScanner.java,v 1.1.2.56 2000/11/01 02:02:55 lehors Exp $
*/
public class XMLDocumentScanner
extends XMLScanner
@@ -176,9 +176,6 @@
/** Debug content dispatcher scanning. */
private static final boolean DEBUG_CONTENT_SCANNING = false;
- /** Debug attribute entities. */
- private static final boolean DEBUG_ATTR_ENTITIES = false;
-
//
// Data
//
@@ -196,9 +193,6 @@
/** Entity stack. */
protected int[] fEntityStack = new int[4];
- /** Entity depth. */
- protected int fEntityDepth;
-
/** True if we started some markup. */
protected boolean fInMarkup;
@@ -211,9 +205,6 @@
/** Standalone. */
protected boolean fStandalone;
- /** Scanning attribute. */
- protected boolean fScanningAttribute;
-
/** Scanning DTD. */
protected boolean fScanningDTD;
@@ -228,12 +219,6 @@
/** Element stack. */
protected ElementStack fElementStack = new ElementStack();
- /** Attribute entity stack. */
- protected AttrEntityStack fAttributeEntityStack = new AttrEntityStack();
-
- /** Attribute value offset. */
- protected int fAttributeOffset;
-
// features
/** Namespaces. */
@@ -270,31 +255,15 @@
/** Single character array. */
private final char[] fSingleChar = new char[1];
- /** String buffer. */
- private XMLStringBuffer fStringBuffer2 = new XMLStringBuffer();
-
/** External entity. */
private XMLEntityManager.ExternalEntity fExternalEntity = new XMLEntityManager.ExternalEntity();
/** Pseudo-attribute values. */
private String[] fPseudoAttributeValues = new String[3];
-
- // symbols
-
- /** Symbol: "amp". */
- private String fAmpSymbol;
-
- /** Symbol: "lt". */
- private String fLtSymbol;
- /** Symbol: "gt". */
- private String fGtSymbol;
+ private XMLString fLiteral = new XMLString();
- /** Symbol: "quot". */
- private String fQuotSymbol;
-
- /** Symbol: "apos". */
- private String fAposSymbol;
+ // symbols
/** Symbol: "CDATA". */
private String fCDATASymbol;
@@ -365,7 +334,6 @@
fDTDScanner = (XMLDTDScanner)componentManager.getProperty(DTD_SCANNER);
// initialize vars
- fEntityDepth = 0;
fInMarkup = false;
fElementDepth = 0;
fCurrentElement = null;
@@ -375,11 +343,6 @@
fScanningDTD = false;
// save built-in entity names
- fAmpSymbol = fSymbolTable.addSymbol("amp");
- fLtSymbol = fSymbolTable.addSymbol("lt");
- fGtSymbol = fSymbolTable.addSymbol("gt");
- fQuotSymbol = fSymbolTable.addSymbol("quot");
- fAposSymbol = fSymbolTable.addSymbol("apos");
fCDATASymbol = fSymbolTable.addSymbol("CDATA");
// setup dispatcher
@@ -462,27 +425,21 @@
public void startEntity(String name, String publicId, String systemId,
String encoding) throws SAXException {
+ super.startEntity(name, publicId, systemId, encoding);
+
// keep track of this entity
- if (fEntityDepth == fEntityStack.length) {
+ if (fEntityDepth > fEntityStack.length) {
int[] entityarray = new int[fEntityStack.length * 2];
System.arraycopy(fEntityStack, 0, entityarray, 0, fEntityStack.length);
fEntityStack = entityarray;
}
- fEntityStack[fEntityDepth++] = fElementDepth;
+ fEntityStack[fEntityDepth] = fElementDepth;
// prepare to look for a TextDecl if external general entity
if (!name.equals("[xml]") && fEntityScanner.isExternal()) {
setScannerState(SCANNER_STATE_TEXT_DECL);
}
- // keep track of entities appearing in attribute values
- if (fScanningAttribute) {
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** pushAttrEntity("+name+','+fAttributeOffset+')');
- }
- fAttributeEntityStack.pushAttrEntity(name, fAttributeOffset);
- }
-
// call handler
if (fDocumentHandler != null) {
if (!fScanningAttribute) {
@@ -507,20 +464,14 @@
*/
public void endEntity(String name) throws SAXException {
+ super.endEntity(name);
+
// make sure elements are balanced
- if (fElementDepth != fEntityStack[--fEntityDepth]) {
+ if (fElementDepth != fEntityStack[fEntityDepth]) {
reportFatalError("ElementEntityMismatch",
new Object[]{fCurrentElement.rawname});
}
- // keep track of entities appearing in attribute values
- if (fScanningAttribute) {
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** popAttrEntity("+fAttributeOffset+") \""+name+'"');
- }
- fAttributeEntityStack.popAttrEntity(fAttributeOffset);
- }
-
// make sure markup is properly balanced
else if (fInMarkup) {
fInMarkup = false;
@@ -877,7 +828,6 @@
* <p>
* <pre>
* [41] Attribute ::= Name Eq AttValue
- * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
* </pre>
* <p>
* <strong>Note:</strong> This method assumes that the next
@@ -908,152 +858,14 @@
}
fEntityScanner.skipSpaces();
- // quote
- int quote = fEntityScanner.peekChar();
- if (quote != '\'' && quote != '"') {
- reportFatalError("OpenQuoteExpected",
- new Object[]{fAttributeQName.rawname});
- }
- fEntityScanner.scanChar();
- int entityDepth = fEntityDepth;
-
// content
attributes.addAttribute(fAttributeQName, fCDATASymbol, null);
- XMLString value = fString;
- int c = fEntityScanner.scanLiteral(quote, fString);
- if (c != quote) {
- fScanningAttribute = true;
- int attrIndex = attributes.getLength() - 1;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** reset attribute entity stack");
- }
- fAttributeEntityStack.reset(attributes, attrIndex);
- fAttributeOffset = 0;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** set attribute offset: "+fAttributeOffset);
- }
- fStringBuffer2.clear();
- do {
- fStringBuffer2.append(fString);
- fAttributeOffset += fString.length;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** increment attribute offset: "+fAttributeOffset);
- }
- if (c == '&') {
- fEntityScanner.skipChar('&');
- if (fEntityScanner.skipChar('#')) {
- int ch = scanCharReferenceValue(fStringBuffer2);
- if (ch != -1) {
- fAttributeOffset++;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** increment attribute offset: "+fAttributeOffset);
- }
- }
- }
- else {
- String entityName = fEntityScanner.scanName();
- if (entityName == null) {
- reportFatalError("NameRequiredInReference", null);
- }
- if (!fEntityScanner.skipChar(';')) {
- reportFatalError("SemicolonRequiredInReference",
- null);
- }
- if (entityName == fAmpSymbol) {
- fStringBuffer2.append('&');
- fAttributeOffset++;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** increment attribute offset: "+fAttributeOffset);
- }
- }
- else if (entityName == fAposSymbol) {
- fStringBuffer2.append('\'');
- fAttributeOffset++;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** increment attribute offset: "+fAttributeOffset);
- }
- }
- else if (entityName == fLtSymbol) {
- fStringBuffer2.append('<');
- fAttributeOffset++;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** increment attribute offset: "+fAttributeOffset);
- }
- }
- else if (entityName == fGtSymbol) {
- fStringBuffer2.append('>');
- fAttributeOffset++;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** increment attribute offset: "+fAttributeOffset);
- }
- }
- else if (entityName == fQuotSymbol) {
- fStringBuffer2.append('"');
- fAttributeOffset++;
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** increment attribute offset: "+fAttributeOffset);
- }
- }
- else {
- if (fEntityManager.isExternalEntity(entityName)) {
- reportFatalError("ReferenceToExternalEntity",
- new Object[] { entityName });
- }
- else {
- fEntityManager.startEntity(entityName, false);
- }
- }
- }
- }
- else if (c == '<') {
- reportFatalError("LessthanInAttValue",
- new Object[] { null,
- fAttributeQName.rawname });
- }
- else if (c == '%') {
- fStringBuffer2.append((char)fEntityScanner.scanChar());
- }
- else if (c != -1 && XMLChar.isHighSurrogate(c)) {
- scanSurrogates(fStringBuffer2);
- }
- else if (c != -1 && XMLChar.isInvalid(c)) {
- reportFatalError("InvalidCharInAttValue",
- new Object[] {Integer.toString(c, 16)});
- fEntityScanner.scanChar();
- }
- while (true) {
- c = fEntityScanner.scanLiteral(quote, fString);
- if (c != quote || entityDepth == fEntityDepth) {
- break;
- }
- fStringBuffer2.append(fString);
- fStringBuffer2.append((char)fEntityScanner.scanChar());
- }
- } while (c != quote);
- fAttributeOffset += fString.length;
- fStringBuffer2.append(fString);
- value = fStringBuffer2;
- int attrEntityCount = fAttributeEntityStack.size();
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** add remaining attribute entities: "+attrEntityCount);
- }
- for (int i = 0; i < attrEntityCount; i++) {
- if (DEBUG_ATTR_ENTITIES) {
- System.out.println("*** popAttrEntity("+fAttributeOffset+')');
- }
- fAttributeEntityStack.popAttrEntity(fAttributeOffset);
- }
- fScanningAttribute = false;
- }
- attributes.setValue(attributes.getLength() - 1, value.toString());
-
- // quote
- int cquote = fEntityScanner.scanChar();
- if (cquote != cquote) {
- reportFatalError("CloseQuoteExpected",
- new Object[]{fAttributeQName.rawname});
- }
+ scanAttributeValue(fLiteral, fAttributeQName.rawname,
+ attributes, attributes.getLength() - 1);
+
+ attributes.setValue(attributes.getLength() - 1, fLiteral.toString());
+
if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanAttribute()");
} // scanAttribute(XMLAttributes)
@@ -1491,91 +1303,6 @@
} // clear()
} // class ElementStack
-
- /**
- * A stack for keeping track of entity offsets and lengths in
- * attribute values. This stack adds the attribute entities to
- * a specified XMLAttribute object.
- *
- * @author Andy Clark, IBM
- */
- protected static class AttrEntityStack {
-
- //
- // Data
- //
-
- /** Attributes. */
- protected XMLAttributes fAttributes;
-
- /** The index of the attribute where to add entities. */
- protected int fAttributeIndex;
-
- // stack information
-
- /** The size of the stack. */
- protected int fSize;
-
- /** The entity indexes on the stack. */
- protected int[] fEntityIndexes = new int[4];
-
- //
- // Public methods
- //
-
- /**
- * Resets the attribute entity stack and sets the attributes
- * object to add entities to.
- *
- * @param attributes The attributes object where new attribute
- * entities are added.
- * @param attrIndex The index of the attribute where to add
- * entities.
- */
- public void reset(XMLAttributes attributes, int attrIndex) {
- fAttributes = attributes;
- fAttributeIndex = attrIndex;
- fSize = 0;
- } // reset(XMLAttributes,int)
-
- /** Returns the size of the stack. */
- public int size() {
- return fSize;
- } // size():int
-
- /**
- * Pushes a new entity onto the stack.
- *
- * @param entityName The entity name.
- * @param entityOffset The entity offset.
- */
- public void pushAttrEntity(String entityName, int entityOffset) {
- if (fSize == fEntityIndexes.length) {
- int[] indexarray = new int[fEntityIndexes.length * 2];
- System.arraycopy(fEntityIndexes, 0, indexarray, 0, fEntityIndexes.length);
- fEntityIndexes = indexarray;
- }
- fEntityIndexes[fSize] =
- fAttributes.addAttributeEntity(fAttributeIndex, entityName,
- entityOffset, -1);
- fSize++;
- } // pushAttrEntity(String,int)
-
- /**
- * Pops the current entity off of the stack and adds it to the
- * list of entities for the attribute in the XMLAttributes object.
- *
- * @param endOffset The entity's ending offset.
- */
- public void popAttrEntity(int endOffset) {
- fSize--;
- int entityIndex = fEntityIndexes[fSize];
- int offset = fAttributes.getEntityOffset(fAttributeIndex, entityIndex);
- int length = endOffset - offset;
- fAttributes.setEntityLength(fAttributeIndex, entityIndex, length);
- } // popAttrEntity(int)
-
- } // class AttrEntityStack
/**
* This interface defines an XML "event" dispatching model. Classes
1.1.2.24 +360 -4 xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLScanner.java
Index: XMLScanner.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLScanner.java,v
retrieving revision 1.1.2.23
retrieving revision 1.1.2.24
diff -u -r1.1.2.23 -r1.1.2.24
--- XMLScanner.java 2000/10/31 22:57:31 1.1.2.23
+++ XMLScanner.java 2000/11/01 02:02:55 1.1.2.24
@@ -66,6 +66,7 @@
import org.apache.xerces.util.SymbolTable;
import org.apache.xerces.util.XMLStringBuffer;
import org.apache.xerces.util.XMLChar;
+import org.apache.xerces.xni.XMLAttributes;
import org.apache.xerces.xni.XMLComponent;
import org.apache.xerces.xni.XMLComponentManager;
import org.apache.xerces.xni.XMLString;
@@ -92,7 +93,7 @@
* @author Andy Clark, IBM
* @author Arnaud Le Hors, IBM
*
- * @version $Id: XMLScanner.java,v 1.1.2.23 2000/10/31 22:57:31 lehors Exp $
+ * @version $Id: XMLScanner.java,v 1.1.2.24 2000/11/01 02:02:55 lehors Exp $
*/
public abstract class XMLScanner
implements XMLComponent {
@@ -114,28 +115,63 @@
/** Entity scanner. */
protected XMLEntityScanner fEntityScanner;
+ /** Entity depth. */
+ protected int fEntityDepth;
+
/** String. */
protected XMLString fString = new XMLString();
/** String buffer. */
protected XMLStringBuffer fStringBuffer = new XMLStringBuffer();
+ /** String buffer. */
+ protected XMLStringBuffer fStringBuffer2 = new XMLStringBuffer();
+
/** Error reporter. */
protected XMLErrorReporter fErrorReporter;
+ /** Attribute entity stack. */
+ protected AttrEntityStack fAttributeEntityStack = new AttrEntityStack();
+
+ /** Attribute value offset. */
+ protected int fAttributeOffset;
+
+ /** Scanning attribute. */
+ protected boolean fScanningAttribute;
+
+ // debugging
+
+ /** Debug attribute entities. */
+ protected static final boolean DEBUG_ATTR_ENTITIES = false;
+
// private data
// symbols
/** Symbol: "version". */
- private String fVersionSymbol;
+ protected String fVersionSymbol;
/** Symbol: "encoding". */
- private String fEncodingSymbol;
+ protected String fEncodingSymbol;
/** Symbol: "standalone". */
- private String fStandaloneSymbol;
+ protected String fStandaloneSymbol;
+
+ /** Symbol: "amp". */
+ protected String fAmpSymbol;
+
+ /** Symbol: "lt". */
+ protected String fLtSymbol;
+
+ /** Symbol: "gt". */
+ protected String fGtSymbol;
+
+ /** Symbol: "quot". */
+ protected String fQuotSymbol;
+ /** Symbol: "apos". */
+ protected String fAposSymbol;
+
// pseudo-attribute values
/** Pseudo-attribute string buffer. */
@@ -167,10 +203,18 @@
// initialize scanner
fEntityScanner = fEntityManager.getEntityScanner();
+ // initialize vars
+ fEntityDepth = 0;
+
// save built-in entity names
fVersionSymbol = fSymbolTable.addSymbol("version");
fEncodingSymbol = fSymbolTable.addSymbol("encoding");
fStandaloneSymbol = fSymbolTable.addSymbol("standalone");
+ fAmpSymbol = fSymbolTable.addSymbol("amp");
+ fLtSymbol = fSymbolTable.addSymbol("lt");
+ fGtSymbol = fSymbolTable.addSymbol("gt");
+ fQuotSymbol = fSymbolTable.addSymbol("quot");
+ fAposSymbol = fSymbolTable.addSymbol("apos");
} // reset(XMLComponentManager)
@@ -514,7 +558,228 @@
} // scanComment()
+ /**
+ * Scans an attribute value.
+ *
+ * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
+ *
+ * @param value The XMLString to fill in with the value.
+ * @param atName The name of the attribute being parsed (for error msgs).
+ * @param attributes The attributes list for the scanned attribute.
+ * @param attrIndex The index of the attribute to use from the list.
+ *
+ * <strong>Note:</strong> This method uses fString and fStringBuffer2,
+ * anything in it at the time of calling is lost.
+ **/
+ protected void scanAttributeValue(XMLString value, String atName,
+ XMLAttributes attributes, int attrIndex)
+ throws IOException, SAXException
+ {
+ // quote
+ int quote = fEntityScanner.peekChar();
+ if (quote != '\'' && quote != '"') {
+ reportFatalError("OpenQuoteExpected", new Object[]{atName});
+ }
+
+ fEntityScanner.scanChar();
+ int entityDepth = fEntityDepth;
+ int c = fEntityScanner.scanLiteral(quote, fString);
+ if (c != quote) {
+ fScanningAttribute = true;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** reset attribute entity stack");
+ }
+ fAttributeEntityStack.reset(attributes, attrIndex);
+ fAttributeOffset = 0;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** set attribute offset: "+fAttributeOffset);
+ }
+ fStringBuffer2.clear();
+ do {
+ fStringBuffer2.append(fString);
+ fAttributeOffset += fString.length;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** increment attribute offset: "+fAttributeOffset);
+ }
+ if (c == '&') {
+ fEntityScanner.skipChar('&');
+ if (fEntityScanner.skipChar('#')) {
+ int ch = scanCharReferenceValue(fStringBuffer2);
+ if (ch != -1) {
+ fAttributeOffset++;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** increment attribute offset: "+fAttributeOffset);
+ }
+ }
+ }
+ else {
+ String entityName = fEntityScanner.scanName();
+ if (entityName == null) {
+ reportFatalError("NameRequiredInReference", null);
+ }
+ if (!fEntityScanner.skipChar(';')) {
+ reportFatalError("SemicolonRequiredInReference",
+ null);
+ }
+ if (entityName == fAmpSymbol) {
+ fStringBuffer2.append('&');
+ fAttributeOffset++;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** increment attribute offset: "+fAttributeOffset);
+ }
+ }
+ else if (entityName == fAposSymbol) {
+ fStringBuffer2.append('\'');
+ fAttributeOffset++;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** increment attribute offset: "+fAttributeOffset);
+ }
+ }
+ else if (entityName == fLtSymbol) {
+ fStringBuffer2.append('<');
+ fAttributeOffset++;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** increment attribute offset: "+fAttributeOffset);
+ }
+ }
+ else if (entityName == fGtSymbol) {
+ fStringBuffer2.append('>');
+ fAttributeOffset++;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** increment attribute offset: "+fAttributeOffset);
+ }
+ }
+ else if (entityName == fQuotSymbol) {
+ fStringBuffer2.append('"');
+ fAttributeOffset++;
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** increment attribute offset: "+fAttributeOffset);
+ }
+ }
+ else {
+ if (fEntityManager.isExternalEntity(entityName)) {
+ reportFatalError("ReferenceToExternalEntity",
+ new Object[] { entityName });
+ }
+ else {
+ fEntityManager.startEntity(entityName, false);
+ }
+ }
+ }
+ }
+ else if (c == '<') {
+ reportFatalError("LessthanInAttValue",
+ new Object[] { null, atName });
+ }
+ else if (c == '%') {
+ fStringBuffer2.append((char)fEntityScanner.scanChar());
+ }
+ else if (c != -1 && XMLChar.isHighSurrogate(c)) {
+ scanSurrogates(fStringBuffer2);
+ }
+ else if (c != -1 && XMLChar.isInvalid(c)) {
+ reportFatalError("InvalidCharInAttValue",
+ new Object[] {Integer.toString(c, 16)});
+ fEntityScanner.scanChar();
+ }
+ while (true) {
+ c = fEntityScanner.scanLiteral(quote, fString);
+ if (c != quote || entityDepth == fEntityDepth) {
+ break;
+ }
+ fStringBuffer2.append(fString);
+ fStringBuffer2.append((char)fEntityScanner.scanChar());
+ }
+ } while (c != quote);
+ fAttributeOffset += fString.length;
+ fStringBuffer2.append(fString);
+ value = fStringBuffer2;
+ int attrEntityCount = fAttributeEntityStack.size();
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** add remaining attribute entities: "+attrEntityCount);
+ }
+ for (int i = 0; i < attrEntityCount; i++) {
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** popAttrEntity("+fAttributeOffset+')');
+ }
+ fAttributeEntityStack.popAttrEntity(fAttributeOffset);
+ }
+ fScanningAttribute = false;
+ }
+
+ // quote
+ int cquote = fEntityScanner.scanChar();
+ if (cquote != cquote) {
+ reportFatalError("CloseQuoteExpected", new Object[]{atName});
+ }
+ } // scanAttributeValue()
+
+
+ //
+ // XMLEntityHandler methods
+ //
+
+ /**
+ * This method notifies of the start of an entity. The document entity
+ * has the pseudo-name of "[xml]"; 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 publicId The public identifier of the entity if the entity
+ * is external, null otherwise.
+ * @param systemId The system identifier of the entity if the entity
+ * is external, null otherwise.
+ * @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).
+ *
+ * @throws SAXException Thrown by handler to signal an error.
+ */
+ public void startEntity(String name, String publicId, String systemId,
+ String encoding) throws SAXException {
+
+ // keep track of the entity depth
+ fEntityDepth++;
+
+ // keep track of entities appearing in attribute values
+ if (fScanningAttribute) {
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** pushAttrEntity("+name+','+fAttributeOffset+')');
+ }
+ fAttributeEntityStack.pushAttrEntity(name, fAttributeOffset);
+ }
+ } // startEntity(String,String,String,String)
+
+ /**
+ * This method notifies the end of an entity. The document entity has
+ * the pseudo-name of "[xml]"; 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 SAXException Thrown by handler to signal an error.
+ */
+ public void endEntity(String name) throws SAXException {
+
+ // keep track of the entity depth
+ fEntityDepth--;
+
+ // keep track of entities appearing in attribute values
+ if (fScanningAttribute) {
+ if (DEBUG_ATTR_ENTITIES) {
+ System.out.println("*** popAttrEntity("+fAttributeOffset+") \""+name+'"');
+ }
+ fAttributeEntityStack.popAttrEntity(fAttributeOffset);
+ }
+ }
+
+
+
/**
* Scans a character reference and append the corresponding chars to the
* specified buffer.
@@ -629,11 +894,102 @@
} // scanSurrogates():boolean
+
+
+ /**
+ * Convenience function used in all XML scanners.
+ */
protected void reportFatalError(String msgId, Object[] args)
throws SAXException {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
msgId, args,
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
+
+
+ /**
+ * A stack for keeping track of entity offsets and lengths in
+ * attribute values. This stack adds the attribute entities to
+ * a specified XMLAttribute object.
+ *
+ * @author Andy Clark, IBM
+ */
+ protected static class AttrEntityStack {
+
+ //
+ // Data
+ //
+
+ /** Attributes. */
+ protected XMLAttributes fAttributes;
+
+ /** The index of the attribute where to add entities. */
+ protected int fAttributeIndex;
+
+ // stack information
+
+ /** The size of the stack. */
+ protected int fSize;
+
+ /** The entity indexes on the stack. */
+ protected int[] fEntityIndexes = new int[4];
+
+ //
+ // Public methods
+ //
+
+ /**
+ * Resets the attribute entity stack and sets the attributes
+ * object to add entities to.
+ *
+ * @param attributes The attributes object where new attribute
+ * entities are added.
+ * @param attrIndex The index of the attribute where to add
+ * entities.
+ */
+ public void reset(XMLAttributes attributes, int attrIndex) {
+ fAttributes = attributes;
+ fAttributeIndex = attrIndex;
+ fSize = 0;
+ } // reset(XMLAttributes,int)
+
+ /** Returns the size of the stack. */
+ public int size() {
+ return fSize;
+ } // size():int
+
+ /**
+ * Pushes a new entity onto the stack.
+ *
+ * @param entityName The entity name.
+ * @param entityOffset The entity offset.
+ */
+ public void pushAttrEntity(String entityName, int entityOffset) {
+ if (fSize == fEntityIndexes.length) {
+ int[] indexarray = new int[fEntityIndexes.length * 2];
+ System.arraycopy(fEntityIndexes, 0, indexarray, 0, fEntityIndexes.length);
+ fEntityIndexes = indexarray;
+ }
+ fEntityIndexes[fSize] =
+ fAttributes.addAttributeEntity(fAttributeIndex, entityName,
+ entityOffset, -1);
+ fSize++;
+ } // pushAttrEntity(String,int)
+
+ /**
+ * Pops the current entity off of the stack and adds it to the
+ * list of entities for the attribute in the XMLAttributes object.
+ *
+ * @param endOffset The entity's ending offset.
+ */
+ public void popAttrEntity(int endOffset) {
+ fSize--;
+ int entityIndex = fEntityIndexes[fSize];
+ int offset = fAttributes.getEntityOffset(fAttributeIndex, entityIndex);
+ int length = endOffset - offset;
+ fAttributes.setEntityLength(fAttributeIndex, entityIndex, length);
+ } // popAttrEntity(int)
+
+ } // class AttrEntityStack
} // class XMLScanner