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 + -
显示快捷键?