xmldocumentscannerimpl.java

来自「JAVA 所有包」· Java 代码 · 共 1,499 行 · 第 1/4 页

JAVA
1,499
字号
    //        /**     * Driver to handle XMLDecl scanning.     *     * This class has been modified as per the new design which is more suited to     * efficiently build pull parser. Lots of performance improvements have been done and     * the code has been added to support stax functionality/features.     *     * @author Neeraj Bajaj, Sun Microsystems.     *     * @author Andy Clark, IBM     */    protected final class XMLDeclDriver            implements Driver {                //        // Driver methods        //                        public int next() throws IOException, XNIException {            if(DEBUG_NEXT){                System.out.println("NOW IN XMLDeclDriver");            }                        // next driver is prolog regardless of whether there            // is an XMLDecl in this document            setScannerState(SCANNER_STATE_PROLOG);            setDriver(fPrologDriver);                        //System.out.println("fEntityScanner = " + fEntityScanner);            // scan XMLDecl            try {                if (fEntityScanner.skipString(xmlDecl)) {                    fMarkupDepth++;                    // NOTE: special case where document starts with a PI                    //       whose name starts with "xml" (e.g. "xmlfoo")                    if (XMLChar.isName(fEntityScanner.peekChar())) {                        fStringBuffer.clear();                        fStringBuffer.append("xml");                        while (XMLChar.isName(fEntityScanner.peekChar())) {                            fStringBuffer.append((char)fEntityScanner.scanChar());                        }                        String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);                        //this function should fill the data.. and set the fEvent object to this event.                        fStringBuffer.clear() ;                        scanPIData(target, fStringBuffer);                        //REVISIT:where else we can set this value to 'true'                        fEntityManager.fCurrentEntity.mayReadChunks = true;                        //return PI event since PI was encountered                        return XMLEvent.PROCESSING_INSTRUCTION ;                    }                    // standard XML declaration                    else {                        scanXMLDeclOrTextDecl(false);                        //REVISIT:where else we can set this value to 'true'                        fEntityManager.fCurrentEntity.mayReadChunks = true;                        return XMLEvent.START_DOCUMENT;                    }                } else{                    //REVISIT:where else we can set this value to 'true'                    fEntityManager.fCurrentEntity.mayReadChunks = true;                    //In both case return the START_DOCUMENT. ony difference is that first block will                    //cosume the XML declaration if any.                    return XMLEvent.START_DOCUMENT;                }                                                //START_OF_THE_DOCUMENT                                            }                        // premature end of file            catch (EOFException e) {                reportFatalError("PrematureEOF", null);                return -1;                //throw e;            }                    }    } // class XMLDeclDriver        /**     * Driver to handle prolog scanning.     *     * @author Andy Clark, IBM     */    protected final class PrologDriver            implements Driver {                /**         * Drives the parser to the next state/event on the input. Parser is guaranteed         * to stop at the next state/event.         *         * Internally XML document is divided into several states. Each state represents         * a sections of XML document. When this functions returns normally, it has read         * the section of XML document and returns the state corresponding to section of         * document which has been read. For optimizations, a particular driver         * can read ahead of the section of document (state returned) just read and         * can maintain a different internal state.         *         * @return state representing the section of document just read.         *         * @throws IOException  Thrown on i/o error.         * @throws XNIException Thrown on parse error.         */                public int next() throws IOException, XNIException {            //System.out.println("here in next");                        if(DEBUG_NEXT){                System.out.println("NOW IN PrologDriver");            }            try {                do {                    switch (fScannerState) {                        case SCANNER_STATE_PROLOG: {                            fEntityScanner.skipSpaces();                            if (fEntityScanner.skipChar('<')) {                                setScannerState(SCANNER_STATE_START_OF_MARKUP);                            } else if (fEntityScanner.skipChar('&')) {                                setScannerState(SCANNER_STATE_REFERENCE);                            } else {                                setScannerState(SCANNER_STATE_CONTENT);                            }                            break;                        }                                                case SCANNER_STATE_START_OF_MARKUP: {                            fMarkupDepth++;                                                        if (fEntityScanner.skipChar('?')) {                                setScannerState(SCANNER_STATE_PI);                            } else if (fEntityScanner.skipChar('!')) {                                if (fEntityScanner.skipChar('-')) {                                    if (!fEntityScanner.skipChar('-')) {                                        reportFatalError("InvalidCommentStart",                                                null);                                    }                                    setScannerState(SCANNER_STATE_COMMENT);                                } else if (fEntityScanner.skipString(DOCTYPE)) {                                    setScannerState(SCANNER_STATE_DOCTYPE);                                    Entity entity = fEntityScanner.getCurrentEntity();                                    if(entity instanceof Entity.ScannedEntity){                                        fStartPos=((Entity.ScannedEntity)entity).position;                                    }                                    fReadingDTD=true;                                    if(fDTDDecl == null)                                        fDTDDecl = new XMLStringBuffer();                                    fDTDDecl.append("<!DOCTYPE");                                                                    } else {                                    reportFatalError("MarkupNotRecognizedInProlog",                                            null);                                }                            } else if (XMLChar.isNameStart(fEntityScanner.peekChar())) {                                setScannerState(SCANNER_STATE_ROOT_ELEMENT);                                setDriver(fContentDriver);                                //from now onwards this would be handled by fContentDriver,in the same next() call                                return fContentDriver.next();                                                            } else {                                reportFatalError("MarkupNotRecognizedInProlog",                                        null);                            }                            break;                        }                    }                } while (fScannerState == SCANNER_STATE_PROLOG || fScannerState == SCANNER_STATE_START_OF_MARKUP );                                switch(fScannerState){                    /**                    //this part is handled by FragmentContentHandler                    case SCANNER_STATE_ROOT_ELEMENT: {                        //we have read '<' and beginning of reading the start element tag                        setScannerState(SCANNER_STATE_START_ELEMENT_TAG);                        setDriver(fContentDriver);                        //from now onwards this would be handled by fContentDriver,in the same next() call                        return fContentDriver.next();                    }                     */                    case SCANNER_STATE_COMMENT: {                        //this function fills the data..                        scanComment();                        setScannerState(SCANNER_STATE_PROLOG);                        return XMLEvent.COMMENT;                        //setScannerState(SCANNER_STATE_PROLOG);                        //break;                    }                    case SCANNER_STATE_PI: {                        fContentBuffer.clear() ;                        scanPI(fContentBuffer);                        setScannerState(SCANNER_STATE_PROLOG);                        return XMLEvent.PROCESSING_INSTRUCTION;                    }                    case SCANNER_STATE_DOCTYPE: {                                                if (fDisallowDoctype) {                            reportFatalError("DoctypeNotAllowed", null);                        }                                                if (fSeenDoctypeDecl) {                            reportFatalError("AlreadySeenDoctype", null);                        }                        fSeenDoctypeDecl = true;                        if(fDTDDriver == null){                            fDTDDriver = new DTDDriver();                        }                                                // scanDoctypeDecl() sends XNI doctypeDecl event that                        // in SAX is converted to startDTD() event.                        if (scanDoctypeDecl()) {                            setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS);                            fSeenInternalSubset = true;                            setDriver(fContentDriver);                            return fDTDDriver.next();                        }                                                /** xxx:check this part again                        if(fSeenDoctypeDecl){                            Entity entity = fEntityScanner.getCurrentEntity();                            if(entity instanceof Entity.ScannedEntity){                                fEndPos = ((Entity.ScannedEntity)entity).position;                            }                            fReadingDTD = false;                        }                         */                                                // handle external subset                        if (fDoctypeSystemId != null) {                            if (((fValidation || fLoadExternalDTD)                                 && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {                                setScannerState(SCANNER_STATE_DTD_EXTERNAL);                                setDriver(fContentDriver);                                return fDTDDriver.next();                                                            }                        }                        else if (fExternalSubsetSource != null) {                            if (((fValidation || fLoadExternalDTD)                                 && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {                                // This handles the case of a DOCTYPE that had neither an internal subset or an external subset.                                fDTDScanner.setInputSource(fExternalSubsetSource);                                fExternalSubsetSource = null;                                setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);                                setDriver(fContentDriver);                                return fDTDDriver.next();                            }                       	                        }                        // Send endDTD() call if:                         // a) systemId is null or if an external subset resolver could not locate an external subset.                        // b) "load-external-dtd" and validation are false                        // c) DTD grammar is cached                        // in XNI this results in 3 events:  doctypeDecl, startDTD, endDTD                        // in SAX this results in 2 events: startDTD, endDTD                        fDTDScanner.setInputSource(null);                        setScannerState(SCANNER_STATE_PROLOG);                        return XMLEvent.DTD;                    }                                        case SCANNER_STATE_CONTENT: {                        reportFatalError("ContentIllegalInProlog", null);                        fEntityScanner.scanChar();                    }                    case SCANNER_STATE_REFERENCE: {                        reportFatalError("ReferenceIllegalInProlog", null);                    }                                        /**                     * if (complete) {                     * if (fEntityScanner.scanChar() != '<') {                     * reportFatalError("RootElementRequired", null);                     * }                     * setScannerState(SCANNER_STATE_ROOT_ELEMENT);                     * setDriver(fContentDriver);                     * }                     */                }            }            // premature end of file            catch (EOFException e) {                reportFatalError("PrematureEOF", null);                //xxx  what should be returned here.... ???                return -1 ;                //throw e;            }            //xxx  what should be returned here.... ???            return -1;                    }                    } // class PrologDriver        /**     * Driver to handle the internal and external DTD subsets.     *     * @author Andy Clark, IBM     */    protected final class DTDDriver            implements Driver {                //        // Driver methods        //                public int next() throws IOException, XNIException{            // throw new XNIException("DTD Parsing is currently not supported");            if(DEBUG_NEXT){                System.out.println("Now in DTD Driver");            }                        dispatch(true);                        if(DEBUG_NEXT){                System.out.println("After calling dispatch(true) -- At this point whole DTD is read.");            }                        //xxx: remove this hack and align this with reusing DTD components            //currently this routine will only be executed from Stax            if(fPropertyManager != null){                dtdGrammarUtil =  new DTDGrammarUtil(((XMLDTDScannerImpl)fDTDScanner).getGrammar(),fSymbolTable, fNamespaceContext);            }                        return XMLEvent.DTD ;        }                /**         * Dispatch an XML "event".         *         * @param complete True if this driver is intended to scan         *                 and dispatch as much as possible.         *         * @return True if there is more to dispatch either from this         *          or a another driver.         *         * @throws IOException  Thrown on i/o error.         * @throws XNIException Thrown on parse error.         */        public boolean dispatch(boolean complete)        throws IOException, XNIException {            fEntityManager.setEntityHandler(null);            try {                boolean again;                XMLResourceIdentifierImpl resourceIdentifier = new XMLResourceIdentifierImpl();                if( fDTDScanner == null){                                        if (fEntityManager.getEntityScanner() instanceof XML11EntityScanner){                        fDTDScanner = new XML11DTDScannerImpl();                    } else                                        fDTDScanner = new XMLDTDScannerImpl();                                        ((XMLDTDScannerImpl)fDTDScanner).reset(fPropertyManager);                }                do {                    again = false;                    switch (fScannerState) {                        case SCANNER_STATE_DTD_INTERNAL_DECLS: {                            // REVISIT: Should there be a feature for                            //          the "complete" parameter?                            boolean completeDTD = true;                                                        boolean moreToScan = fDTDScanner.scanDTDInternalSubset(completeDTD, fStandalone, fHasExternalDTD && fLoadExternalDTD);                            Entity entity = fEntityScanner.getCurrentEntity();                            if(entity instanceof Entity.ScannedEntity){                                fEndPos=((Entity.ScannedEntity)entity).position;                            }                            fReadingDTD=false;                            if (!moreToScan) {

⌨️ 快捷键说明

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