
com.sun.xml.stream.XMLNSDocumentScannerImpl Maven / Gradle / Ivy
Show all versions of sjsxp Show documentation
/*
* $Id: XMLNSDocumentScannerImpl.java,v 1.8 2009-11-20 21:07:25 joehw Exp $
*/
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2002 The Apache Software Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact [email protected].
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2002, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* .
*/
package com.sun.xml.stream;
import java.io.IOException;
import javax.xml.stream.events.XMLEvent;
import com.sun.xml.stream.xerces.xni.XMLString;
//import com.sun.xml.stream.xerces.impl.dtd.XMLDTDValidatorFilter;
import com.sun.xml.stream.xerces.impl.msg.XMLMessageFormatter;
import com.sun.xml.stream.xerces.util.XMLAttributesImpl;
import com.sun.xml.stream.xerces.util.XMLStringBuffer;
import com.sun.xml.stream.xerces.util.XMLSymbols;
import com.sun.xml.stream.xerces.xni.NamespaceContext;
import com.sun.xml.stream.xerces.xni.QName;
import com.sun.xml.stream.xerces.xni.XNIException;
import com.sun.xml.stream.xerces.xni.parser.XMLComponentManager;
import com.sun.xml.stream.xerces.xni.parser.XMLConfigurationException;
/**
* 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 2009-11-20 21:07:25 joehw Exp $
*/
public class XMLNSDocumentScannerImpl
extends XMLDocumentScannerImpl {
/** If validating parser, make sure we report an error in the
* scanner if DTD grammar is missing.*/
protected boolean fPerformValidation;
private boolean fEmptyElement = false;
private XMLBufferListenerImpl listener = new XMLBufferListenerImpl();
// private boolean fClearAttributes = true;
private boolean fXmlnsDeclared = false;
/** Resets the fields of this scanner.
*/
public void reset(PropertyManager propertyManager) {
setPropertyManager(propertyManager);
super.reset(propertyManager);
try{
if(!fAttributeCacheInitDone){
for(int i=0; i
*
* [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
* [40] STag ::= '<' Name (S Attribute)* S? '>'
*
*
* Note: This method assumes that the leading
* '<' character has been consumed.
*
* Note: 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_CONTENT_SCANNING) System.out.println(">>> 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.characters); // 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();
// name
if (fBindNamespaces) {
fEntityScanner.scanQName(fElementQName);
}
else {
String name = fEntityScanner.scanName();
fElementQName.setValues(null, name, name, null);
//XXX: THIS IS UGLY -- THIS SHOULD BE CHANGED.
//WE SHOULD DO IT AS PART OF QNAME -- NB.
fElementQName.characters = fEntityScanner.scannedName;
}
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;
// attributes must be always cleared
//if(fClearAttributes)
fAttributes.removeAllAttributes();
if(!seekCloseOfStartTag()){
fReadingAttributes = true;
fAttributeCacheUsedCount =0;
fStringBufferIndex =0;
//fClearAttributes=true;
fAddDefaultAttr = true;
fXmlnsDeclared = false;
do {
scanAttribute(fAttributes);
} while (!seekCloseOfStartTag());
fReadingAttributes=false;
} /*else{
fClearAttributes=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) {
fAttributeQName.uri = uri;
if (uri == null) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributePrefixUnbound",
new Object[]{fElementQName.rawname,fAttributeQName.rawname,aprefix},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
fAttributes.setURI(i, uri);
// checkDuplicates(fAttributeQName, fAttributes);
}
}
if (length > 1) {
QName name = fAttributes.checkDuplicatesNS();
if (name != null) {
if (name.uri != null) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNSNotUnique",
new Object[]{fElementQName.rawname, name.localpart, name.uri},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
else {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNotUnique",
new Object[]{fElementQName.rawname, name.rawname},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
}
}
if (fEmptyElement) {
//decrease the markup depth..
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.emptyElement(fElementQName, fAttributes, null);
}
//We should not be popping out the context here in endELement becaause the namespace context is still
//valid when parser is at the endElement state.
fScanEndElement = true;
//if (fBindNamespaces) {
// fNamespaceContext.popContext();
//}
//pop the element off the stack..
fElementStack.popElement();
} else {
if(dtdGrammarUtil != null){
dtdGrammarUtil.startElement(fElementQName, fAttributes);
}
if(fDocumentHandler != null){
//fDocumentHandler.startElement(fElementQName, fAttributes, null);
}
}
if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanStartElement(): "+fEmptyElement);
return fEmptyElement;
} // scanStartElement():boolean
/**
* Looks for the close of start tag, i.e. if it finds '>' or '/>'
* Characters are consumed.
*/
private boolean seekCloseOfStartTag() throws IOException, XNIException {
// spaces
boolean sawSpace = fEntityScanner.skipSpaces();
// end tag?
final int c = fEntityScanner.peekChar();
if (c == '>') {
fEntityScanner.scanChar();
return true;
}
else if (c == '/') {
fEntityScanner.scanChar();
if (!fEntityScanner.skipChar('>')) {
reportFatalError("ElementUnterminated",
new Object[]{fElementQName.rawname});
}
fEmptyElement = true;
return true;
}
else if (!isValidNameStartChar(c) || !sawSpace) {
reportFatalError("ElementUnterminated", new Object[]{fElementQName.rawname});
}
return false;
}
/**
* Scans an attribute.
*
*
* [41] Attribute ::= Name Eq AttValue
*
*
* Note: This method assumes that the next
* character on the stream is the first character of the attribute
* name.
*
* Note: This method uses the fAttributeQName and
* fQName variables. The contents of these variables will be
* destroyed.
*
* @param attributes The attributes list for the scanned attribute.
*/
protected void scanAttribute(XMLAttributesImpl attributes)
throws IOException, XNIException {
if (DEBUG_CONTENT_SCANNING) System.out.println(">>> scanAttribute()");
// name
fEntityScanner.scanQName(fAttributeQName);
// equals
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=')) {
reportFatalError("EqRequiredInAttribute",
new Object[]{fCurrentElement.rawname,fAttributeQName.rawname});
}
fEntityScanner.skipSpaces();
// content
int attrIndex = 0 ;
//REVISIT: one more case needs to be included: external PE and standalone is no
boolean isVC = fHasExternalDTD && !fStandalone;
// REVISIT: it seems that this function should not take attributes, and length
//fTempString would store attribute value
///fTempString2 would store attribute non-normalized value
//this function doesn't use 'attIndex'. We are adding the attribute later
//after we have figured out that current attribute is not namespace declaration
//since scanAttributeValue doesn't use attIndex parameter therefore we
//can safely add the attribute later..
XMLString tmpStr = getString();
scanAttributeValue(tmpStr, fTempString2,
fAttributeQName.rawname, attributes,
attrIndex, isVC);
String value = null;
//fTempString.toString();
// record namespace declarations if any.
if (fBindNamespaces) {
String localpart = fAttributeQName.localpart;
String prefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
// when it's of form xmlns="..." or xmlns:prefix="...",
// it's a namespace declaration. but prefix:xmlns="..." isn't.
if (prefix == XMLSymbols.PREFIX_XMLNS ||
prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) {
// get the internalized value of this attribute
String uri = fSymbolTable.addSymbol(tmpStr.ch,tmpStr.offset,tmpStr.length);
value = uri;
// 1. "xmlns" can't be bound to any namespace
if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 2. the namespace for "xmlns" can't be bound to any prefix
if (uri == NamespaceContext.XMLNS_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 3. "xml" can't be bound to any other namespace than it's own
if (localpart == XMLSymbols.PREFIX_XML) {
if (uri != NamespaceContext.XML_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
// 4. the namespace for "xml" can't be bound to any other prefix
else {
if (uri ==NamespaceContext.XML_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
// http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-prefix
// We should only report an error if there is a prefix,
// that is, the local part is not "xmlns". -SG
if (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"EmptyPrefixedAttName",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// check for duplicate prefix bindings
if (((com.sun.xml.stream.xerces.util.NamespaceSupport) fNamespaceContext).containsPrefixInCurrentContext(prefix)) {
reportFatalError("AttributeNotUnique",
new Object[]{fCurrentElement.rawname,
fAttributeQName.rawname});
}
// declare prefix in context
boolean declared = fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
// check for duplicate xmlns declarations
if (!declared) { // by convention, prefix == "xmlns" | "xml"
// error if duplicate declaration
if (fXmlnsDeclared) {
reportFatalError("AttributeNotUnique",
new Object[]{fCurrentElement.rawname,
fAttributeQName.rawname});
}
// xmlns declared
fXmlnsDeclared = true;
}
//we are not adding namespace declarations in the XMLAttributes.
//Namespace declarations are available from fNamespaceContext
return ;
// bind namespace attribute to a namespace
//we are not adding namespace declarations tothe list of attribute
//attributes.setURI(attrIndex, fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS));
}
}
//add the attributes to the list of attributes
if (fBindNamespaces) {
attrIndex = attributes.getLength();
attributes.addAttributeNS(fAttributeQName, XMLSymbols.fCDATASymbol, null);
}
else {
int oldLen = attributes.getLength();
attrIndex = attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null);
// WFC: Unique Att Spec
if (oldLen == attributes.getLength()) {
reportFatalError("AttributeNotUnique",
new Object[]{fCurrentElement.rawname,
fAttributeQName.rawname});
}
}
attributes.setValue(attrIndex, value,tmpStr);
//attributes.setNonNormalizedValue(attrIndex, fTempString2.toString());
//removing as we are not using non-normalized values . -Venu
attributes.setSpecified(attrIndex, true);
// attempt to bind attribute
if (fAttributeQName.prefix != null) {
attributes.setURI(attrIndex, fNamespaceContext.getURI(fAttributeQName.prefix));
}
if (DEBUG_CONTENT_SCANNING) System.out.println("<<< scanAttribute()");
} // scanAttribute(XMLAttributes)
/**
* Scans an end element.
*
*
* [42] ETag ::= '</' Name S? '>'
*
*
* Note: 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()");
// pop context
QName endElementName = fElementStack.popElement();
String rawname = endElementName.rawname;
// 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 - [email protected]
// 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.
//Pass characters instead of string , this gives better performance than strings.
//Use the character array for rawname present in the symboltable. -Venu
if (!fEntityScanner.skipString(endElementName.characters)) {
reportFatalError("ETagRequired", new Object[]{rawname});
}
// end
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>')) {
reportFatalError("ETagUnterminated",
new Object[]{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[]{rawname});
}
//We should not be popping out the context here in endELement becaause the namespace context is still
//valid when parser is at the endElement state.
//if (fBindNamespaces) {
// fNamespaceContext.popContext();
//}
// call handler
if (fDocumentHandler != null ) {
//xxx: Commenting this now since we are not passing any information
//along the pipeline. However, we do need to set the values if we
//need to pass the values along the pipeline.
//fDocumentHandler.endElement(fElementQName, null);
}
if(dtdGrammarUtil != null)
dtdGrammarUtil.endElement(endElementName);
fScanEndElement = true;
return fMarkupDepth;
} // scanEndElement():int
//getNamespaceContext
public NamespaceContext getNamespaceContext(){
return fNamespaceContext ;
}
public void reset(XMLComponentManager componentManager)
throws XMLConfigurationException {
super.reset(componentManager);
fPerformValidation = false;
fBindNamespaces = false;
}
/** Creates a content driver. */
protected Driver createContentDriver() {
return new NSContentDriver();
} // createContentDriver():Driver
/**
* Driver to handle content scanning.
*/
protected final class NSContentDriver
extends ContentDriver {
/**
* Scan for root element hook. This method is a hook for
* subclasses to add code that handles scanning for the root
* element. This method will also attempt to remove DTD validator
* from the pipeline, if there is no DTD grammar. If DTD validator
* is no longer in the pipeline bind namespaces in the scanner.
*
*
* @return True if the caller should stop and return true which
* allows the scanner to switch to a new scanning
* driver. A return value of false indicates that
* the content driver should continue as normal.
*/
protected boolean scanRootElementHook()
throws IOException, XNIException {
if (scanStartElement()) {
setScannerState(SCANNER_STATE_TRAILING_MISC);
setDriver(fTrailingMiscDriver);
return true;
}
return false;
} // scanRootElementHook():boolean
}
XMLString getString(){
if(fAttributeCacheUsedCount < initialCacheCount || fAttributeCacheUsedCount < attributeValueCache.size()){
return (XMLString)attributeValueCache.get(fAttributeCacheUsedCount++);
}
else{
XMLString str = new XMLString();
fAttributeCacheUsedCount++;
attributeValueCache.add(str);
return str;
}
}
public XMLStringBuffer getDTDDecl(){
Entity entity = fEntityScanner.getCurrentEntity();
fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos);
if(fSeenInternalSubset)
fDTDDecl.append("]>");
return fDTDDecl;
}
public String getCharacterEncodingScheme(){
return fDeclaredEncoding;
}
} // class XMLNSDocumentScannerImpl