FileDocCategorySizeDatePackage
XML11DocumentScannerImpl.javaAPI DocJava SE 5 API23490Fri Aug 26 14:55:46 BST 2005com.sun.org.apache.xerces.internal.impl

XML11DocumentScannerImpl

public class XML11DocumentScannerImpl extends XMLDocumentScannerImpl
This class is responsible for scanning XML document structure and content. The scanner acts as the source for the document information which is communicated to the document handler.

This component requires the following features and properties from the component manager that uses it:

  • http://xml.org/sax/features/namespaces
  • http://xml.org/sax/features/validation
  • http://apache.org/xml/features/nonvalidating/load-external-dtd
  • http://apache.org/xml/features/scanner/notify-char-refs
  • http://apache.org/xml/features/scanner/notify-builtin-refs
  • http://apache.org/xml/properties/internal/symbol-table
  • http://apache.org/xml/properties/internal/error-reporter
  • http://apache.org/xml/properties/internal/entity-manager
  • http://apache.org/xml/properties/internal/dtd-scanner
author
Glenn Marcy, IBM
author
Andy Clark, IBM
author
Arnaud Le Hors, IBM
author
Eric Ye, IBM
version
$Id: XML11DocumentScannerImpl.java,v 1.19 2004/04/25 05:05:50 mrglavas Exp $

Fields Summary
private String[]
fStrings
Array of 3 strings.
private XMLString
fString
String.
private XMLStringBuffer
fStringBuffer
String buffer.
private XMLStringBuffer
fStringBuffer2
private XMLStringBuffer
fStringBuffer3
Constructors Summary
public XML11DocumentScannerImpl()
Default constructor.


    //
    // Constructors
    //

       
      super();
Methods Summary
protected java.lang.StringgetVersionNotSupportedKey()

        return "VersionNotSupported11";
    
protected booleanisInvalid(int value)

        return (XML11Char.isXML11Invalid(value)); 
    
protected booleanisInvalidLiteral(int value)

        return (!XML11Char.isXML11ValidLiteral(value)); 
    
protected booleanisValidNCName(int value)

        return (XML11Char.isXML11NCName(value));
    
protected booleanisValidNameChar(int value)

        return (XML11Char.isXML11Name(value)); 
    
protected booleanisValidNameStartChar(int value)

        return (XML11Char.isXML11NameStart(value)); 
    
protected booleanisValidNameStartHighSurrogate(int value)

        return XML11Char.isXML11NameHighSurrogate(value); 
    
protected voidnormalizeWhitespace(com.sun.org.apache.xerces.internal.xni.XMLString value)
Normalize whitespace in an XMLString converting all whitespace characters to space characters.

        int end = value.offset + value.length;
	    for (int i = value.offset; i < end; i++) {
           int c = value.ch[i];
           if (XMLChar.isSpace(c)) {
               value.ch[i] = ' ";
           }
       }
    
protected voidscanAttributeValue(com.sun.org.apache.xerces.internal.xni.XMLString value, com.sun.org.apache.xerces.internal.xni.XMLString nonNormalizedValue, java.lang.String atName, boolean checkEntities, java.lang.String eleName)
Scans an attribute value and normalizes whitespace converting all whitespace characters to space characters. [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"

param
value The XMLString to fill in with the value.
param
nonNormalizedValue The XMLString to fill in with the non-normalized value.
param
atName The name of the attribute being parsed (for error msgs).
param
checkEntities true if undeclared entities should be reported as VC violation, false if undeclared entities should be reported as WFC violation.
param
eleName The name of element to which this attribute belongs. Note: This method uses fStringBuffer2, anything in it at the time of calling is lost.

        // quote
        int quote = fEntityScanner.peekChar();
        if (quote != '\'" && quote != '"") {
            reportFatalError("OpenQuoteExpected", new Object[]{eleName,atName});
        }

        fEntityScanner.scanChar();
        int entityDepth = fEntityDepth;

        int c = fEntityScanner.scanLiteral(quote, value);
        if (DEBUG_ATTR_NORMALIZATION) {
            System.out.println("** scanLiteral -> \""
                               + value.toString() + "\"");
        }
        fStringBuffer2.clear();
        fStringBuffer2.append(value);
        normalizeWhitespace(value);
        if (DEBUG_ATTR_NORMALIZATION) {
            System.out.println("** normalizeWhitespace -> \""
                               + value.toString() + "\"");
        }
        if (c != quote) {
            fScanningAttribute = true;
            fStringBuffer.clear();
            do {
                fStringBuffer.append(value);
                if (DEBUG_ATTR_NORMALIZATION) {
                    System.out.println("** value2: \""
                                       + fStringBuffer.toString() + "\"");
                }
                if (c == '&") {
                    fEntityScanner.skipChar('&");
                    if (entityDepth == fEntityDepth) {
                        fStringBuffer2.append('&");
                    }
                    if (fEntityScanner.skipChar('#")) {
                        if (entityDepth == fEntityDepth) {
                            fStringBuffer2.append('#");
                        }
                        int ch = scanCharReferenceValue(fStringBuffer, fStringBuffer2);
                        if (ch != -1) {
                            if (DEBUG_ATTR_NORMALIZATION) {
                                System.out.println("** value3: \""
                                                   + fStringBuffer.toString()
                                                   + "\"");
                            }
                        }
                    }
                    else {
                        String entityName = fEntityScanner.scanName();
                        if (entityName == null) {
                            reportFatalError("NameRequiredInReference", null);
                        }
                        else if (entityDepth == fEntityDepth) {
                            fStringBuffer2.append(entityName);
                        }
                        if (!fEntityScanner.skipChar(';")) {
                            reportFatalError("SemicolonRequiredInReference",
                                             new Object []{entityName});
                        }
                        else if (entityDepth == fEntityDepth) {
                            fStringBuffer2.append(';");
                        }
                        if (entityName == fAmpSymbol) {
                            fStringBuffer.append('&");
                            if (DEBUG_ATTR_NORMALIZATION) {
                                System.out.println("** value5: \""
                                                   + fStringBuffer.toString()
                                                   + "\"");
                            }
                        }
                        else if (entityName == fAposSymbol) {
                            fStringBuffer.append('\'");
                            if (DEBUG_ATTR_NORMALIZATION) {
                                System.out.println("** value7: \""
                                                   + fStringBuffer.toString()
                                                   + "\"");
                            }
                        }
                        else if (entityName == fLtSymbol) {
                            fStringBuffer.append('<");
                            if (DEBUG_ATTR_NORMALIZATION) {
                                System.out.println("** value9: \""
                                                   + fStringBuffer.toString()
                                                   + "\"");
                            }
                        }
                        else if (entityName == fGtSymbol) {
                            fStringBuffer.append('>");
                            if (DEBUG_ATTR_NORMALIZATION) {
                                System.out.println("** valueB: \""
                                                   + fStringBuffer.toString()
                                                   + "\"");
                            }
                        }
                        else if (entityName == fQuotSymbol) {
                            fStringBuffer.append('"");
                            if (DEBUG_ATTR_NORMALIZATION) {
                                System.out.println("** valueD: \""
                                                   + fStringBuffer.toString()
                                                   + "\"");
                            }
                        }
                        else {
                            if (fEntityManager.isExternalEntity(entityName)) {
                                reportFatalError("ReferenceToExternalEntity",
                                                 new Object[] { entityName });
                            }
                            else {
                                if (!fEntityManager.isDeclaredEntity(entityName)) {
                                    //WFC & VC: Entity Declared
                                    if (checkEntities) {
                                        if (fValidation) {
                                            fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                                       "EntityNotDeclared",
                                                                       new Object[]{entityName},
                                                                       XMLErrorReporter.SEVERITY_ERROR);
                                        }
                                    }
                                    else {
                                        reportFatalError("EntityNotDeclared",
                                                         new Object[]{entityName});
                                    }
                                }
                                fEntityManager.startEntity(entityName, true);
                            }
                        }
                    }
                }
                else if (c == '<") {
                    reportFatalError("LessthanInAttValue",
                                     new Object[] { eleName, atName });
                    fEntityScanner.scanChar();
                    if (entityDepth == fEntityDepth) {
                        fStringBuffer2.append((char)c);
                    }
                }
                else if (c == '%" || c == ']") {
                    fEntityScanner.scanChar();
                    fStringBuffer.append((char)c);
                    if (entityDepth == fEntityDepth) {
                        fStringBuffer2.append((char)c);
                    }
                    if (DEBUG_ATTR_NORMALIZATION) {
                        System.out.println("** valueF: \""
                                           + fStringBuffer.toString() + "\"");
                    }
                }
                // note that none of these characters should ever get through
                // XML11EntityScanner.  Not sure why
                // this check was originally necessary.  - NG
                else if (c == '\n" || c == '\r" || c == 0x85 || c == 0x2028) {
                    fEntityScanner.scanChar();
                    fStringBuffer.append(' ");
                    if (entityDepth == fEntityDepth) {
                        fStringBuffer2.append('\n");
                    }
                }
                else if (c != -1 && XMLChar.isHighSurrogate(c)) {
                    fStringBuffer3.clear();
                    if (scanSurrogates(fStringBuffer3)) {
                        fStringBuffer.append(fStringBuffer3);
                        if (entityDepth == fEntityDepth) {
                            fStringBuffer2.append(fStringBuffer3);
                        }
                        if (DEBUG_ATTR_NORMALIZATION) {
                            System.out.println("** valueI: \""
                                               + fStringBuffer.toString()
                                               + "\"");
                        }
                    }
                }
                else if (c != -1 && XML11Char.isXML11Invalid(c)) {
                    reportFatalError("InvalidCharInAttValue",
                                     new Object[] {eleName, atName, Integer.toString(c, 16)});
                    fEntityScanner.scanChar();
                    if (entityDepth == fEntityDepth) {
                        fStringBuffer2.append((char)c);
                    }
                }
                c = fEntityScanner.scanLiteral(quote, value);
                if (entityDepth == fEntityDepth) {
                    fStringBuffer2.append(value);
                }
                normalizeWhitespace(value);
            } while (c != quote || entityDepth != fEntityDepth);
            fStringBuffer.append(value);
            if (DEBUG_ATTR_NORMALIZATION) {
                System.out.println("** valueN: \""
                                   + fStringBuffer.toString() + "\"");
            }
            value.setValues(fStringBuffer);
            fScanningAttribute = false;
        }
        nonNormalizedValue.setValues(fStringBuffer2);

        // quote
        int cquote = fEntityScanner.scanChar();
        if (cquote != quote) {
            reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName});
        }
    
protected intscanContent()
Scans element content.

return
Returns the next character on the stream.


        XMLString content = fString;
        int c = fEntityScanner.scanContent(content);
        if (c == '\r" || c == 0x85 || c == 0x2028) {
            // happens when there is the character reference 
            // but scanContent doesn't do entity expansions...
            // is this *really* necessary???  - NG
            fEntityScanner.scanChar();
            fStringBuffer.clear();
            fStringBuffer.append(fString);
            fStringBuffer.append((char)c);
            content = fStringBuffer;
            c = -1;
        }
        if (fDocumentHandler != null && content.length > 0) {
            fDocumentHandler.characters(content, null);
        }

        if (c == ']" && fString.length == 0) {
            fStringBuffer.clear();
            fStringBuffer.append((char)fEntityScanner.scanChar());
            // remember where we are in case we get an endEntity before we
            // could flush the buffer out - this happens when we're parsing an
            // entity which ends with a ]
            fInScanContent = true;
            //
            // We work on a single character basis to handle cases such as:
            // ']]]>' which we might otherwise miss.
            //
            if (fEntityScanner.skipChar(']")) {
                fStringBuffer.append(']");
                while (fEntityScanner.skipChar(']")) {
                    fStringBuffer.append(']");
                }
                if (fEntityScanner.skipChar('>")) {
                    reportFatalError("CDEndInContent", null);
                }
            }
            if (fDocumentHandler != null && fStringBuffer.length != 0) {
                fDocumentHandler.characters(fStringBuffer, null);
            }
            fInScanContent = false;
            c = -1;
        }
        return c;

    
protected booleanscanPubidLiteral(com.sun.org.apache.xerces.internal.xni.XMLString literal)
Scans public ID literal. [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" [13] PubidChar::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] The returned string is normalized according to the following rule, from http://www.w3.org/TR/REC-xml#dt-pubid: Before a match is attempted, all strings of white space in the public identifier must be normalized to single space characters (#x20), and leading and trailing white space must be removed.

param
literal The string to fill in with the public ID literal.
return
True on success. Note: This method uses fStringBuffer, anything in it at the time of calling is lost.

        int quote = fEntityScanner.scanChar();
        if (quote != '\'" && quote != '"") {
            reportFatalError("QuoteRequiredInPublicID", null);
            return false;
        }

        fStringBuffer.clear();
        // skip leading whitespace
        boolean skipSpace = true;
        boolean dataok = true;
        while (true) {
            int c = fEntityScanner.scanChar();
            // REVISIT:  none of these except \n and 0x20 should make it past the entity scanner
            if (c == ' " || c == '\n" || c == '\r" || c == 0x85 || c == 0x2028) {
                if (!skipSpace) {
                    // take the first whitespace as a space and skip the others
                    fStringBuffer.append(' ");
                    skipSpace = true;
                }
            }
            else if (c == quote) {
                if (skipSpace) {
                    // if we finished on a space let's trim it
                    fStringBuffer.length--;
                }
                literal.setValues(fStringBuffer);
                break;
            }
            else if (XMLChar.isPubid(c)) {
                fStringBuffer.append((char)c);
                skipSpace = false;
            }
            else if (c == -1) {
                reportFatalError("PublicIDUnterminated", null);
                return false;
            }
            else {
                dataok = false;
                reportFatalError("InvalidCharInPublicID",
                                 new Object[]{Integer.toHexString(c)});
            }
        }
        return dataok;
   
protected booleanversionSupported(java.lang.String version)

        return (version.equals("1.1") || version.equals("1.0"));