📄 xmlnsdocumentscannerimpl.java
字号:
/* * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the "License"). You may not use this file except * in compliance with the License. * * You can obtain a copy of the license at * https://jaxp.dev.java.net/CDDLv1.0.html. * See the License for the specific language governing * permissions and limitations under the License. * * When distributing Covered Code, include this CDDL * HEADER in each file and include the License file at * https://jaxp.dev.java.net/CDDLv1.0.html * If applicable add the following below this CDDL HEADER * with the fields enclosed by brackets "[]" replaced with * your own identifying information: Portions Copyright * [year] [name of copyright owner] *//* * $Id: XMLNSDocumentScannerImpl.java,v 1.8 2006/02/08 07:40:59 sunithareddy Exp $ * @(#)XMLNSDocumentScannerImpl.java 1.19 06/04/07 * * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. *//* * Copyright 2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.sun.org.apache.xerces.internal.impl;import java.io.IOException;import com.sun.org.apache.xerces.internal.xni.XMLString;import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidatorFilter;import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;import com.sun.org.apache.xerces.internal.util.XMLAttributesIteratorImpl;import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;import com.sun.org.apache.xerces.internal.util.XMLSymbols;import com.sun.org.apache.xerces.internal.xni.NamespaceContext;import com.sun.org.apache.xerces.internal.xni.QName;import com.sun.org.apache.xerces.internal.xni.XNIException;import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;import com.sun.org.apache.xerces.internal.xni.XMLAttributes;import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;import javax.xml.stream.XMLInputFactory;import javax.xml.stream.XMLStreamConstants;import javax.xml.stream.events.XMLEvent;/** * This class adds the functionality of namespace processing. * * This class has been modified as per the new design which is more suited to * efficiently build pull parser. Lot of improvements have been done and * the code has been added to support stax functionality/features. * * * This class scans an XML document, checks if document has a DTD, and if * DTD is not found the scanner will remove the DTD Validator from the pipeline and perform * namespace binding. * * * @author Neeraj Bajaj, Sun Microsystems * @author Venugopal Rao K, Sun Microsystems * @author Elena Litani, IBM * @version $Id: XMLNSDocumentScannerImpl.java,v 1.8 2006/02/08 07:40:59 sunithareddy Exp $ */public class XMLNSDocumentScannerImpl extends XMLDocumentScannerImpl { /** * If is true, the dtd validator is no longer in the pipeline * and the scanner should bind namespaces */ protected boolean fBindNamespaces; /** If validating parser, make sure we report an error in the * scanner if DTD grammar is missing.*/ protected boolean fPerformValidation; /** Default value of this feature is false, when in Stax mode this should be true */ protected boolean fNotAddNSDeclAsAttribute = false; /** DTD validator */ private XMLDTDValidatorFilter fDTDValidator; /** xmlns, default Namespace, declared */ private boolean fXmlnsDeclared = false; /** Resets the fields of this scanner. */ public void reset(PropertyManager propertyManager) { setPropertyManager(propertyManager); super.reset(propertyManager); fBindNamespaces = false; fNotAddNSDeclAsAttribute = !((Boolean)propertyManager.getProperty(Constants.ADD_NAMESPACE_DECL_AS_ATTRIBUTE)).booleanValue(); } public void reset(XMLComponentManager componentManager) throws XMLConfigurationException { super.reset(componentManager); fNotAddNSDeclAsAttribute = false ; fPerformValidation = false; fBindNamespaces = false; } /** return the next state on the input * * @return int */ public int next() throws IOException, XNIException { //since namespace context should still be valid when the parser is at the end element state therefore //we pop the context only when next() has been called after the end element state was encountered. - nb. if((fScannerLastState == XMLEvent.END_ELEMENT) && fBindNamespaces){ fScannerLastState = -1; fNamespaceContext.popContext(); } return fScannerLastState = super.next(); } /** * The scanner is responsible for removing DTD validator * from the pipeline if it is not needed. * * @param previous The filter component before DTDValidator * @param dtdValidator * The DTDValidator * @param next The documentHandler after the DTDValidator */ public void setDTDValidator(XMLDTDValidatorFilter dtd){ fDTDValidator = dtd; } /** * Scans a start element. This method will handle the binding of * namespace information and notifying the handler of the start * of the element. * <p> * <pre> * [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' * [40] STag ::= '<' Name (S Attribute)* S? '>' * </pre> * <p> * <strong>Note:</strong> This method assumes that the leading * '<' character has been consumed. * <p> * <strong>Note:</strong> This method uses the fElementQName and * fAttributes variables. The contents of these variables will be * destroyed. The caller should copy important information out of * these variables before calling this method. * * @return True if element is empty. (i.e. It matches * production [44]. */ protected boolean scanStartElement() throws IOException, XNIException { if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +">>> scanStartElement()"); //when skipping is true and no more elements should be added if(fSkip && !fAdd){ //get the stored element -- if everything goes right this should match the //token in the buffer QName name = fElementStack.getNext(); if(DEBUG_SKIP_ALGORITHM){ System.out.println("Trying to skip String = " + name.rawname); } //Be conservative -- if skipping fails -- stop. fSkip = fEntityScanner.skipString(name.rawname); // skipQElement(name); if(fSkip){ if(DEBUG_SKIP_ALGORITHM){ System.out.println("Element SUCESSFULLY skipped = " + name.rawname); } fElementStack.push(); fElementQName = name; }else{ //if skipping fails reposition the stack or fallback to normal way of processing fElementStack.reposition(); if(DEBUG_SKIP_ALGORITHM){ System.out.println("Element was NOT skipped, REPOSITIONING stack" ); } } } //we are still at the stage of adding elements //the elements were not matched or //fSkip is not set to true if(!fSkip || fAdd){ //get the next element from the stack fElementQName = fElementStack.nextElement(); // There are two variables,fNamespaces and fBindNamespaces //StAX uses XMLNSDocumentScannerImpl so this distinction needs to be maintained if (fNamespaces) { fEntityScanner.scanQName(fElementQName); } else { String name = fEntityScanner.scanName(); fElementQName.setValues(null, name, name, null); } if(DEBUG)System.out.println("Element scanned in start element is " + fElementQName.toString()); if(DEBUG_SKIP_ALGORITHM){ if(fAdd){ System.out.println("Elements are being ADDED -- elemet added is = " + fElementQName.rawname + " at count = " + fElementStack.fCount); } } } //when the elements are being added , we need to check if we are set for skipping the elements if(fAdd){ //this sets the value of fAdd variable fElementStack.matchElement(fElementQName); } //xxx: We dont need another pointer, fCurrentElement, we can use fElementQName fCurrentElement = fElementQName; String rawname = fElementQName.rawname; if (fBindNamespaces) { fNamespaceContext.pushContext(); if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) { if (fPerformValidation) { fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "MSG_GRAMMAR_NOT_FOUND", new Object[]{ rawname}, XMLErrorReporter.SEVERITY_ERROR); if (fDoctypeName == null || !fDoctypeName.equals(rawname)) { fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN, "RootElementTypeMustMatchDoctypedecl", new Object[]{fDoctypeName, rawname}, XMLErrorReporter.SEVERITY_ERROR); } } } } fEmptyElement = false; fAttributes.removeAllAttributes(); if(!seekCloseOfStartTag()){ fReadingAttributes = true; fAttributeCacheUsedCount =0; fStringBufferIndex =0; fAddDefaultAttr = true; fXmlnsDeclared = false; do { scanAttribute(fAttributes); if (fSecurityManager != null && fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", new Object[]{rawname, new Integer(fAttributes.getLength()) }, XMLErrorReporter.SEVERITY_FATAL_ERROR ); } } while (!seekCloseOfStartTag()); fReadingAttributes=false; } if (fBindNamespaces) { // REVISIT: is it required? forbit xmlns prefix for element if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "ElementXMLNSPrefix", new Object[]{fElementQName.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // bind the element String prefix = fElementQName.prefix != null ? fElementQName.prefix : XMLSymbols.EMPTY_STRING; // assign uri to the element fElementQName.uri = fNamespaceContext.getURI(prefix); // make sure that object in the element stack is updated as well fCurrentElement.uri = fElementQName.uri; if (fElementQName.prefix == null && fElementQName.uri != null) { fElementQName.prefix = XMLSymbols.EMPTY_STRING; } if (fElementQName.prefix != null && fElementQName.uri == null) { fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN, "ElementPrefixUnbound", new Object[]{fElementQName.prefix, fElementQName.rawname}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } // bind attributes (xmlns are already bound bellow) int length = fAttributes.getLength(); // fLength = 0; //initialize structure for (int i = 0; i < length; i++) { fAttributes.getName(i, fAttributeQName); String aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING; String uri = fNamespaceContext.getURI(aprefix); // REVISIT: try removing the first "if" and see if it is faster. // if (fAttributeQName.uri != null && fAttributeQName.uri == uri) { // checkDuplicates(fAttributeQName, fAttributes); continue; } if (aprefix != XMLSymbols.EMPTY_STRING) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -