parser2.java

来自「java jdk 1.4的源码」· Java 代码 · 共 1,790 行 · 第 1/5 页

JAVA
1,790
字号
            // Convert string to array of chars            int length = strTmp.length();            char[] charArray = new char[length];            if (length != 0) {                // XXX Avoid calling getChars on zero-size array as a                // workaround for a bug that occurs in at least JDK1.2.2                // which has since been fixed in JDK1.3                strTmp.getChars(0, length, charArray, 0);            }            lexicalHandler.comment(charArray, 0, length);        }        return true;    }    private boolean maybePI (boolean skipStart)    throws IOException, SAXException    {        // [16] PI ::= '<?' PITarget        //              (S (Char* - (Char* '?>' Char*)))?        //              '?>'        // [17] PITarget ::= Name - (('X'|'x')('M'|'m')('L'|'l')        boolean         savedLexicalPE = doLexicalPE;        if (!in.peek (skipStart ? "?" : "<?", null))            return false;        doLexicalPE = false;        String          target = maybeGetName ();        if (target == null)            fatal ("P-018");        if ("xml".equals (target))            fatal ("P-019");        if ("xml".equalsIgnoreCase (target))            fatal ("P-020", new Object [] { target });        if (maybeWhitespace ()) {            strTmp = new StringBuffer ();            try {                for (;;) {                    // use in.getc to bypass PE processing                    char c = in.getc ();                    //Reached the end of PI.                    if (c == '?' && in.peekc ('>'))                        break;                    strTmp.append (c);                }            } catch (EndOfInputException e) {                fatal ("P-021");            }            contentHandler.processingInstruction (target, strTmp.toString ());        } else {            if (!in.peek ("?>", null))                fatal ("P-022");            contentHandler.processingInstruction (target, "");        }        doLexicalPE = savedLexicalPE;        return true;    }        // [18] CDSect ::= CDStart CData CDEnd        // [19] CDStart ::= '<![CDATA['        // [20] CData ::= (Char* - (Char* ']]>' Char*))        // [21] CDEnd ::= ']]>'        //        //      ... handled by InputEntity.unparsedContent()    private void maybeXmlDecl ()    throws IOException, SAXException    {        // [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl?        //                      SDDecl? S? '>'        if (!in.isXmlDeclOrTextDeclPrefix()) {            return;        }        // Consume '<?xml'        peek("<?xml");        readVersion (true, "1.0");        readEncoding (false);        readStandalone ();        maybeWhitespace ();        if (!peek ("?>")) {            char c = getc ();            fatal ("P-023", new Object []                { Integer.toHexString (c), new Character (c) });        }    }    // collapsing several rules together ...     // simpler than attribute literals -- no reference parsing!    private String maybeReadAttribute (String name, boolean must)    throws IOException, SAXException    {        // [24] VersionInfo ::= S 'version' Eq \'|\" versionNum \'|\"        // [80] EncodingDecl ::= S 'encoding' Eq \'|\" EncName \'|\"        // [32] SDDecl ::=  S 'standalone' Eq \'|\" ... \'|\"        if (!maybeWhitespace ()) {            if (!must)                return null;            fatal ("P-024", new Object [] { name });            // NOTREACHED        }        if (!peek (name))            if (must)                fatal ("P-024", new Object [] { name });            else {                // To ensure that the whitespace is there so that when we                // check for the next attribute we assure that the                // whitespace still exists.                ungetc ();                return null;            }        // [25] Eq ::= S? '=' S?        maybeWhitespace ();        nextChar ('=', "F-023", null);        maybeWhitespace ();        return getQuotedString ("F-035", name);    }    private void readVersion (boolean must, String versionNum)    throws IOException, SAXException    {        String  value = maybeReadAttribute ("version", must);        // [26] versionNum ::= ([a-zA-Z0-9_.:]| '-')+        if (must && value == null)            fatal ("P-025", new Object [] { versionNum });        if (value != null) {            int length = value.length ();            for (int i = 0; i < length; i++) {                char c = value.charAt (i);                if (!(    (c >= '0' && c <= '9')                        || c == '_' || c == '.'                        || (c >= 'a' && c <= 'z')                        || (c >= 'A' && c <= 'Z')                        || c == ':' || c == '-')                        )                    fatal ("P-026", new Object [] { value });            }        }        if (value != null && !value.equals (versionNum))            error ("P-027", new Object [] { versionNum, value });    }    private void maybeMisc (boolean eofOK)    throws IOException, SAXException    {        // Misc*        while (!eofOK || !in.isEOF ()) {            // [27] Misc ::= Comment | PI | S            if (maybeComment (false)                    || maybePI (false)                    || maybeWhitespace ())                continue;            else                break;        }    }    // common code used by most markup declarations    // ... S (Q)Name ...    private String getMarkupDeclname (String roleId, boolean qname)    throws IOException, SAXException    {        String  name;        whitespace (roleId);        name = maybeGetName ();        if (name == null)            fatal ("P-005", new Object []                { messages.getMessage (locale, roleId) });        return name;    }    private boolean maybeDoctypeDecl ()    throws IOException, SAXException    {        // [28] doctypedecl ::= '<!DOCTYPE' S Name        //      (S ExternalID)?        //      S? ('[' (markupdecl|PEReference|S)* ']' S?)?        //      '>'        if (!peek ("<!DOCTYPE")){            return false;        }        else{            if(disallowDoctypeDecl){                fatal("P-085", new Object[] {SYSTEM_PROPERTY_DISALLOW_DOCTYPE_DECL} );            }        }        ExternalEntity  externalSubset = null;        rootElementName = getMarkupDeclname ("F-014", true);        if (maybeWhitespace ()                && (externalSubset = maybeExternalID ()) != null) {            lexicalHandler.startDTD(rootElementName, externalSubset.publicId,                                    externalSubset.verbatimSystemId);            maybeWhitespace ();        } else {            lexicalHandler.startDTD(rootElementName, null, null);        }        if (in.peekc ('[')) {            for (;;) {                //Pop PEs when they are done.                if (in.isEOF () && !in.isDocument ()) {                    in = in.pop ();                    continue;                }                if (maybeMarkupDecl ()                        || maybePEReference ()                        || maybeWhitespace ()                        )                    continue;                else if (peek ("<!["))                    fatal ("P-028");                else                    break;            }            nextChar (']', "F-024", null);            maybeWhitespace ();        }        nextChar ('>', "F-025", null);        // [30] extSubset ::= TextDecl? extSubsetDecl        // [31] extSubsetDecl ::= ( markupdecl | conditionalSect        //              | PEReference | S )*        //      ... same as [79] extPE, which is where the code is        if (externalSubset != null) {            externalSubset.name = "[dtd]";  // SAX2 ext specifies this name            externalSubset.isPE = true;            externalParameterEntity (externalSubset);        }        // params are no good to anyone starting now -- bye!        params.clear ();        lexicalHandler.endDTD();        // make sure notations mentioned in attributes        // and entities were declared ... those are validity        // errors, but we must always clean up after them!        Vector  v = new Vector ();        for (Enumeration e = notations.keys ();                e.hasMoreElements ();                ) {            String name = (String) e.nextElement ();            Object value = notations.get (name);            if (value == Boolean.TRUE) {                if (supportValidation && isValidating)                    error ("V-003", new Object [] { name });                v.addElement (name);            } else if (value instanceof String) {                if (supportValidation && isValidating)                    error ("V-004", new Object [] { name });                v.addElement (name);            }        }        while (!v.isEmpty ()) {            Object name = v.firstElement ();            v.removeElement (name);            notations.remove (name);        }        return true;    }    private boolean maybeMarkupDecl ()    throws IOException, SAXException    {            // [29] markupdecl ::= elementdecl | Attlistdecl            //         | EntityDecl | NotationDecl | PI | Comment        return maybeElementDecl ()                || maybeAttlistDecl ()                || maybeEntityDecl ()                || maybeNotationDecl ()                || maybePI (false)                || maybeComment (false)                ;    }    private void readStandalone ()    throws IOException, SAXException    {        String  value = maybeReadAttribute ("standalone", false);        // [32] SDDecl ::= ... "yes" or "no"        if (value == null || "no".equals (value))            return;        if ("yes".equals (value)) {            isStandalone = true;            return;        }        fatal ("P-029", new Object [] { value });    }    private static final String         XmlLang = "xml:lang";    private boolean isXmlLang (String value)    {        // [33] LanguageId ::= Langcode ('-' Subcode)*        // [34] Langcode ::= ISO639Code | IanaCode | UserCode        // [35] ISO639Code ::= [a-zA-Z] [a-zA-Z]        // [36] IanaCode ::= [iI] '-' SubCode        // [37] UserCode ::= [xX] '-' SubCode        // [38] SubCode ::= [a-zA-Z]+        // the ISO and IANA codes (and subcodes) are registered,        // but that's neither a WF nor a validity constraint.        int     nextSuffix;        char    c;                if (value.length () < 2)            return false;        c = value.charAt (1);        if (c == '-') {         // IANA, or user, code            c = value.charAt (0);            if (!(c == 'i' || c == 'I' || c == 'x' || c == 'X'))                return false;            nextSuffix = 1;        } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {                                // 2 letter ISO code, or error            c = value.charAt (0);            if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))                return false;            nextSuffix = 2;        } else            return false;                // here "suffix" ::= '-' [a-zA-Z]+ suffix*        while (nextSuffix < value.length ()) {            c = value.charAt (nextSuffix);            if (c != '-')                break;            while (++nextSuffix < value.length ()) {                c = value.charAt (nextSuffix);                if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))                    break;            }        }        return value.length () == nextSuffix && c != '-';    }    //

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?