You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2003/10/02 20:24:15 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/impl XML11NSDocumentScannerImpl.java
mrglavas 2003/10/02 11:24:15
Modified: java/src/org/apache/xerces/impl
XML11NSDocumentScannerImpl.java
Log:
Fixing indentation.
Revision Changes Path
1.2 +532 -481 xml-xerces/java/src/org/apache/xerces/impl/XML11NSDocumentScannerImpl.java
Index: XML11NSDocumentScannerImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/XML11NSDocumentScannerImpl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- XML11NSDocumentScannerImpl.java 2 Oct 2003 18:18:15 -0000 1.1
+++ XML11NSDocumentScannerImpl.java 2 Oct 2003 18:24:15 -0000 1.2
@@ -99,489 +99,540 @@
*
* @author Elena Litani, IBM
* @author Michael Glavassevich, IBM
+ *
+ * @version
*/
public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
- /**
- * If is true, the dtd validator is no longer in the pipeline
- * and the scanner should bind namespaces
- */
- protected boolean fBindNamespaces;
-
- /**
- * If validating parser, make sure we report an error in the
- * scanner if DTD grammar is missing.
- */
- protected boolean fPerformValidation;
-
- protected String[] fUri= new String[4];
- protected String[] fLocalpart = new String[4];
- protected int fLength = 0;
-
-
- // private data
- //
-
- /** DTD validator */
- private XMLDTDValidatorFilter fDTDValidator;
-
- /**
- * The scanner is responsible for removing DTD validator
- * from the pipeline if it is not needed.
- *
- * @param validator the DTD validator from the pipeline
- */
- public void setDTDValidator(XMLDTDValidatorFilter validator){
- fDTDValidator = validator;
- }
-
- /**
- * Scans a start element. This method will handle the binding of
- * namespace information and notifying the handler of the start
- * of the element.
- * <p>
- * <pre>
- * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
- * [40] STag ::= '<' Name (S Attribute)* S? '>'
- * </pre>
- * <p>
- * <strong>Note:</strong> This method assumes that the leading
- * '<' character has been consumed.
- * <p>
- * <strong>Note:</strong> This method uses the fElementQName and
- * fAttributes variables. The contents of these variables will be
- * destroyed. The caller should copy important information out of
- * these variables before calling this method.
- *
- * @return True if element is empty. (i.e. It matches
- * production [44].
- */
- protected boolean scanStartElement()
- throws IOException, XNIException {
- if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanStartElementNS()");
-
- // Note: namespace processing is on by default
- fEntityScanner.scanQName(fElementQName);
- // REVISIT - [Q] Why do we need this local variable? -- mrglavas
- String rawname = fElementQName.rawname;
- if (fBindNamespaces) {
- fNamespaceContext.pushContext();
- if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) {
- if (fPerformValidation) {
- fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
- "MSG_GRAMMAR_NOT_FOUND",
- new Object[]{ rawname},
- XMLErrorReporter.SEVERITY_ERROR);
-
- if (fDoctypeName == null || !fDoctypeName.equals(rawname)) {
- fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
- "RootElementTypeMustMatchDoctypedecl",
- new Object[]{fDoctypeName, rawname},
- XMLErrorReporter.SEVERITY_ERROR);
- }
- }
- }
- }
-
- // push element stack
- fCurrentElement = fElementStack.pushElement(fElementQName);
-
- // attributes
- boolean empty = false;
- fAttributes.removeAllAttributes();
- do {
- // spaces
- boolean sawSpace = fEntityScanner.skipSpaces();
-
- // end tag?
- int c = fEntityScanner.peekChar();
- if (c == '>') {
- fEntityScanner.scanChar();
- break;
- }
- else if (c == '/') {
- fEntityScanner.scanChar();
- if (!fEntityScanner.skipChar('>')) {
- reportFatalError("ElementUnterminated",
- new Object[]{rawname});
- }
- empty = true;
- break;
- }
- else if (!isValidNameStartChar(c) || !sawSpace) {
- reportFatalError("ElementUnterminated", new Object[]{rawname});
- }
-
- // attributes
- scanAttribute(fAttributes);
-
- } while (true);
-
- if (fBindNamespaces) {
- // REVISIT: is it required? forbit xmlns prefix for element
- if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "ElementXMLNSPrefix",
- new Object[]{fElementQName.rawname},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // bind the element
- String prefix = fElementQName.prefix != null
- ? fElementQName.prefix : XMLSymbols.EMPTY_STRING;
- // assign uri to the element
- fElementQName.uri = fNamespaceContext.getURI(prefix);
- // make sure that object in the element stack is updated as well
- fCurrentElement.uri = fElementQName.uri;
-
- if (fElementQName.prefix == null && fElementQName.uri != null) {
- fElementQName.prefix = XMLSymbols.EMPTY_STRING;
- }
- if (fElementQName.prefix != null && fElementQName.uri == null) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "ElementPrefixUnbound",
- new Object[]{fElementQName.prefix, fElementQName.rawname},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // bind attributes (xmlns are already bound bellow)
- int length = fAttributes.getLength();
- fLength = 0; //initialize structure
- for (int i = 0; i < length; i++) {
- fAttributes.getName(i, fAttributeQName);
-
- String aprefix = fAttributeQName.prefix != null
- ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
- String uri = fNamespaceContext.getURI(aprefix);
- // REVISIT: try removing the first "if" and see if it is faster.
- //
- if (fAttributeQName.uri != null && fAttributeQName.uri == uri) {
- checkDuplicates(fAttributeQName, fAttributes);
- continue;
- }
- if (aprefix != XMLSymbols.EMPTY_STRING) {
- fAttributeQName.uri = uri;
- if (uri == null) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "AttributePrefixUnbound",
- new Object[]{fElementQName.rawname,fAttributeQName.rawname,aprefix},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- fAttributes.setURI(i, uri);
- checkDuplicates(fAttributeQName, fAttributes);
- }
- }
- }
-
-
- // call handler
- if (fDocumentHandler != null) {
- if (empty) {
-
- //decrease the markup depth..
- fMarkupDepth--;
-
- // check that this element was opened in the same entity
- if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
- reportFatalError("ElementEntityMismatch",
- new Object[]{fCurrentElement.rawname});
- }
-
- fDocumentHandler.emptyElement(fElementQName, fAttributes, null);
-
- if (fBindNamespaces) {
- fNamespaceContext.popContext();
- }
- //pop the element off the stack..
- fElementStack.popElement(fElementQName);
- } else {
- fDocumentHandler.startElement(fElementQName, fAttributes, null);
- }
- }
-
- if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanStartElement(): "+empty);
- return empty;
-
- } // scanStartElement():boolean
-
- private final void checkDuplicates(QName qname, XMLAttributesImpl attributes){
-
- // Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
- // search if such attribute already exists
- for (int i = 0; i < fLength; i++) {
- if (qname.uri == fUri[i] && fLocalpart[i].equals(qname.localpart)) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "AttributeNSNotUnique",
- new Object[]{fElementQName.rawname,qname.rawname, qname.uri},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- }
- int index = fLength;
- if (fLength++ == fUri.length) {
- String[] uris = new String[fUri.length + 4];
- String[] lps = new String [fUri.length + 4];
- System.arraycopy(fUri, 0, uris, 0, fUri.length);
- System.arraycopy(fLocalpart, 0, lps, 0, fLocalpart.length);
- fUri = uris;
- fLocalpart = lps;
-
- }
-
- fUri[index] = qname.uri;
- fLocalpart[index] = qname.localpart;
- }
-
-
-
-
- /**
- * Scans an attribute.
- * <p>
- * <pre>
- * [41] Attribute ::= Name Eq AttValue
- * </pre>
- * <p>
- * <strong>Note:</strong> This method assumes that the next
- * character on the stream is the first character of the attribute
- * name.
- * <p>
- * <strong>Note:</strong> This method uses the fAttributeQName and
- * fQName variables. The contents of these variables will be
- * destroyed.
- *
- * @param attributes The attributes list for the scanned attribute.
- */
- protected void scanAttribute(XMLAttributesImpl attributes)
- throws IOException, XNIException {
- if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanAttribute()");
-
- // name
- fEntityScanner.scanQName(fAttributeQName);
-
- // equals
- fEntityScanner.skipSpaces();
- if (!fEntityScanner.skipChar('=')) {
- reportFatalError("EqRequiredInAttribute",
- new Object[]{fCurrentElement.rawname,fAttributeQName.rawname});
- }
- fEntityScanner.skipSpaces();
-
- // content
- int oldLen = attributes.getLength();
- attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null);
-
- // WFC: Unique Att Spec
- if (oldLen == attributes.getLength()) {
- reportFatalError("AttributeNotUnique",
- new Object[]{fCurrentElement.rawname,
- fAttributeQName.rawname});
- }
-
- //REVISIT: one more case needs to be included: external PE and standalone is no
- boolean isVC = fHasExternalDTD && !fStandalone;
-
- // REVISIT: it seems that this function should not take attributes, and length
- scanAttributeValue(this.fTempString, fTempString2,
- fAttributeQName.rawname, attributes,
- oldLen, isVC,fCurrentElement.rawname);
- String value = fTempString.toString();
- attributes.setValue(oldLen, value);
- attributes.setNonNormalizedValue(oldLen, fTempString2.toString());
- attributes.setSpecified(oldLen, true);
-
- // record namespace declarations if any.
- if (fBindNamespaces) {
-
- String localpart = fAttributeQName.localpart;
- String prefix = fAttributeQName.prefix != null
- ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
- // when it's of form xmlns="..." or xmlns:prefix="...",
- // it's a namespace declaration. but prefix:xmlns="..." isn't.
- if (prefix == XMLSymbols.PREFIX_XMLNS ||
- prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) {
-
- // get the internalized value of this attribute
- String uri = fSymbolTable.addSymbol(value);
-
- // 1. "xmlns" can't be bound to any namespace
- if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXMLNS",
- new Object[]{fAttributeQName},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // 2. the namespace for "xmlns" can't be bound to any prefix
- if (uri == NamespaceContext.XMLNS_URI) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXMLNS",
- new Object[]{fAttributeQName},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
-
- // 3. "xml" can't be bound to any other namespace than it's own
- if (localpart == XMLSymbols.PREFIX_XML) {
- if (uri != NamespaceContext.XML_URI) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXML",
- new Object[]{fAttributeQName},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- }
- // 4. the namespace for "xml" can't be bound to any other prefix
- else {
- if (uri ==NamespaceContext.XML_URI) {
- fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
- "CantBindXML",
- new Object[]{fAttributeQName},
- XMLErrorReporter.SEVERITY_FATAL_ERROR);
- }
- }
-
- prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
-
- // Declare prefix in context. Removing the association between a prefix and a
- // namespace name is permitted in XML 1.1, so if the uri value is the empty string,
- // the prefix is being unbound. -- mrglavas
- fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
- // bind namespace attribute to a namespace
- attributes.setURI(oldLen, fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS));
-
- }
- else {
- // attempt to bind attribute
- if (fAttributeQName.prefix != null) {
- attributes.setURI(oldLen, fNamespaceContext.getURI(fAttributeQName.prefix));
- }
- }
- }
-
- if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanAttribute()");
- } // scanAttribute(XMLAttributes)
-
-
-
- /**
- * Scans an end element.
- * <p>
- * <pre>
- * [42] ETag ::= '</' Name S? '>'
- * </pre>
- * <p>
- * <strong>Note:</strong> This method uses the fElementQName variable.
- * The contents of this variable will be destroyed. The caller should
- * copy the needed information out of this variable before calling
- * this method.
- *
- * @return The element depth.
- */
- protected int scanEndElement() throws IOException, XNIException {
- if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanEndElement()");
-
- // pop context
- fElementStack.popElement(fElementQName) ;
-
- // Take advantage of the fact that next string _should_ be "fElementQName.rawName",
- //In scanners most of the time is consumed on checks done for XML characters, we can
- // optimize on it and avoid the checks done for endElement,
- //we will also avoid symbol table lookup - neeraj.bajaj@sun.com
-
- // this should work both for namespace processing true or false...
-
- //REVISIT: if the string is not the same as expected.. we need to do better error handling..
- //We can skip this for now... In any case if the string doesn't match -- document is not well formed.
- if (!fEntityScanner.skipString(fElementQName.rawname)) {
- reportFatalError("ETagRequired", new Object[]{fElementQName.rawname});
- }
-
- // end
- fEntityScanner.skipSpaces();
- if (!fEntityScanner.skipChar('>')) {
- reportFatalError("ETagUnterminated",
- new Object[]{fElementQName.rawname});
- }
- fMarkupDepth--;
-
- //we have increased the depth for two markup "<" characters
- fMarkupDepth--;
-
- // check that this element was opened in the same entity
- if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
- reportFatalError("ElementEntityMismatch",
- new Object[]{fCurrentElement.rawname});
- }
-
- // call handler
- if (fDocumentHandler != null ) {
-
- fDocumentHandler.endElement(fElementQName, null);
- if (fBindNamespaces) {
- fNamespaceContext.popContext();
- }
-
- }
-
- return fMarkupDepth;
-
- } // scanEndElement():int
-
-
- public void reset(XMLComponentManager componentManager)
- throws XMLConfigurationException {
-
- super.reset(componentManager);
- fPerformValidation = false;
- fBindNamespaces = false;
- }
-
- /** Creates a content dispatcher. */
- protected Dispatcher createContentDispatcher() {
- return new NS11ContentDispatcher();
- } // createContentDispatcher():Dispatcher
-
- /**
- * Dispatcher to handle content scanning.
- */
- protected final class NS11ContentDispatcher
- extends ContentDispatcher {
- /**
- * Scan for root element hook. This method is a hook for
- * subclasses to add code that handles scanning for the root
- * element. This method will also attempt to remove DTD validator
- * from the pipeline, if there is no DTD grammar. If DTD validator
- * is no longer in the pipeline bind namespaces in the scanner.
- *
- *
- * @return True if the caller should stop and return true which
- * allows the scanner to switch to a new scanning
- * dispatcher. A return value of false indicates that
- * the content dispatcher should continue as normal.
- */
- protected boolean scanRootElementHook()
- throws IOException, XNIException {
- if (fDTDValidator == null) {
- fBindNamespaces = true;
- }
- else if (!fDTDValidator.hasGrammar()) {
- fBindNamespaces = true;
- fPerformValidation = fDTDValidator.validate();
- // re-configure pipeline
- XMLDocumentSource source = fDTDValidator.getDocumentSource();
- XMLDocumentHandler handler = fDTDValidator.getDocumentHandler();
- source.setDocumentHandler(handler);
- if (handler != null)
- handler.setDocumentSource(source);
- fDTDValidator.setDocumentSource(null);
- fDTDValidator.setDocumentHandler(null);
- }
-
- if (scanStartElement()) {
- setScannerState(SCANNER_STATE_TRAILING_MISC);
- setDispatcher(fTrailingMiscDispatcher);
- return true;
- }
- return false;
+ /**
+ * If is true, the dtd validator is no longer in the pipeline
+ * and the scanner should bind namespaces
+ */
+ protected boolean fBindNamespaces;
+
+ /**
+ * If validating parser, make sure we report an error in the
+ * scanner if DTD grammar is missing.
+ */
+ protected boolean fPerformValidation;
+
+ protected String[] fUri = new String[4];
+ protected String[] fLocalpart = new String[4];
+ protected int fLength = 0;
+
+ // private data
+ //
+
+ /** DTD validator */
+ private XMLDTDValidatorFilter fDTDValidator;
+
+ /**
+ * The scanner is responsible for removing DTD validator
+ * from the pipeline if it is not needed.
+ *
+ * @param validator the DTD validator from the pipeline
+ */
+ public void setDTDValidator(XMLDTDValidatorFilter validator) {
+ fDTDValidator = validator;
+ }
+
+ /**
+ * Scans a start element. This method will handle the binding of
+ * namespace information and notifying the handler of the start
+ * of the element.
+ * <p>
+ * <pre>
+ * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
+ * [40] STag ::= '<' Name (S Attribute)* S? '>'
+ * </pre>
+ * <p>
+ * <strong>Note:</strong> This method assumes that the leading
+ * '<' character has been consumed.
+ * <p>
+ * <strong>Note:</strong> This method uses the fElementQName and
+ * fAttributes variables. The contents of these variables will be
+ * destroyed. The caller should copy important information out of
+ * these variables before calling this method.
+ *
+ * @return True if element is empty. (i.e. It matches
+ * production [44].
+ */
+ protected boolean scanStartElement() throws IOException, XNIException {
+ if (DEBUG_CONTENT_SCANNING)
+ System.out.println(">>> scanStartElementNS()");
+
+ // Note: namespace processing is on by default
+ fEntityScanner.scanQName(fElementQName);
+ // REVISIT - [Q] Why do we need this local variable? -- mrglavas
+ String rawname = fElementQName.rawname;
+ if (fBindNamespaces) {
+ fNamespaceContext.pushContext();
+ if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) {
+ if (fPerformValidation) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "MSG_GRAMMAR_NOT_FOUND",
+ new Object[] { rawname },
+ XMLErrorReporter.SEVERITY_ERROR);
+
+ if (fDoctypeName == null
+ || !fDoctypeName.equals(rawname)) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XML_DOMAIN,
+ "RootElementTypeMustMatchDoctypedecl",
+ new Object[] { fDoctypeName, rawname },
+ XMLErrorReporter.SEVERITY_ERROR);
+ }
+ }
+ }
+ }
+
+ // push element stack
+ fCurrentElement = fElementStack.pushElement(fElementQName);
+
+ // attributes
+ boolean empty = false;
+ fAttributes.removeAllAttributes();
+ do {
+ // spaces
+ boolean sawSpace = fEntityScanner.skipSpaces();
+
+ // end tag?
+ int c = fEntityScanner.peekChar();
+ if (c == '>') {
+ fEntityScanner.scanChar();
+ break;
+ } else if (c == '/') {
+ fEntityScanner.scanChar();
+ if (!fEntityScanner.skipChar('>')) {
+ reportFatalError(
+ "ElementUnterminated",
+ new Object[] { rawname });
+ }
+ empty = true;
+ break;
+ } else if (!isValidNameStartChar(c) || !sawSpace) {
+ reportFatalError(
+ "ElementUnterminated",
+ new Object[] { rawname });
+ }
+
+ // attributes
+ scanAttribute(fAttributes);
+
+ } while (true);
+
+ if (fBindNamespaces) {
+ // REVISIT: is it required? forbit xmlns prefix for element
+ if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "ElementXMLNSPrefix",
+ new Object[] { fElementQName.rawname },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+
+ // bind the element
+ String prefix =
+ fElementQName.prefix != null
+ ? fElementQName.prefix
+ : XMLSymbols.EMPTY_STRING;
+ // assign uri to the element
+ fElementQName.uri = fNamespaceContext.getURI(prefix);
+ // make sure that object in the element stack is updated as well
+ fCurrentElement.uri = fElementQName.uri;
+
+ if (fElementQName.prefix == null && fElementQName.uri != null) {
+ fElementQName.prefix = XMLSymbols.EMPTY_STRING;
+ }
+ if (fElementQName.prefix != null && fElementQName.uri == null) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "ElementPrefixUnbound",
+ new Object[] {
+ fElementQName.prefix,
+ fElementQName.rawname },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+
+ // bind attributes (xmlns are already bound bellow)
+ int length = fAttributes.getLength();
+ fLength = 0; //initialize structure
+ for (int i = 0; i < length; i++) {
+ fAttributes.getName(i, fAttributeQName);
+
+ String aprefix =
+ fAttributeQName.prefix != null
+ ? fAttributeQName.prefix
+ : XMLSymbols.EMPTY_STRING;
+ String uri = fNamespaceContext.getURI(aprefix);
+ // REVISIT: try removing the first "if" and see if it is faster.
+ //
+ if (fAttributeQName.uri != null
+ && fAttributeQName.uri == uri) {
+ checkDuplicates(fAttributeQName, fAttributes);
+ continue;
+ }
+ if (aprefix != XMLSymbols.EMPTY_STRING) {
+ fAttributeQName.uri = uri;
+ if (uri == null) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "AttributePrefixUnbound",
+ new Object[] {
+ fElementQName.rawname,
+ fAttributeQName.rawname,
+ aprefix },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+ fAttributes.setURI(i, uri);
+ checkDuplicates(fAttributeQName, fAttributes);
+ }
+ }
+ }
+
+ // call handler
+ if (fDocumentHandler != null) {
+ if (empty) {
+
+ //decrease the markup depth..
+ fMarkupDepth--;
+
+ // check that this element was opened in the same entity
+ if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
+ reportFatalError(
+ "ElementEntityMismatch",
+ new Object[] { fCurrentElement.rawname });
+ }
+
+ fDocumentHandler.emptyElement(fElementQName, fAttributes, null);
+
+ if (fBindNamespaces) {
+ fNamespaceContext.popContext();
+ }
+ //pop the element off the stack..
+ fElementStack.popElement(fElementQName);
+ } else {
+ fDocumentHandler.startElement(fElementQName, fAttributes, null);
+ }
+ }
+
+ if (DEBUG_CONTENT_SCANNING)
+ System.out.println("<<< scanStartElement(): " + empty);
+ return empty;
+
+ } // scanStartElement():boolean
+
+ private final void checkDuplicates(
+ QName qname,
+ XMLAttributesImpl attributes) {
+
+ // Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
+ // search if such attribute already exists
+ for (int i = 0; i < fLength; i++) {
+ if (qname.uri == fUri[i]
+ && fLocalpart[i].equals(qname.localpart)) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "AttributeNSNotUnique",
+ new Object[] {
+ fElementQName.rawname,
+ qname.rawname,
+ qname.uri },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+ }
+ int index = fLength;
+ if (fLength++ == fUri.length) {
+ String[] uris = new String[fUri.length + 4];
+ String[] lps = new String[fUri.length + 4];
+ System.arraycopy(fUri, 0, uris, 0, fUri.length);
+ System.arraycopy(fLocalpart, 0, lps, 0, fLocalpart.length);
+ fUri = uris;
+ fLocalpart = lps;
+
+ }
+
+ fUri[index] = qname.uri;
+ fLocalpart[index] = qname.localpart;
+ }
+
+ /**
+ * Scans an attribute.
+ * <p>
+ * <pre>
+ * [41] Attribute ::= Name Eq AttValue
+ * </pre>
+ * <p>
+ * <strong>Note:</strong> This method assumes that the next
+ * character on the stream is the first character of the attribute
+ * name.
+ * <p>
+ * <strong>Note:</strong> This method uses the fAttributeQName and
+ * fQName variables. The contents of these variables will be
+ * destroyed.
+ *
+ * @param attributes The attributes list for the scanned attribute.
+ */
+ protected void scanAttribute(XMLAttributesImpl attributes)
+ throws IOException, XNIException {
+ if (DEBUG_CONTENT_SCANNING)
+ System.out.println(">>> scanAttribute()");
+
+ // name
+ fEntityScanner.scanQName(fAttributeQName);
+
+ // equals
+ fEntityScanner.skipSpaces();
+ if (!fEntityScanner.skipChar('=')) {
+ reportFatalError(
+ "EqRequiredInAttribute",
+ new Object[] {
+ fCurrentElement.rawname,
+ fAttributeQName.rawname });
+ }
+ fEntityScanner.skipSpaces();
+
+ // content
+ int oldLen = attributes.getLength();
+ attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null);
+
+ // WFC: Unique Att Spec
+ if (oldLen == attributes.getLength()) {
+ reportFatalError(
+ "AttributeNotUnique",
+ new Object[] {
+ fCurrentElement.rawname,
+ fAttributeQName.rawname });
+ }
+
+ //REVISIT: one more case needs to be included: external PE and standalone is no
+ boolean isVC = fHasExternalDTD && !fStandalone;
+
+ // REVISIT: it seems that this function should not take attributes, and length
+ scanAttributeValue(
+ this.fTempString,
+ fTempString2,
+ fAttributeQName.rawname,
+ attributes,
+ oldLen,
+ isVC,
+ fCurrentElement.rawname);
+ String value = fTempString.toString();
+ attributes.setValue(oldLen, value);
+ attributes.setNonNormalizedValue(oldLen, fTempString2.toString());
+ attributes.setSpecified(oldLen, true);
+
+ // record namespace declarations if any.
+ if (fBindNamespaces) {
+
+ String localpart = fAttributeQName.localpart;
+ String prefix =
+ fAttributeQName.prefix != null
+ ? fAttributeQName.prefix
+ : XMLSymbols.EMPTY_STRING;
+ // when it's of form xmlns="..." or xmlns:prefix="...",
+ // it's a namespace declaration. but prefix:xmlns="..." isn't.
+ if (prefix == XMLSymbols.PREFIX_XMLNS
+ || prefix == XMLSymbols.EMPTY_STRING
+ && localpart == XMLSymbols.PREFIX_XMLNS) {
+
+ // get the internalized value of this attribute
+ String uri = fSymbolTable.addSymbol(value);
+
+ // 1. "xmlns" can't be bound to any namespace
+ if (prefix == XMLSymbols.PREFIX_XMLNS
+ && localpart == XMLSymbols.PREFIX_XMLNS) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "CantBindXMLNS",
+ new Object[] { fAttributeQName },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+
+ // 2. the namespace for "xmlns" can't be bound to any prefix
+ if (uri == NamespaceContext.XMLNS_URI) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "CantBindXMLNS",
+ new Object[] { fAttributeQName },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+
+ // 3. "xml" can't be bound to any other namespace than it's own
+ if (localpart == XMLSymbols.PREFIX_XML) {
+ if (uri != NamespaceContext.XML_URI) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "CantBindXML",
+ new Object[] { fAttributeQName },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+ }
+ // 4. the namespace for "xml" can't be bound to any other prefix
+ else {
+ if (uri == NamespaceContext.XML_URI) {
+ fErrorReporter.reportError(
+ XMLMessageFormatter.XMLNS_DOMAIN,
+ "CantBindXML",
+ new Object[] { fAttributeQName },
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+ }
+
+ prefix =
+ localpart != XMLSymbols.PREFIX_XMLNS
+ ? localpart
+ : XMLSymbols.EMPTY_STRING;
+
+ // Declare prefix in context. Removing the association between a prefix and a
+ // namespace name is permitted in XML 1.1, so if the uri value is the empty string,
+ // the prefix is being unbound. -- mrglavas
+ fNamespaceContext.declarePrefix(
+ prefix,
+ uri.length() != 0 ? uri : null);
+ // bind namespace attribute to a namespace
+ attributes.setURI(
+ oldLen,
+ fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS));
+
+ } else {
+ // attempt to bind attribute
+ if (fAttributeQName.prefix != null) {
+ attributes.setURI(
+ oldLen,
+ fNamespaceContext.getURI(fAttributeQName.prefix));
+ }
+ }
+ }
+
+ if (DEBUG_CONTENT_SCANNING)
+ System.out.println("<<< scanAttribute()");
+ } // scanAttribute(XMLAttributes)
+
+ /**
+ * Scans an end element.
+ * <p>
+ * <pre>
+ * [42] ETag ::= '</' Name S? '>'
+ * </pre>
+ * <p>
+ * <strong>Note:</strong> This method uses the fElementQName variable.
+ * The contents of this variable will be destroyed. The caller should
+ * copy the needed information out of this variable before calling
+ * this method.
+ *
+ * @return The element depth.
+ */
+ protected int scanEndElement() throws IOException, XNIException {
+ if (DEBUG_CONTENT_SCANNING)
+ System.out.println(">>> scanEndElement()");
+
+ // pop context
+ fElementStack.popElement(fElementQName);
+
+ // Take advantage of the fact that next string _should_ be "fElementQName.rawName",
+ //In scanners most of the time is consumed on checks done for XML characters, we can
+ // optimize on it and avoid the checks done for endElement,
+ //we will also avoid symbol table lookup - neeraj.bajaj@sun.com
+
+ // this should work both for namespace processing true or false...
+
+ //REVISIT: if the string is not the same as expected.. we need to do better error handling..
+ //We can skip this for now... In any case if the string doesn't match -- document is not well formed.
+ if (!fEntityScanner.skipString(fElementQName.rawname)) {
+ reportFatalError(
+ "ETagRequired",
+ new Object[] { fElementQName.rawname });
+ }
+
+ // end
+ fEntityScanner.skipSpaces();
+ if (!fEntityScanner.skipChar('>')) {
+ reportFatalError(
+ "ETagUnterminated",
+ new Object[] { fElementQName.rawname });
+ }
+ fMarkupDepth--;
+
+ //we have increased the depth for two markup "<" characters
+ fMarkupDepth--;
+
+ // check that this element was opened in the same entity
+ if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
+ reportFatalError(
+ "ElementEntityMismatch",
+ new Object[] { fCurrentElement.rawname });
+ }
+
+ // call handler
+ if (fDocumentHandler != null) {
+
+ fDocumentHandler.endElement(fElementQName, null);
+ if (fBindNamespaces) {
+ fNamespaceContext.popContext();
+ }
+
+ }
+
+ return fMarkupDepth;
+
+ } // scanEndElement():int
+
+ public void reset(XMLComponentManager componentManager)
+ throws XMLConfigurationException {
+
+ super.reset(componentManager);
+ fPerformValidation = false;
+ fBindNamespaces = false;
+ }
+
+ /** Creates a content dispatcher. */
+ protected Dispatcher createContentDispatcher() {
+ return new NS11ContentDispatcher();
+ } // createContentDispatcher():Dispatcher
+
+ /**
+ * Dispatcher to handle content scanning.
+ */
+ protected final class NS11ContentDispatcher extends ContentDispatcher {
+ /**
+ * Scan for root element hook. This method is a hook for
+ * subclasses to add code that handles scanning for the root
+ * element. This method will also attempt to remove DTD validator
+ * from the pipeline, if there is no DTD grammar. If DTD validator
+ * is no longer in the pipeline bind namespaces in the scanner.
+ *
+ *
+ * @return True if the caller should stop and return true which
+ * allows the scanner to switch to a new scanning
+ * dispatcher. A return value of false indicates that
+ * the content dispatcher should continue as normal.
+ */
+ protected boolean scanRootElementHook()
+ throws IOException, XNIException {
+ if (fDTDValidator == null) {
+ fBindNamespaces = true;
+ } else if (!fDTDValidator.hasGrammar()) {
+ fBindNamespaces = true;
+ fPerformValidation = fDTDValidator.validate();
+ // re-configure pipeline
+ XMLDocumentSource source = fDTDValidator.getDocumentSource();
+ XMLDocumentHandler handler = fDTDValidator.getDocumentHandler();
+ source.setDocumentHandler(handler);
+ if (handler != null)
+ handler.setDocumentSource(source);
+ fDTDValidator.setDocumentSource(null);
+ fDTDValidator.setDocumentHandler(null);
+ }
+
+ if (scanStartElement()) {
+ setScannerState(SCANNER_STATE_TRAILING_MISC);
+ setDispatcher(fTrailingMiscDispatcher);
+ return true;
+ }
+ return false;
- } // scanRootElementHook():boolean
- }
+ } // scanRootElementHook():boolean
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org