xmldocumentfragmentscannerimpl.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,788 行 · 第 1/5 页
JAVA
1,788 行
// 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; } // scanContent():int /** * Scans a CDATA section. * <p> * <strong>Note:</strong> This method uses the fTempString and * fStringBuffer variables. * * @param complete True if the CDATA section is to be scanned * completely. * * @return True if CDATA is completely scanned. */ protected boolean scanCDATASection(boolean complete) throws IOException, XNIException { // call handler if (fDocumentHandler != null) { fDocumentHandler.startCDATA(null); } while (true) { fStringBuffer.clear(); if (!fEntityScanner.scanData("]]", fStringBuffer)) { if (fDocumentHandler != null && fStringBuffer.length > 0) { fDocumentHandler.characters(fStringBuffer, null); } int brackets = 0; while (fEntityScanner.skipChar(']')) { brackets++; } if (fDocumentHandler != null && brackets > 0) { fStringBuffer.clear(); if (brackets > XMLEntityManager.DEFAULT_BUFFER_SIZE) { // Handle large sequences of ']' int chunks = brackets / XMLEntityManager.DEFAULT_BUFFER_SIZE; int remainder = brackets % XMLEntityManager.DEFAULT_BUFFER_SIZE; for (int i = 0; i < XMLEntityManager.DEFAULT_BUFFER_SIZE; i++) { fStringBuffer.append(']'); } for (int i = 0; i < chunks; i++) { fDocumentHandler.characters(fStringBuffer, null); } if (remainder != 0) { fStringBuffer.length = remainder; fDocumentHandler.characters(fStringBuffer, null); } } else { for (int i = 0; i < brackets; i++) { fStringBuffer.append(']'); } fDocumentHandler.characters(fStringBuffer, null); } } if (fEntityScanner.skipChar('>')) { break; } if (fDocumentHandler != null) { fStringBuffer.clear(); fStringBuffer.append("]]"); fDocumentHandler.characters(fStringBuffer, null); } } else { if (fDocumentHandler != null) { fDocumentHandler.characters(fStringBuffer, null); } int c = fEntityScanner.peekChar(); if (c != -1 && isInvalidLiteral(c)) { if (XMLChar.isHighSurrogate(c)) { fStringBuffer.clear(); scanSurrogates(fStringBuffer); if (fDocumentHandler != null) { fDocumentHandler.characters(fStringBuffer, null); } } else { reportFatalError("InvalidCharInCDSect", new Object[]{Integer.toString(c,16)}); fEntityScanner.scanChar(); } } } } fMarkupDepth--; // call handler if (fDocumentHandler != null) { fDocumentHandler.endCDATA(null); } return true; } // scanCDATASection(boolean):boolean /** * 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()"); 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); } return fMarkupDepth; } // scanEndElement():int /** * Scans a character reference. * <p> * <pre> * [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';' * </pre> */ protected void scanCharReference() throws IOException, XNIException { fStringBuffer2.clear(); int ch = scanCharReferenceValue(fStringBuffer2, null); fMarkupDepth--; if (ch != -1) { // call handler if (fDocumentHandler != null) { if (fNotifyCharRefs) { fDocumentHandler.startGeneralEntity(fCharRefLiteral, null, null, null); } Augmentations augs = null; if (fValidation && ch <= 0x20) { augs = new AugmentationsImpl(); augs.putItem(Constants.CHAR_REF_PROBABLE_WS, Boolean.TRUE); } fDocumentHandler.characters(fStringBuffer2, augs); if (fNotifyCharRefs) { fDocumentHandler.endGeneralEntity(fCharRefLiteral, null); } } } } // scanCharReference() /** * Scans an entity reference. * * @throws IOException Thrown if i/o error occurs. * @throws XNIException Thrown if handler throws exception upon * notification. */ protected void scanEntityReference() throws IOException, XNIException { // name String name = fEntityScanner.scanName(); if (name == null) { reportFatalError("NameRequiredInReference", null); return; } // end if (!fEntityScanner.skipChar(';')) { reportFatalError("SemicolonRequiredInReference", new Object []{name}); } fMarkupDepth--; // handle built-in entities if (name == fAmpSymbol) { handleCharacter('&', fAmpSymbol); } else if (name == fLtSymbol) { handleCharacter('<', fLtSymbol); } else if (name == fGtSymbol) { handleCharacter('>', fGtSymbol); } else if (name == fQuotSymbol) { handleCharacter('"', fQuotSymbol); } else if (name == fAposSymbol) { handleCharacter('\'', fAposSymbol); } // start general entity else if (fEntityManager.isUnparsedEntity(name)) { reportFatalError("ReferenceToUnparsedEntity", new Object[]{name}); } else { if (!fEntityManager.isDeclaredEntity(name)) { //REVISIT: one more case needs to be included: external PE and standalone is no if ( fHasExternalDTD && !fStandalone) { if (fValidation) fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,"EntityNotDeclared", new Object[]{name}, XMLErrorReporter.SEVERITY_ERROR); } else reportFatalError("EntityNotDeclared", new Object[]{name}); } fEntityManager.startEntity(name, false); } } // scanEntityReference() // utility methods /** * Calls document handler with a single character resulting from * built-in entity resolution. * * @param c * @param entity built-in name */ private void handleCharacter(char c, String entity) throws XNIException { if (fDocumentHandler != null) { if (fNotifyBuiltInRefs) { fDocumentHandler.startGeneralEntity(entity, null, null, null); } fSingleChar[0] = c; fTempString.setValues(fSingleChar, 0, 1); fDocumentHandler.characters(fTempString, null); if (fNotifyBuiltInRefs) { fDocumentHandler.endGeneralEntity(entity, null); } } } // handleCharacter(char) /** * Handles the end element. This method will make sure that * the end element name matches the current element and notify * the handler about the end of the element and the end of any * relevent prefix mappings. * <p> * <strong>Note:</strong> This method uses the fQName variable. * The contents of this variable will be destroyed. * * @param element The element. * * @return The element depth. * * @throws XNIException Thrown if the handler throws a SAX exception * upon notification. * */ // REVISIT: need to remove this method. It's not called anymore, because // the handling is done when the end tag is scanned. - SG protected int handleEndElement(QName element, boolean isEmpty) throws XNIException { fMarkupDepth--; // check that this element was opened in the same entity if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) { reportFatalError("ElementEntityMismatch", new Object[]{fCurrentElement.rawname}); } // make sure the elements match QName startElement = fQName; fElementStack.popElement(startElement); if (element.rawname != startElement.rawname) { reportFatalError("ETagRequired", new Object[]{startElement.rawname}); } // bind namespaces if (fNamespaces) { element.uri = startElement.uri; } // call handler if (fDocumentHandler != null && !isEmpty) { fDocumentHandler.endElement(element, null); } return fMarkupDepth; } // callEndElement(QName,boolean):int // helper methods /** * Sets the scanner state. * * @param state The new scanner state. */ protected final void setScannerState(int state) { fScannerState = state; if (DEBUG_SCANNER_STATE) { System.out.print("### setScannerState: "); System.out.print(getScannerStateName(state)); System.out.println(); } } // setScannerState(int) /**
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?