XMLDocumentScannerImpl.java revision 1083:5621e47022e5
177957Sbenno/* 290643Sbenno * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 390643Sbenno */ 490643Sbenno 590643Sbenno/* 690643Sbenno * Licensed to the Apache Software Foundation (ASF) under one or more 790643Sbenno * contributor license agreements. See the NOTICE file distributed with 890643Sbenno * this work for additional information regarding copyright ownership. 990643Sbenno * The ASF licenses this file to You under the Apache License, Version 2.0 1090643Sbenno * (the "License"); you may not use this file except in compliance with 1190643Sbenno * the License. You may obtain a copy of the License at 1290643Sbenno * 1390643Sbenno * http://www.apache.org/licenses/LICENSE-2.0 1490643Sbenno * 1590643Sbenno * Unless required by applicable law or agreed to in writing, software 1690643Sbenno * distributed under the License is distributed on an "AS IS" BASIS, 1790643Sbenno * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1890643Sbenno * See the License for the specific language governing permissions and 1990643Sbenno * limitations under the License. 2090643Sbenno */ 2190643Sbenno 2290643Sbennopackage com.sun.org.apache.xerces.internal.impl; 2390643Sbenno 2490643Sbennoimport com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription; 2590643Sbennoimport com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; 2690643Sbennoimport com.sun.org.apache.xerces.internal.util.NamespaceSupport; 2790643Sbennoimport com.sun.org.apache.xerces.internal.util.XMLChar; 2890643Sbennoimport com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl; 2990643Sbennoimport com.sun.org.apache.xerces.internal.util.XMLStringBuffer; 3090643Sbennoimport com.sun.org.apache.xerces.internal.utils.SecuritySupport; 3190643Sbennoimport com.sun.org.apache.xerces.internal.xni.Augmentations; 3290643Sbennoimport com.sun.org.apache.xerces.internal.xni.NamespaceContext; 3390643Sbennoimport com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; 3490643Sbennoimport com.sun.org.apache.xerces.internal.xni.XNIException; 3590643Sbennoimport com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 3690643Sbennoimport com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 3777957Sbennoimport com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner; 3877957Sbennoimport com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 3977957Sbennoimport com.sun.xml.internal.stream.Entity; 4077957Sbennoimport com.sun.xml.internal.stream.StaxXMLInputSource; 4177957Sbennoimport com.sun.xml.internal.stream.dtd.DTDGrammarUtil; 4277957Sbennoimport java.io.EOFException; 4377957Sbennoimport java.io.IOException; 4477957Sbennoimport javax.xml.stream.XMLInputFactory; 4577957Sbennoimport javax.xml.stream.events.XMLEvent; 4677957Sbenno 4777957Sbenno 4877957Sbenno/** 4977957Sbenno * This class is responsible for scanning XML document structure 5077957Sbenno * and content. 5177957Sbenno * 5277957Sbenno * This class has been modified as per the new design which is more suited to 5377957Sbenno * efficiently build pull parser. Lot of improvements have been done and 5477957Sbenno * the code has been added to support stax functionality/features. 5577957Sbenno * 5677957Sbenno * @author Neeraj Bajaj, Sun Microsystems 5777957Sbenno * @author K.Venugopal, Sun Microsystems 5877957Sbenno * @author Glenn Marcy, IBM 5977957Sbenno * @author Andy Clark, IBM 6077957Sbenno * @author Arnaud Le Hors, IBM 6177957Sbenno * @author Eric Ye, IBM 6277957Sbenno * @author Sunitha Reddy, Sun Microsystems 6377957Sbenno * 6477957Sbenno * Refer to the table in unit-test javax.xml.stream.XMLStreamReaderTest.SupportDTD for changes 6577957Sbenno * related to property SupportDTD. 6678880Sbenno * @author Joe Wang, Sun Microsystems 6777957Sbenno */ 6877957Sbennopublic class XMLDocumentScannerImpl 6977957Sbenno extends XMLDocumentFragmentScannerImpl{ 7077957Sbenno 7177957Sbenno // 7277957Sbenno // Constants 7377957Sbenno // 7477957Sbenno 7577957Sbenno // scanner states 7677957Sbenno 7777957Sbenno /** Scanner state: XML declaration. */ 7877957Sbenno protected static final int SCANNER_STATE_XML_DECL = 42; 7977957Sbenno 8077957Sbenno /** Scanner state: prolog. */ 8177957Sbenno protected static final int SCANNER_STATE_PROLOG = 43; 8277957Sbenno 8377957Sbenno /** Scanner state: trailing misc. */ 8477957Sbenno protected static final int SCANNER_STATE_TRAILING_MISC = 44; 8577957Sbenno 8677957Sbenno /** Scanner state: DTD internal declarations. */ 8777957Sbenno protected static final int SCANNER_STATE_DTD_INTERNAL_DECLS = 45; 8877957Sbenno 8977957Sbenno /** Scanner state: open DTD external subset. */ 9077957Sbenno protected static final int SCANNER_STATE_DTD_EXTERNAL = 46; 9177957Sbenno 9277957Sbenno /** Scanner state: DTD external declarations. */ 9377957Sbenno protected static final int SCANNER_STATE_DTD_EXTERNAL_DECLS = 47; 9477957Sbenno 9577957Sbenno /** Scanner state: NO MORE ELEMENTS. */ 9677957Sbenno protected static final int SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION = 48; 9777957Sbenno 9890643Sbenno // feature identifiers 9990643Sbenno 10090643Sbenno /** Property identifier document scanner: */ 10190643Sbenno protected static final String DOCUMENT_SCANNER = 10290643Sbenno Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY; 10390643Sbenno 10490643Sbenno /** Feature identifier: load external DTD. */ 10590643Sbenno protected static final String LOAD_EXTERNAL_DTD = 10690643Sbenno Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE; 10790643Sbenno 10890643Sbenno /** Feature identifier: load external DTD. */ 10990643Sbenno protected static final String DISALLOW_DOCTYPE_DECL_FEATURE = 11090643Sbenno Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE; 11190643Sbenno 11290643Sbenno // property identifiers 11390643Sbenno 11490643Sbenno /** Property identifier: DTD scanner. */ 11590643Sbenno protected static final String DTD_SCANNER = 11690643Sbenno Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY; 11790643Sbenno 11890643Sbenno // property identifier: ValidationManager 11977957Sbenno protected static final String VALIDATION_MANAGER = 12080431Speter Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 12190643Sbenno 12290643Sbenno /** property identifier: NamespaceContext */ 12390643Sbenno protected static final String NAMESPACE_CONTEXT = 12490643Sbenno Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY; 12577957Sbenno 12690643Sbenno // recognized features and properties 12790643Sbenno 12877957Sbenno /** Recognized features. */ 12977957Sbenno private static final String[] RECOGNIZED_FEATURES = { 13090643Sbenno LOAD_EXTERNAL_DTD, 13190643Sbenno DISALLOW_DOCTYPE_DECL_FEATURE, 13290643Sbenno }; 13377957Sbenno 13477957Sbenno /** Feature defaults. */ 13577957Sbenno private static final Boolean[] FEATURE_DEFAULTS = { 13677957Sbenno Boolean.TRUE, 13777957Sbenno Boolean.FALSE, 13877957Sbenno }; 13977957Sbenno 14077957Sbenno /** Recognized properties. */ 14177957Sbenno private static final String[] RECOGNIZED_PROPERTIES = { 14277957Sbenno DTD_SCANNER, 14383730Smp VALIDATION_MANAGER 14490643Sbenno }; 14590643Sbenno 14690643Sbenno /** Property defaults. */ 14777957Sbenno private static final Object[] PROPERTY_DEFAULTS = { 14890643Sbenno null, 14977957Sbenno null 15090643Sbenno }; 15177957Sbenno 15290643Sbenno // 15377957Sbenno // Data((Boolean)propertyManager.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE)).booleanValue(); 15490643Sbenno // 15590643Sbenno 15690643Sbenno // properties 15790643Sbenno 15890643Sbenno /** DTD scanner. */ 15990643Sbenno protected XMLDTDScanner fDTDScanner = null; 16090643Sbenno 16190643Sbenno /** Validation manager . */ 16290643Sbenno //xxx: fValidationManager code needs to be added yet! 16390643Sbenno protected ValidationManager fValidationManager; 16490643Sbenno 16590643Sbenno protected XMLStringBuffer fDTDDecl = null; 16690643Sbenno protected boolean fReadingDTD = false; 16790643Sbenno protected boolean fAddedListener = false; 16890643Sbenno 16990643Sbenno // protected data 17090643Sbenno 17190643Sbenno // other info 17290643Sbenno 17390643Sbenno /** Doctype name. */ 17490643Sbenno protected String fDoctypeName; 17590643Sbenno 17690643Sbenno /** Doctype declaration public identifier. */ 17790643Sbenno protected String fDoctypePublicId; 17890643Sbenno 17990643Sbenno /** Doctype declaration system identifier. */ 18090643Sbenno protected String fDoctypeSystemId; 18190643Sbenno 18290643Sbenno /** Namespace support. */ 18390643Sbenno protected NamespaceContext fNamespaceContext = new NamespaceSupport(); 18490643Sbenno 18577957Sbenno // features 18677957Sbenno 18790643Sbenno /** Load external DTD. */ 18890643Sbenno protected boolean fLoadExternalDTD = true; 18990643Sbenno 19090643Sbenno // state 19190643Sbenno 19290643Sbenno /** Seen doctype declaration. */ 19377957Sbenno protected boolean fSeenDoctypeDecl; 19490643Sbenno 19577957Sbenno protected boolean fScanEndElement; 19690643Sbenno 19790643Sbenno //protected int fScannerLastState ; 19890643Sbenno 19990643Sbenno // drivers 20090643Sbenno 20177957Sbenno /** XML declaration driver. */ 20290643Sbenno protected Driver fXMLDeclDriver = new XMLDeclDriver(); 20390643Sbenno 20490643Sbenno /** Prolog driver. */ 20590643Sbenno protected Driver fPrologDriver = new PrologDriver(); 20690643Sbenno 20777957Sbenno /** DTD driver. */ 20890643Sbenno protected Driver fDTDDriver = null ; 20990643Sbenno 21090643Sbenno /** Trailing miscellaneous section driver. */ 21190643Sbenno protected Driver fTrailingMiscDriver = new TrailingMiscDriver(); 21290643Sbenno protected int fStartPos = 0; 21390643Sbenno protected int fEndPos = 0; 21490643Sbenno protected boolean fSeenInternalSubset= false; 21590643Sbenno // temporary variables 21677957Sbenno 21790643Sbenno /** Array of 3 strings. */ 21890643Sbenno private String[] fStrings = new String[3]; 21990643Sbenno 22090643Sbenno /** External subset source. */ 22190643Sbenno private XMLInputSource fExternalSubsetSource = null; 22290643Sbenno 22377957Sbenno /** A DTD Description. */ 22490643Sbenno private final XMLDTDDescription fDTDDescription = new XMLDTDDescription(null, null, null, null, null); 22590643Sbenno 22690643Sbenno private static final char [] DOCTYPE = {'D','O','C','T','Y','P','E'}; 22790643Sbenno private static final char [] COMMENTSTRING = {'-','-'}; 22890643Sbenno 22977957Sbenno // 23090643Sbenno // Constructors 23190643Sbenno // 23290643Sbenno 23390643Sbenno /** Default constructor. */ 23490643Sbenno public XMLDocumentScannerImpl() {} // <init>() 23590643Sbenno 23677957Sbenno 23790643Sbenno // 23890643Sbenno // XMLDocumentScanner methods 23990643Sbenno // 24090643Sbenno 24190643Sbenno 24290643Sbenno /** 24390643Sbenno * Sets the input source. 24490643Sbenno * 24577957Sbenno * @param inputSource The input source. 24690643Sbenno * 24790643Sbenno * @throws IOException Thrown on i/o error. 24890643Sbenno */ 24990643Sbenno public void setInputSource(XMLInputSource inputSource) throws IOException { 25090643Sbenno fEntityManager.setEntityHandler(this); 25190643Sbenno //this starts a new entity and sets the current entity to the document entity. 25277957Sbenno fEntityManager.startDocumentEntity(inputSource); 25390643Sbenno // fDocumentSystemId = fEntityManager.expandSystemId(inputSource.getSystemId()); 25490643Sbenno setScannerState(XMLEvent.START_DOCUMENT); 25577957Sbenno } // setInputSource(XMLInputSource) 25690643Sbenno 25790643Sbenno 25877957Sbenno 25990643Sbenno /**return the state of the scanner */ 26077957Sbenno public int getScannetState(){ 26190643Sbenno return fScannerState ; 26290643Sbenno } 26390643Sbenno 26490643Sbenno 26590643Sbenno 26690643Sbenno 26790643Sbenno public void reset(PropertyManager propertyManager) { 26890643Sbenno super.reset(propertyManager); 26990643Sbenno // other settings 27090643Sbenno fDoctypeName = null; 27190643Sbenno fDoctypePublicId = null; 27290643Sbenno fDoctypeSystemId = null; 27390643Sbenno fSeenDoctypeDecl = false; 27490643Sbenno fNamespaceContext.reset(); 27590643Sbenno fSupportDTD = ((Boolean)propertyManager.getProperty(XMLInputFactory.SUPPORT_DTD)).booleanValue(); 27690643Sbenno 27790643Sbenno // xerces features 27890643Sbenno fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue(); 27990643Sbenno setScannerState(XMLEvent.START_DOCUMENT); 28090643Sbenno setDriver(fXMLDeclDriver); 28190643Sbenno fSeenInternalSubset = false; 28290643Sbenno if(fDTDScanner != null){ 28390643Sbenno ((XMLDTDScannerImpl)fDTDScanner).reset(propertyManager); 28490643Sbenno } 28577957Sbenno fEndPos = 0; 28690643Sbenno fStartPos = 0; 28777957Sbenno if(fDTDDecl != null){ 28890643Sbenno fDTDDecl.clear(); 28990643Sbenno } 29077957Sbenno 29190643Sbenno } 29290643Sbenno 29390643Sbenno /** 29490643Sbenno * Resets the component. The component can query the component manager 29577957Sbenno * about any features and properties that affect the operation of the 29690643Sbenno * component. 29790643Sbenno * 29890643Sbenno * @param componentManager The component manager. 29990643Sbenno * 30077957Sbenno * @throws SAXException Thrown by component on initialization error. 30177957Sbenno * For example, if a feature or property is 30290643Sbenno * required for the operation of the component, the 30377957Sbenno * component manager may throw a 30490643Sbenno * SAXNotRecognizedException or a 30590643Sbenno * SAXNotSupportedException. 30690643Sbenno */ 30790643Sbenno public void reset(XMLComponentManager componentManager) 30890643Sbenno throws XMLConfigurationException { 30990643Sbenno 31090643Sbenno super.reset(componentManager); 31190643Sbenno 31290643Sbenno // other settings 31390643Sbenno fDoctypeName = null; 31490643Sbenno fDoctypePublicId = null; 31590643Sbenno fDoctypeSystemId = null; 31690643Sbenno fSeenDoctypeDecl = false; 31790643Sbenno fExternalSubsetSource = null; 31890643Sbenno 31990643Sbenno // xerces features 32090643Sbenno fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD, true); 32190643Sbenno fDisallowDoctype = componentManager.getFeature(DISALLOW_DOCTYPE_DECL_FEATURE, false); 32290643Sbenno 32390643Sbenno fNamespaces = componentManager.getFeature(NAMESPACES, true); 32477957Sbenno 32590643Sbenno fSeenInternalSubset = false; 32690643Sbenno // xerces properties 32777957Sbenno fDTDScanner = (XMLDTDScanner)componentManager.getProperty(DTD_SCANNER); 32890643Sbenno 32990643Sbenno fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER, null); 33090643Sbenno 33190643Sbenno try { 33290643Sbenno fNamespaceContext = (NamespaceContext)componentManager.getProperty(NAMESPACE_CONTEXT); 33390643Sbenno } 33490643Sbenno catch (XMLConfigurationException e) { } 33590643Sbenno if (fNamespaceContext == null) { 33677957Sbenno fNamespaceContext = new NamespaceSupport(); 33777957Sbenno } 33890643Sbenno fNamespaceContext.reset(); 33990643Sbenno 34077957Sbenno fEndPos = 0; 34190643Sbenno fStartPos = 0; 34277957Sbenno if(fDTDDecl != null) 34390643Sbenno fDTDDecl.clear(); 34490643Sbenno 34590643Sbenno 34690643Sbenno //fEntityScanner.registerListener((XMLBufferListener)componentManager.getProperty(DOCUMENT_SCANNER)); 34790643Sbenno 34890643Sbenno // setup driver 34977957Sbenno setScannerState(SCANNER_STATE_XML_DECL); 35077957Sbenno setDriver(fXMLDeclDriver); 35190643Sbenno 35290643Sbenno } // reset(XMLComponentManager) 35390643Sbenno 35490643Sbenno 35590643Sbenno /** 35690643Sbenno * Returns a list of feature identifiers that are recognized by 35790643Sbenno * this component. This method may return null if no features 35877957Sbenno * are recognized by this component. 35990643Sbenno */ 36077957Sbenno public String[] getRecognizedFeatures() { 36190643Sbenno String[] featureIds = super.getRecognizedFeatures(); 36290643Sbenno int length = featureIds != null ? featureIds.length : 0; 36377957Sbenno String[] combinedFeatureIds = new String[length + RECOGNIZED_FEATURES.length]; 36477957Sbenno if (featureIds != null) { 36577957Sbenno System.arraycopy(featureIds, 0, combinedFeatureIds, 0, featureIds.length); 36690643Sbenno } 36777957Sbenno System.arraycopy(RECOGNIZED_FEATURES, 0, combinedFeatureIds, length, RECOGNIZED_FEATURES.length); 36877957Sbenno return combinedFeatureIds; 36990643Sbenno } // getRecognizedFeatures():String[] 37077957Sbenno 37177957Sbenno /** 37290643Sbenno * Sets the state of a feature. This method is called by the component 37390643Sbenno * manager any time after reset when a feature changes state. 37490643Sbenno * <p> 37590643Sbenno * <strong>Note:</strong> Components should silently ignore features 37690643Sbenno * that do not affect the operation of the component. 37790643Sbenno * 37890643Sbenno * @param featureId The feature identifier. 37977957Sbenno * @param state The state of the feature. 38090643Sbenno * 38177957Sbenno * @throws SAXNotRecognizedException The component should not throw 38290643Sbenno * this exception. 38390643Sbenno * @throws SAXNotSupportedException The component should not throw 38490643Sbenno * this exception. 38590643Sbenno */ 38677957Sbenno public void setFeature(String featureId, boolean state) 38777957Sbenno throws XMLConfigurationException { 38877957Sbenno 38990643Sbenno super.setFeature(featureId, state); 39077957Sbenno 39190643Sbenno // Xerces properties 39290643Sbenno if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 39390643Sbenno final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 39490643Sbenno 39577957Sbenno if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && 39690643Sbenno featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { 39790643Sbenno fLoadExternalDTD = state; 39890643Sbenno return; 39990643Sbenno } 40090643Sbenno else if (suffixLength == Constants.DISALLOW_DOCTYPE_DECL_FEATURE.length() && 40190643Sbenno featureId.endsWith(Constants.DISALLOW_DOCTYPE_DECL_FEATURE)) { 40290643Sbenno fDisallowDoctype = state; 40390643Sbenno return; 40490643Sbenno } 40590643Sbenno } 40690643Sbenno 40790643Sbenno } // setFeature(String,boolean) 40877957Sbenno 40977957Sbenno /** 41090643Sbenno * Returns a list of property identifiers that are recognized by 41190643Sbenno * this component. This method may return null if no properties 41277957Sbenno * are recognized by this component. 41377957Sbenno */ 41490643Sbenno public String[] getRecognizedProperties() { 41577957Sbenno String[] propertyIds = super.getRecognizedProperties(); 41677957Sbenno int length = propertyIds != null ? propertyIds.length : 0; 41790643Sbenno String[] combinedPropertyIds = new String[length + RECOGNIZED_PROPERTIES.length]; 41890643Sbenno if (propertyIds != null) { 41977957Sbenno System.arraycopy(propertyIds, 0, combinedPropertyIds, 0, propertyIds.length); 42077957Sbenno } 42190643Sbenno System.arraycopy(RECOGNIZED_PROPERTIES, 0, combinedPropertyIds, length, RECOGNIZED_PROPERTIES.length); 42290643Sbenno return combinedPropertyIds; 42390643Sbenno } // getRecognizedProperties():String[] 42490643Sbenno 42590643Sbenno /** 42690643Sbenno * Sets the value of a property. This method is called by the component 42790643Sbenno * manager any time after reset when a property changes value. 42890643Sbenno * <p> 42977957Sbenno * <strong>Note:</strong> Components should silently ignore properties 43077957Sbenno * that do not affect the operation of the component. 43190643Sbenno * 43290643Sbenno * @param propertyId The property identifier. 43377957Sbenno * @param value The value of the property. 43477957Sbenno * 43590643Sbenno * @throws SAXNotRecognizedException The component should not throw 43690643Sbenno * this exception. 43777957Sbenno * @throws SAXNotSupportedException The component should not throw 43890643Sbenno * this exception. 43990643Sbenno */ 44090643Sbenno public void setProperty(String propertyId, Object value) 44177957Sbenno throws XMLConfigurationException { 44290643Sbenno 44390643Sbenno super.setProperty(propertyId, value); 44490643Sbenno 44590643Sbenno // Xerces properties 44690643Sbenno if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 44790643Sbenno final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 44877957Sbenno 44990643Sbenno if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && 45090643Sbenno propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { 45190643Sbenno fDTDScanner = (XMLDTDScanner)value; 45290643Sbenno } 45390643Sbenno if (suffixLength == Constants.NAMESPACE_CONTEXT_PROPERTY.length() && 45490643Sbenno propertyId.endsWith(Constants.NAMESPACE_CONTEXT_PROPERTY)) { 45577957Sbenno if (value != null) { 45690643Sbenno fNamespaceContext = (NamespaceContext)value; 45777957Sbenno } 45890643Sbenno } 45977957Sbenno 46090643Sbenno return; 46190643Sbenno } 46290643Sbenno 46390643Sbenno } // setProperty(String,Object) 46477957Sbenno 46590643Sbenno /** 46690643Sbenno * Returns the default state for a feature, or null if this 46790643Sbenno * component does not want to report a default value for this 46890643Sbenno * feature. 46990643Sbenno * 47077957Sbenno * @param featureId The feature identifier. 47190643Sbenno * 47290643Sbenno * @since Xerces 2.2.0 47390643Sbenno */ 47490643Sbenno public Boolean getFeatureDefault(String featureId) { 47590643Sbenno 47677957Sbenno for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { 47777957Sbenno if (RECOGNIZED_FEATURES[i].equals(featureId)) { 47890643Sbenno return FEATURE_DEFAULTS[i]; 47990643Sbenno } 48090643Sbenno } 48190643Sbenno return super.getFeatureDefault(featureId); 48290643Sbenno } // getFeatureDefault(String):Boolean 48390643Sbenno 48490643Sbenno /** 48590643Sbenno * Returns the default state for a property, or null if this 48690643Sbenno * component does not want to report a default value for this 48790643Sbenno * property. 48890643Sbenno * 48977957Sbenno * @param propertyId The property identifier. 49090643Sbenno * 49177957Sbenno * @since Xerces 2.2.0 49290643Sbenno */ 49390643Sbenno public Object getPropertyDefault(String propertyId) { 49490643Sbenno for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { 49590643Sbenno if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { 49690643Sbenno return PROPERTY_DEFAULTS[i]; 49777957Sbenno } 49890643Sbenno } 49990643Sbenno return super.getPropertyDefault(propertyId); 50077957Sbenno } // getPropertyDefault(String):Object 50190643Sbenno 50290643Sbenno // 50390643Sbenno // XMLEntityHandler methods 50490643Sbenno // 50590643Sbenno 50690643Sbenno /** 50790643Sbenno * This method notifies of the start of an entity. The DTD has the 50890643Sbenno * pseudo-name of "[dtd]" parameter entity names start with '%'; and 50990643Sbenno * general entities are just specified by their name. 51077957Sbenno * 51190643Sbenno * @param name The name of the entity. 51290643Sbenno * @param identifier The resource identifier. 51390643Sbenno * @param encoding The auto-detected IANA encoding name of the entity 51490643Sbenno * stream. This value will be null in those situations 51590643Sbenno * where the entity encoding is not auto-detected (e.g. 51690643Sbenno * internal entities or a document entity that is 51790643Sbenno * parsed from a java.io.Reader). 51890643Sbenno * 51990643Sbenno * @throws XNIException Thrown by handler to signal an error. 52090643Sbenno */ 52190643Sbenno public void startEntity(String name, 52290643Sbenno XMLResourceIdentifier identifier, 52390643Sbenno String encoding, Augmentations augs) throws XNIException { 52490643Sbenno 52577957Sbenno super.startEntity(name, identifier, encoding,augs); 52677957Sbenno 52777957Sbenno //register current document scanner as a listener for XMLEntityScanner 52890643Sbenno fEntityScanner.registerListener(this); 52977957Sbenno 53090643Sbenno // prepare to look for a TextDecl if external general entity 53190643Sbenno if (!name.equals("[xml]") && fEntityScanner.isExternal()) { 53290643Sbenno // Don't do this if we're skipping the entity! 53390643Sbenno if (augs == null || !((Boolean) augs.getItem(Constants.ENTITY_SKIPPED)).booleanValue()) { 53490643Sbenno setScannerState(SCANNER_STATE_TEXT_DECL); 53590643Sbenno } 53690643Sbenno } 53777957Sbenno 53877957Sbenno // call handler 53990643Sbenno /** comment this part.. LOCATOR problem.. */ 54090643Sbenno if (fDocumentHandler != null && name.equals("[xml]")) { 54177957Sbenno fDocumentHandler.startDocument(fEntityScanner, encoding, fNamespaceContext, null); 54290643Sbenno } 54390643Sbenno 54490643Sbenno } // startEntity(String,identifier,String) 54590643Sbenno 54690643Sbenno 54790643Sbenno /** 54890643Sbenno * This method notifies the end of an entity. The DTD has the pseudo-name 54990643Sbenno * of "[dtd]" parameter entity names start with '%'; and general entities 55090643Sbenno * are just specified by their name. 55190643Sbenno * 55277957Sbenno * @param name The name of the entity. 55377957Sbenno * 55490643Sbenno * @throws XNIException Thrown by handler to signal an error. 55577957Sbenno */ 55690643Sbenno public void endEntity(String name, Augmentations augs) throws IOException, XNIException { 55790643Sbenno 55890643Sbenno super.endEntity(name, augs); 55990643Sbenno 56090643Sbenno if(name.equals("[xml]")){ 56190643Sbenno //if fMarkupDepth has reached 0. 56290643Sbenno //and driver is fTrailingMiscDriver (which 56390643Sbenno //handles end of document in normal case) 56490643Sbenno //set the scanner state of SCANNER_STATE_TERMINATED 56590643Sbenno if(fMarkupDepth == 0 && fDriver == fTrailingMiscDriver){ 56690643Sbenno //set the scanner set to SCANNER_STATE_TERMINATED 56790643Sbenno setScannerState(SCANNER_STATE_TERMINATED) ; 56890643Sbenno } else{ 56990643Sbenno //else we have reached the end of document prematurely 57090643Sbenno //so throw EOFException. 57190643Sbenno throw new java.io.EOFException(); 57290643Sbenno } 57390643Sbenno 57490643Sbenno //this is taken care in wrapper which generates XNI callbacks, There are no next events 57590643Sbenno 57690643Sbenno //if (fDocumentHandler != null) { 57790643Sbenno //fDocumentHandler.endDocument(null); 57890643Sbenno //} 57990643Sbenno } 58090643Sbenno } // endEntity(String) 58177957Sbenno 58277957Sbenno 58377957Sbenno public XMLStringBuffer getDTDDecl(){ 58490643Sbenno Entity entity = fEntityScanner.getCurrentEntity(); 58577957Sbenno fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos); 58690643Sbenno if(fSeenInternalSubset) 58790643Sbenno fDTDDecl.append("]>"); 58890643Sbenno return fDTDDecl; 58990643Sbenno } 59077957Sbenno 59190643Sbenno public String getCharacterEncodingScheme(){ 59290643Sbenno return fDeclaredEncoding; 59377957Sbenno } 59490643Sbenno 59590643Sbenno /** return the next state on the input 59677957Sbenno * 59790643Sbenno * @return int 59890643Sbenno */ 59990643Sbenno 60090643Sbenno public int next() throws IOException, XNIException { 60190643Sbenno return fDriver.next(); 60290643Sbenno } 60390643Sbenno 60477957Sbenno //getNamespaceContext 60590643Sbenno public NamespaceContext getNamespaceContext(){ 60690643Sbenno return fNamespaceContext ; 60790643Sbenno } 60890643Sbenno 60990643Sbenno 61090643Sbenno 61190643Sbenno // 61290643Sbenno // Protected methods 61390643Sbenno // 61477957Sbenno 61590643Sbenno // driver factory methods 61690643Sbenno 61790643Sbenno /** Creates a content driver. */ 61890643Sbenno protected Driver createContentDriver() { 61977957Sbenno return new ContentDriver(); 62090643Sbenno } // createContentDriver():Driver 62190643Sbenno 62290643Sbenno // scanning methods 62390643Sbenno 62490643Sbenno /** Scans a doctype declaration. */ 62590643Sbenno protected boolean scanDoctypeDecl(boolean supportDTD) throws IOException, XNIException { 62677957Sbenno 62777957Sbenno // spaces 62890643Sbenno if (!fEntityScanner.skipSpaces()) { 62977957Sbenno reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL", 63090643Sbenno null); 63190643Sbenno } 63290643Sbenno 63377957Sbenno // root element name 63490643Sbenno fDoctypeName = fEntityScanner.scanName(NameType.DOCTYPE); 63590643Sbenno if (fDoctypeName == null) { 63690643Sbenno reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null); 63790643Sbenno } 63890643Sbenno 63990643Sbenno // external id 64090643Sbenno if (fEntityScanner.skipSpaces()) { 64190643Sbenno scanExternalID(fStrings, false); 64290643Sbenno fDoctypeSystemId = fStrings[0]; 64390643Sbenno fDoctypePublicId = fStrings[1]; 64490643Sbenno fEntityScanner.skipSpaces(); 64590643Sbenno } 64690643Sbenno 64790643Sbenno fHasExternalDTD = fDoctypeSystemId != null; 64890643Sbenno 64990643Sbenno // Attempt to locate an external subset with an external subset resolver. 65090643Sbenno if (supportDTD && !fHasExternalDTD && fExternalSubsetResolver != null) { 65190643Sbenno fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null); 65290643Sbenno fDTDDescription.setRootName(fDoctypeName); 65390643Sbenno fExternalSubsetSource = fExternalSubsetResolver.getExternalSubset(fDTDDescription); 65490643Sbenno fHasExternalDTD = fExternalSubsetSource != null; 65590643Sbenno } 65690643Sbenno 65777957Sbenno // call handler 65890643Sbenno if (supportDTD && fDocumentHandler != null) { 65977957Sbenno // NOTE: I don't like calling the doctypeDecl callback until 66090643Sbenno // end of the *full* doctype line (including internal 66190643Sbenno // subset) is parsed correctly but SAX2 requires that 66290643Sbenno // it knows the root element name and public and system 66377957Sbenno // identifier for the startDTD call. -Ac 66490643Sbenno if (fExternalSubsetSource == null) { 66590643Sbenno fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null); 66690643Sbenno } 66777957Sbenno else { 66877957Sbenno fDocumentHandler.doctypeDecl(fDoctypeName, fExternalSubsetSource.getPublicId(), fExternalSubsetSource.getSystemId(), null); 66990643Sbenno } 67090643Sbenno } 67190643Sbenno 67277957Sbenno // is there an internal subset? 67390643Sbenno boolean internalSubset = true; 67490643Sbenno if (!fEntityScanner.skipChar('[', null)) { 67590643Sbenno internalSubset = false; 67690643Sbenno fEntityScanner.skipSpaces(); 67790643Sbenno if (!fEntityScanner.skipChar('>', null)) { 67877957Sbenno reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName}); 67990643Sbenno } 68090643Sbenno fMarkupDepth--; 68190643Sbenno } 68277957Sbenno return internalSubset; 68377957Sbenno 68490643Sbenno } // scanDoctypeDecl():boolean 68590643Sbenno 68677957Sbenno // 68790643Sbenno // Private methods 68890643Sbenno // 68990643Sbenno /** Set the scanner state after scanning DTD */ 69090643Sbenno protected void setEndDTDScanState() { 69190643Sbenno setScannerState(SCANNER_STATE_PROLOG); 69290643Sbenno setDriver(fPrologDriver); 69390643Sbenno fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this); 69490643Sbenno fReadingDTD=false; 69590643Sbenno } 69690643Sbenno 69790643Sbenno /** Returns the scanner state name. */ 69877957Sbenno protected String getScannerStateName(int state) { 69977957Sbenno 70090643Sbenno switch (state) { 70190643Sbenno case SCANNER_STATE_XML_DECL: return "SCANNER_STATE_XML_DECL"; 70290643Sbenno case SCANNER_STATE_PROLOG: return "SCANNER_STATE_PROLOG"; 70390643Sbenno case SCANNER_STATE_TRAILING_MISC: return "SCANNER_STATE_TRAILING_MISC"; 70490643Sbenno case SCANNER_STATE_DTD_INTERNAL_DECLS: return "SCANNER_STATE_DTD_INTERNAL_DECLS"; 70590643Sbenno case SCANNER_STATE_DTD_EXTERNAL: return "SCANNER_STATE_DTD_EXTERNAL"; 70690643Sbenno case SCANNER_STATE_DTD_EXTERNAL_DECLS: return "SCANNER_STATE_DTD_EXTERNAL_DECLS"; 70790643Sbenno } 70877957Sbenno return super.getScannerStateName(state); 70977957Sbenno 71090643Sbenno } // getScannerStateName(int):String 71177957Sbenno 71290643Sbenno // 71390643Sbenno // Classes 71477957Sbenno // 71577957Sbenno 71690643Sbenno /** 71777957Sbenno * Driver to handle XMLDecl scanning. 71877957Sbenno * 71990643Sbenno * This class has been modified as per the new design which is more suited to 72090643Sbenno * efficiently build pull parser. Lots of performance improvements have been done and 72177957Sbenno * the code has been added to support stax functionality/features. 72277957Sbenno * 72390643Sbenno * @author Neeraj Bajaj, Sun Microsystems. 72477957Sbenno * 72590643Sbenno * @author Andy Clark, IBM 72677957Sbenno */ 72777957Sbenno protected final class XMLDeclDriver 72890643Sbenno implements Driver { 72977957Sbenno 73077957Sbenno // 73177957Sbenno // Driver methods 73290643Sbenno // 73390643Sbenno 73477957Sbenno 73577957Sbenno public int next() throws IOException, XNIException { 73690643Sbenno 73777957Sbenno // next driver is prolog regardless of whether there 73890643Sbenno // is an XMLDecl in this document 73990643Sbenno setScannerState(SCANNER_STATE_PROLOG); 74077957Sbenno setDriver(fPrologDriver); 74177957Sbenno 74290643Sbenno //System.out.println("fEntityScanner = " + fEntityScanner); 74390643Sbenno // scan XMLDecl 74477957Sbenno try { 74590643Sbenno if (fEntityScanner.skipString(XMLDECL)) { 74677957Sbenno if (XMLChar.isSpace(fEntityScanner.peekChar())) { 74790643Sbenno fMarkupDepth++; 74877957Sbenno scanXMLDeclOrTextDecl(false); 74990643Sbenno } else { 75077957Sbenno // PI, reset position 75177957Sbenno fEntityManager.fCurrentEntity.position = 0; 75290643Sbenno } 75377957Sbenno } 75490643Sbenno 75590643Sbenno //START_OF_THE_DOCUMENT 75690643Sbenno fEntityManager.fCurrentEntity.mayReadChunks = true; 75790643Sbenno return XMLEvent.START_DOCUMENT; 75877957Sbenno 75990643Sbenno } 76090643Sbenno 76190643Sbenno // premature end of file 76277957Sbenno catch (EOFException e) { 76377957Sbenno reportFatalError("PrematureEOF", null); 76490643Sbenno return -1; 76590643Sbenno //throw e; 76677957Sbenno } 76790643Sbenno 76890643Sbenno } 76977957Sbenno } // class XMLDeclDriver 77077957Sbenno 77177957Sbenno /** 77290643Sbenno * Driver to handle prolog scanning. 77377957Sbenno * 77490643Sbenno * @author Andy Clark, IBM 77577957Sbenno */ 77677957Sbenno protected final class PrologDriver 77777957Sbenno implements Driver { 77890643Sbenno 77977957Sbenno /** 78077957Sbenno * Drives the parser to the next state/event on the input. Parser is guaranteed 78190643Sbenno * to stop at the next state/event. 78290643Sbenno * 78390643Sbenno * Internally XML document is divided into several states. Each state represents 78477957Sbenno * a sections of XML document. When this functions returns normally, it has read 78577957Sbenno * the section of XML document and returns the state corresponding to section of 78677957Sbenno * document which has been read. For optimizations, a particular driver 78790643Sbenno * can read ahead of the section of document (state returned) just read and 78877957Sbenno * can maintain a different internal state. 78990643Sbenno * 79077957Sbenno * @return state representing the section of document just read. 79177957Sbenno * 79277957Sbenno * @throws IOException Thrown on i/o error. 79390643Sbenno * @throws XNIException Thrown on parse error. 79490643Sbenno */ 79577957Sbenno 79690643Sbenno public int next() throws IOException, XNIException { 79777957Sbenno 79877957Sbenno try { 79977957Sbenno do { 80090643Sbenno switch (fScannerState) { 80177957Sbenno case SCANNER_STATE_PROLOG: { 80290643Sbenno fEntityScanner.skipSpaces(); 80377957Sbenno if (fEntityScanner.skipChar('<', null)) { 80477957Sbenno setScannerState(SCANNER_STATE_START_OF_MARKUP); 80577957Sbenno } else if (fEntityScanner.skipChar('&', NameType.REFERENCE)) { 80690643Sbenno setScannerState(SCANNER_STATE_REFERENCE); 80777957Sbenno } else { 80877957Sbenno setScannerState(SCANNER_STATE_CONTENT); 80977957Sbenno } 81077957Sbenno break; 81190643Sbenno } 81277957Sbenno 81377957Sbenno case SCANNER_STATE_START_OF_MARKUP: { 81490643Sbenno fMarkupDepth++; 81590643Sbenno if (isValidNameStartChar(fEntityScanner.peekChar()) || 81690643Sbenno isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { 81790643Sbenno setScannerState(SCANNER_STATE_ROOT_ELEMENT); 81890643Sbenno setDriver(fContentDriver); 81990643Sbenno //from now onwards this would be handled by fContentDriver,in the same next() call 82090643Sbenno return fContentDriver.next(); 82190643Sbenno } else if (fEntityScanner.skipChar('!', null)) { 82290643Sbenno if (fEntityScanner.skipChar('-', null)) { 82377957Sbenno if (!fEntityScanner.skipChar('-', null)) { 82490643Sbenno reportFatalError("InvalidCommentStart", 82590643Sbenno null); 82690643Sbenno } 82790643Sbenno setScannerState(SCANNER_STATE_COMMENT); 82890643Sbenno } else if (fEntityScanner.skipString(DOCTYPE)) { 82990643Sbenno setScannerState(SCANNER_STATE_DOCTYPE); 83090643Sbenno Entity entity = fEntityScanner.getCurrentEntity(); 83190643Sbenno if(entity instanceof Entity.ScannedEntity){ 83290643Sbenno fStartPos=((Entity.ScannedEntity)entity).position; 83390643Sbenno } 83477957Sbenno fReadingDTD=true; 83577957Sbenno if(fDTDDecl == null) 83677957Sbenno fDTDDecl = new XMLStringBuffer(); 83777957Sbenno fDTDDecl.append("<!DOCTYPE"); 83877957Sbenno 83990643Sbenno } else { 84077957Sbenno reportFatalError("MarkupNotRecognizedInProlog", 84177957Sbenno null); 84277957Sbenno } 84390643Sbenno } else if (fEntityScanner.skipChar('?', null)) { 84490643Sbenno setScannerState(SCANNER_STATE_PI); 84590643Sbenno } else { 84677957Sbenno reportFatalError("MarkupNotRecognizedInProlog", 84777957Sbenno null); 84890643Sbenno } 84990643Sbenno break; 85077957Sbenno } 85190643Sbenno } 85290643Sbenno } while (fScannerState == SCANNER_STATE_PROLOG || fScannerState == SCANNER_STATE_START_OF_MARKUP ); 85390643Sbenno 85490643Sbenno switch(fScannerState){ 85577957Sbenno /** 85690643Sbenno //this part is handled by FragmentContentHandler 85790643Sbenno case SCANNER_STATE_ROOT_ELEMENT: { 85890643Sbenno //we have read '<' and beginning of reading the start element tag 85990643Sbenno setScannerState(SCANNER_STATE_START_ELEMENT_TAG); 86090643Sbenno setDriver(fContentDriver); 86190643Sbenno //from now onwards this would be handled by fContentDriver,in the same next() call 86290643Sbenno return fContentDriver.next(); 86390643Sbenno } 86490643Sbenno */ 86577957Sbenno case SCANNER_STATE_COMMENT: { 86690643Sbenno //this function fills the data.. 86777957Sbenno scanComment(); 86890643Sbenno setScannerState(SCANNER_STATE_PROLOG); 86990643Sbenno return XMLEvent.COMMENT; 87090643Sbenno //setScannerState(SCANNER_STATE_PROLOG); 87190643Sbenno //break; 87277957Sbenno } 87390643Sbenno case SCANNER_STATE_PI: { 87490643Sbenno fContentBuffer.clear() ; 87577957Sbenno scanPI(fContentBuffer); 87690643Sbenno setScannerState(SCANNER_STATE_PROLOG); 87790643Sbenno return XMLEvent.PROCESSING_INSTRUCTION; 87877957Sbenno } 87990643Sbenno 88090643Sbenno case SCANNER_STATE_DOCTYPE: { 88190643Sbenno if (fDisallowDoctype) { 88290643Sbenno reportFatalError("DoctypeNotAllowed", null); 88377957Sbenno } 88490643Sbenno 88577957Sbenno if (fSeenDoctypeDecl) { 88690643Sbenno reportFatalError("AlreadySeenDoctype", null); 88790643Sbenno } 88877957Sbenno fSeenDoctypeDecl = true; 88977957Sbenno 89077957Sbenno // scanDoctypeDecl() sends XNI doctypeDecl event that 89177957Sbenno // in SAX is converted to startDTD() event. 89290643Sbenno if (scanDoctypeDecl(fSupportDTD)) { 89390643Sbenno //allow parsing of entity decls to continue in order to stay well-formed 89477957Sbenno setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS); 89590643Sbenno fSeenInternalSubset = true; 89690643Sbenno if(fDTDDriver == null){ 89777957Sbenno fDTDDriver = new DTDDriver(); 89877957Sbenno } 89977957Sbenno setDriver(fContentDriver); 90090643Sbenno //always return DTD event, the event however, will not contain any entities 90177957Sbenno return fDTDDriver.next(); 90290643Sbenno } 90390643Sbenno 90477957Sbenno if(fSeenDoctypeDecl){ 90590643Sbenno Entity entity = fEntityScanner.getCurrentEntity(); 90677957Sbenno if(entity instanceof Entity.ScannedEntity){ 90790643Sbenno fEndPos = ((Entity.ScannedEntity)entity).position; 90890643Sbenno } 90990643Sbenno fReadingDTD = false; 91077957Sbenno } 91190643Sbenno 91277957Sbenno // handle external subset 91377957Sbenno if (fDoctypeSystemId != null) { 91490643Sbenno if (((fValidation || fLoadExternalDTD) 91590643Sbenno && (fValidationManager == null || !fValidationManager.isCachedDTD()))) { 91677957Sbenno if (fSupportDTD) { 91777957Sbenno setScannerState(SCANNER_STATE_DTD_EXTERNAL); 91890643Sbenno } else { 91990643Sbenno setScannerState(SCANNER_STATE_PROLOG); 92090643Sbenno } 92190643Sbenno 92290643Sbenno setDriver(fContentDriver); 92390643Sbenno if(fDTDDriver == null) { 92477957Sbenno fDTDDriver = new DTDDriver(); 92577957Sbenno } 92690643Sbenno 92790643Sbenno return fDTDDriver.next(); 92890643Sbenno } 92990643Sbenno } 93090643Sbenno else if (fExternalSubsetSource != null) { 93190643Sbenno if (((fValidation || fLoadExternalDTD) 93290643Sbenno && (fValidationManager == null || !fValidationManager.isCachedDTD()))) { 93390643Sbenno // This handles the case of a DOCTYPE that had neither an internal subset or an external subset. 93490643Sbenno fDTDScanner.setInputSource(fExternalSubsetSource); 93590643Sbenno fExternalSubsetSource = null; 93690643Sbenno if (fSupportDTD) 93790643Sbenno setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS); 93890643Sbenno else 93991403Ssilby setScannerState(SCANNER_STATE_PROLOG); 94091403Ssilby setDriver(fContentDriver); 94191403Ssilby if(fDTDDriver == null) 94291403Ssilby fDTDDriver = new DTDDriver(); 94391403Ssilby return fDTDDriver.next(); 94491403Ssilby } 94591403Ssilby } 94691403Ssilby 94791403Ssilby // Send endDTD() call if: 94891403Ssilby // a) systemId is null or if an external subset resolver could not locate an external subset. 94991403Ssilby // b) "load-external-dtd" and validation are false 95091403Ssilby // c) DTD grammar is cached 95191403Ssilby 95290643Sbenno // in XNI this results in 3 events: doctypeDecl, startDTD, endDTD 95390643Sbenno // in SAX this results in 2 events: startDTD, endDTD 95490643Sbenno if (fDTDScanner != null) { 95590643Sbenno fDTDScanner.setInputSource(null); 95690643Sbenno } 95790643Sbenno setScannerState(SCANNER_STATE_PROLOG); 95890643Sbenno return XMLEvent.DTD; 95977957Sbenno } 96090643Sbenno 96177957Sbenno case SCANNER_STATE_CONTENT: { 96277957Sbenno reportFatalError("ContentIllegalInProlog", null); 96390643Sbenno fEntityScanner.scanChar(null); 96477957Sbenno return -1; 96590643Sbenno } 96690643Sbenno case SCANNER_STATE_REFERENCE: { 96790643Sbenno reportFatalError("ReferenceIllegalInProlog", null); 96877957Sbenno return -1; 96990643Sbenno } 97090643Sbenno 97190643Sbenno /** 97290643Sbenno * if (complete) { 97390643Sbenno * if (fEntityScanner.scanChar() != '<') { 97477957Sbenno * reportFatalError("RootElementRequired", null); 97590643Sbenno * } 97690643Sbenno * setScannerState(SCANNER_STATE_ROOT_ELEMENT); 97790643Sbenno * setDriver(fContentDriver); 97890643Sbenno * } 97977957Sbenno */ 98077957Sbenno } 98177957Sbenno } 98277957Sbenno // premature end of file 98390643Sbenno catch (EOFException e) { 98490643Sbenno reportFatalError("PrematureEOF", null); 98590643Sbenno //xxx what should be returned here.... ??? 98690643Sbenno return -1 ; 98790643Sbenno //throw e; 98890643Sbenno } 98990643Sbenno //xxx what should be returned here.... ??? 99077957Sbenno return -1; 99190643Sbenno 99277957Sbenno } 99390643Sbenno 99490643Sbenno 99577957Sbenno } // class PrologDriver 99677957Sbenno 99777957Sbenno /** 99890643Sbenno * Driver to handle the internal and external DTD subsets. 99990643Sbenno * 100077957Sbenno * @author Andy Clark, IBM 100190643Sbenno */ 100290643Sbenno protected final class DTDDriver 100377957Sbenno implements Driver { 100477957Sbenno 100591456Sbenno // 100691456Sbenno // Driver methods 100791456Sbenno // 100877957Sbenno 100977957Sbenno public int next() throws IOException, XNIException{ 101077957Sbenno 101191456Sbenno dispatch(true); 101291456Sbenno 101377957Sbenno //xxx: remove this hack and align this with reusing DTD components 101477957Sbenno //currently this routine will only be executed from Stax 101577957Sbenno if(fPropertyManager != null){ 101690643Sbenno dtdGrammarUtil = new DTDGrammarUtil(((XMLDTDScannerImpl)fDTDScanner).getGrammar(),fSymbolTable, fNamespaceContext); 101790643Sbenno } 101890643Sbenno 101990643Sbenno return XMLEvent.DTD ; 102090643Sbenno } 102190643Sbenno 102290643Sbenno /** 102377957Sbenno * Dispatch an XML "event". 102490643Sbenno * 102590643Sbenno * @param complete True if this driver is intended to scan 102677957Sbenno * and dispatch as much as possible. 102790643Sbenno * 102877957Sbenno * @return True if there is more to dispatch either from this 102990643Sbenno * or a another driver. 103090643Sbenno * 103190643Sbenno * @throws IOException Thrown on i/o error. 103290643Sbenno * @throws XNIException Thrown on parse error. 103390643Sbenno */ 103490643Sbenno public boolean dispatch(boolean complete) 103577957Sbenno throws IOException, XNIException { 103677957Sbenno fEntityManager.setEntityHandler(null); 103790643Sbenno try { 103890643Sbenno boolean again; 103977957Sbenno XMLResourceIdentifierImpl resourceIdentifier = new XMLResourceIdentifierImpl(); 104090643Sbenno if( fDTDScanner == null){ 104190643Sbenno 104277957Sbenno if (fEntityManager.getEntityScanner() instanceof XML11EntityScanner){ 104377957Sbenno fDTDScanner = new XML11DTDScannerImpl(); 104490643Sbenno } else 104590643Sbenno 104690643Sbenno fDTDScanner = new XMLDTDScannerImpl(); 104777957Sbenno 104877957Sbenno ((XMLDTDScannerImpl)fDTDScanner).reset(fPropertyManager); 104990643Sbenno } 105077957Sbenno 105190643Sbenno fDTDScanner.setLimitAnalyzer(fLimitAnalyzer); 105290643Sbenno do { 105390643Sbenno again = false; 105490643Sbenno switch (fScannerState) { 105577957Sbenno case SCANNER_STATE_DTD_INTERNAL_DECLS: { 105677957Sbenno boolean moreToScan = false; 105790643Sbenno if (!fDTDScanner.skipDTD(fSupportDTD)) { 105877957Sbenno // REVISIT: Should there be a feature for 105990643Sbenno // the "complete" parameter? 106090643Sbenno boolean completeDTD = true; 106190643Sbenno 106290643Sbenno moreToScan = fDTDScanner.scanDTDInternalSubset(completeDTD, fStandalone, fHasExternalDTD && fLoadExternalDTD); 106377957Sbenno } 106477957Sbenno Entity entity = fEntityScanner.getCurrentEntity(); 106590643Sbenno if(entity instanceof Entity.ScannedEntity){ 106690643Sbenno fEndPos=((Entity.ScannedEntity)entity).position; 106790643Sbenno } 106890643Sbenno fReadingDTD=false; 106990643Sbenno if (!moreToScan) { 107090643Sbenno // end doctype declaration 107190643Sbenno if (!fEntityScanner.skipChar(']', null)) { 107290643Sbenno reportFatalError("DoctypedeclNotClosed", new Object[]{fDoctypeName}); 107390643Sbenno } 107477957Sbenno fEntityScanner.skipSpaces(); 107577957Sbenno if (!fEntityScanner.skipChar('>', null)) { 107690643Sbenno reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName}); 107790643Sbenno } 107890643Sbenno fMarkupDepth--; 107990643Sbenno 108090643Sbenno if (!fSupportDTD) { 108177957Sbenno //simply reset the entity store without having to mess around 108290643Sbenno //with the DTD Scanner code 108390643Sbenno fEntityStore = fEntityManager.getEntityStore(); 108490643Sbenno fEntityStore.reset(); 108590643Sbenno } else { 108677957Sbenno // scan external subset next unless we are ignoring DTDs 108790643Sbenno if (fDoctypeSystemId != null && (fValidation || fLoadExternalDTD)) { 108890643Sbenno setScannerState(SCANNER_STATE_DTD_EXTERNAL); 108990643Sbenno break; 109090643Sbenno } 109177957Sbenno } 109290643Sbenno 109390643Sbenno setEndDTDScanState(); 109490643Sbenno return true; 109590643Sbenno 109677957Sbenno } 109790643Sbenno break; 109877957Sbenno } 109990643Sbenno case SCANNER_STATE_DTD_EXTERNAL: { 110090643Sbenno /** 110190643Sbenno fDTDDescription.setValues(fDoctypePublicId, fDoctypeSystemId, null, null); 110290643Sbenno fDTDDescription.setRootName(fDoctypeName); 110390643Sbenno XMLInputSource xmlInputSource = 110477957Sbenno fEntityManager.resolveEntity(fDTDDescription); 110577957Sbenno fDTDScanner.setInputSource(xmlInputSource); 110677957Sbenno setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS); 110790643Sbenno again = true; 110877957Sbenno break; 110977957Sbenno */ 111077957Sbenno 111177957Sbenno resourceIdentifier.setValues(fDoctypePublicId, fDoctypeSystemId, null, null); 111290643Sbenno XMLInputSource xmlInputSource = null ; 111390643Sbenno StaxXMLInputSource staxInputSource = fEntityManager.resolveEntityAsPerStax(resourceIdentifier); 111490643Sbenno 111577957Sbenno // Check access permission. If the source is resolved by a resolver, the check is skipped. 111690643Sbenno if (!staxInputSource.isCreatedByResolver()) { 111790643Sbenno String accessError = checkAccess(fDoctypeSystemId, fAccessExternalDTD); 111890643Sbenno if (accessError != null) { 111990643Sbenno reportFatalError("AccessExternalDTD", new Object[]{ SecuritySupport.sanitizePath(fDoctypeSystemId), accessError }); 112090643Sbenno } 112190643Sbenno } 112290643Sbenno xmlInputSource = staxInputSource.getXMLInputSource(); 112377957Sbenno fDTDScanner.setInputSource(xmlInputSource); 112477957Sbenno if (fEntityScanner.fCurrentEntity != null) { 112590643Sbenno setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS); 112690643Sbenno } else { 112790643Sbenno setScannerState(SCANNER_STATE_PROLOG); 112890643Sbenno } 112990643Sbenno again = true; 113090643Sbenno break; 113190643Sbenno } 113290643Sbenno case SCANNER_STATE_DTD_EXTERNAL_DECLS: { 113390643Sbenno // REVISIT: Should there be a feature for 113490643Sbenno // the "complete" parameter? 113590643Sbenno boolean completeDTD = true; 113677957Sbenno boolean moreToScan = fDTDScanner.scanDTDExternalSubset(completeDTD); 113790643Sbenno if (!moreToScan) { 113890643Sbenno setEndDTDScanState(); 113990643Sbenno return true; 114090643Sbenno } 114190643Sbenno break; 114290643Sbenno } 114390643Sbenno case SCANNER_STATE_PROLOG : { 114490643Sbenno // skip entity decls 114590643Sbenno setEndDTDScanState(); 114690643Sbenno return true; 114790643Sbenno } 114890643Sbenno default: { 114990643Sbenno throw new XNIException("DTDDriver#dispatch: scanner state="+fScannerState+" ("+getScannerStateName(fScannerState)+')'); 115090643Sbenno } 115190643Sbenno } 115277957Sbenno } while (complete || again); 115390643Sbenno } 115490643Sbenno 115590643Sbenno // premature end of file 115690643Sbenno catch (EOFException e) { 115790643Sbenno e.printStackTrace(); 115890643Sbenno reportFatalError("PrematureEOF", null); 115990643Sbenno return false; 116090643Sbenno //throw e; 116190643Sbenno } 116290643Sbenno 116390643Sbenno // cleanup 116477957Sbenno finally { 116577957Sbenno fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this); 116677957Sbenno } 116777957Sbenno 116890643Sbenno return true; 116977957Sbenno 117077957Sbenno } 117190643Sbenno 117290643Sbenno // dispatch(boolean):boolean 117377957Sbenno 117490643Sbenno } // class DTDDriver 117577957Sbenno 117691403Ssilby /** 117791403Ssilby * Driver to handle content scanning. 117891403Ssilby * 117991403Ssilby * @author Andy Clark, IBM 118091403Ssilby * @author Eric Ye, IBM 118191403Ssilby */ 118291403Ssilby protected class ContentDriver 118390643Sbenno extends FragmentContentDriver { 118491403Ssilby 118590643Sbenno // 118690643Sbenno // Protected methods 118790643Sbenno // 118890643Sbenno 118977957Sbenno // hooks 119090643Sbenno 119177957Sbenno // NOTE: These hook methods are added so that the full document 119290643Sbenno // scanner can share the majority of code with this class. 119390643Sbenno 119490643Sbenno /** 119590643Sbenno * Scan for DOCTYPE hook. This method is a hook for subclasses 119690643Sbenno * to add code to handle scanning for a the "DOCTYPE" string 119777957Sbenno * after the string "<!" has been scanned. 119890643Sbenno * 119990643Sbenno * @return True if the "DOCTYPE" was scanned; false if "DOCTYPE" 120077957Sbenno * was not scanned. 120190643Sbenno */ 120290643Sbenno protected boolean scanForDoctypeHook() 120390643Sbenno throws IOException, XNIException { 120490643Sbenno 120590643Sbenno if (fEntityScanner.skipString(DOCTYPE)) { 120690643Sbenno setScannerState(SCANNER_STATE_DOCTYPE); 120777957Sbenno // fEntityScanner.markStartOfDTD(); 120877957Sbenno return true; 120990643Sbenno } 121090643Sbenno return false; 121190643Sbenno 121290643Sbenno } // scanForDoctypeHook():boolean 121390643Sbenno 121477957Sbenno /** 121590643Sbenno * Element depth iz zero. This methos is a hook for subclasses 121690643Sbenno * to add code to handle when the element depth hits zero. When 121790643Sbenno * scanning a document fragment, an element depth of zero is 121890643Sbenno * normal. However, when scanning a full XML document, the 121990643Sbenno * scanner must handle the trailing miscellanous section of 122090643Sbenno * the document after the end of the document's root element. 122190643Sbenno * 122290643Sbenno * @return True if the caller should stop and return true which 122390643Sbenno * allows the scanner to switch to a new scanning 122490643Sbenno * driver. A return value of false indicates that 122590643Sbenno * the content driver should continue as normal. 122690643Sbenno */ 122790643Sbenno protected boolean elementDepthIsZeroHook() 122890643Sbenno throws IOException, XNIException { 122990643Sbenno 123090643Sbenno setScannerState(SCANNER_STATE_TRAILING_MISC); 123190643Sbenno setDriver(fTrailingMiscDriver); 123277957Sbenno return true; 123390643Sbenno 123490643Sbenno } // elementDepthIsZeroHook():boolean 123590643Sbenno 123690643Sbenno /** 123790643Sbenno * Scan for root element hook. This method is a hook for 123877957Sbenno * subclasses to add code that handles scanning for the root 123990643Sbenno * element. When scanning a document fragment, there is no 124077957Sbenno * "root" element. However, when scanning a full XML document, 124177957Sbenno * the scanner must handle the root element specially. 124277957Sbenno * 124390643Sbenno * @return True if the caller should stop and return true which 124477957Sbenno * allows the scanner to switch to a new scanning 124577957Sbenno * driver. A return value of false indicates that 124690643Sbenno * the content driver should continue as normal. 124777957Sbenno */ 124877957Sbenno protected boolean scanRootElementHook() 124990643Sbenno throws IOException, XNIException { 125090643Sbenno 125177957Sbenno if (scanStartElement()) { 125277957Sbenno setScannerState(SCANNER_STATE_TRAILING_MISC); 125377957Sbenno setDriver(fTrailingMiscDriver); 125490643Sbenno return true; 125577957Sbenno } 125690643Sbenno return false; 125790643Sbenno 125877957Sbenno } // scanRootElementHook():boolean 125990643Sbenno 126090643Sbenno /** 126190643Sbenno * End of file hook. This method is a hook for subclasses to 126290643Sbenno * add code that handles the end of file. The end of file in 126390643Sbenno * a document fragment is OK if the markup depth is zero. 126477957Sbenno * However, when scanning a full XML document, an end of file 126590643Sbenno * is always premature. 126690643Sbenno */ 126790643Sbenno protected void endOfFileHook(EOFException e) 126890643Sbenno throws IOException, XNIException { 126977957Sbenno 127077957Sbenno reportFatalError("PrematureEOF", null); 127190643Sbenno // in case continue-after-fatal-error set, should not do this... 127290643Sbenno //throw e; 127377957Sbenno 127490643Sbenno } // endOfFileHook() 127577957Sbenno 127677957Sbenno protected void resolveExternalSubsetAndRead() 127777957Sbenno throws IOException, XNIException { 127891456Sbenno 127991456Sbenno fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null); 128091456Sbenno fDTDDescription.setRootName(fElementQName.rawname); 128191456Sbenno XMLInputSource src = fExternalSubsetResolver.getExternalSubset(fDTDDescription); 128291456Sbenno 128390643Sbenno if (src != null) { 128490643Sbenno fDoctypeName = fElementQName.rawname; 128577957Sbenno fDoctypePublicId = src.getPublicId(); 128690643Sbenno fDoctypeSystemId = src.getSystemId(); 128777957Sbenno // call document handler 128890643Sbenno if (fDocumentHandler != null) { 128990643Sbenno // This inserts a doctypeDecl event into the stream though no 129090643Sbenno // DOCTYPE existed in the instance document. 129177957Sbenno fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null); 129291456Sbenno } 129391456Sbenno try { 129491456Sbenno fDTDScanner.setInputSource(src); 129591456Sbenno while (fDTDScanner.scanDTDExternalSubset(true)); 129690643Sbenno } finally { 129790643Sbenno fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this); 129890643Sbenno } 129991456Sbenno } 130091456Sbenno } // resolveExternalSubsetAndRead() 130191456Sbenno 130291456Sbenno 130377957Sbenno 130477957Sbenno } // class ContentDriver 130577957Sbenno 130690643Sbenno /** 130777957Sbenno * Driver to handle trailing miscellaneous section scanning. 130890643Sbenno * 130990643Sbenno * @author Andy Clark, IBM 131077957Sbenno * @author Eric Ye, IBM 131177957Sbenno */ 131290643Sbenno protected final class TrailingMiscDriver 131390643Sbenno implements Driver { 131490643Sbenno 131577957Sbenno // 131690643Sbenno // Driver methods 131790643Sbenno // 131890643Sbenno public int next() throws IOException, XNIException{ 131990643Sbenno //this could for cases like <foo/> 132077957Sbenno //look at scanRootElementHook 132177957Sbenno if(fEmptyElement){ 132291456Sbenno fEmptyElement = false; 132391456Sbenno return XMLEvent.END_ELEMENT; 132491456Sbenno } 132590643Sbenno 132691456Sbenno try { 132777957Sbenno if(fScannerState == SCANNER_STATE_TERMINATED){ 132891456Sbenno return XMLEvent.END_DOCUMENT ;} 132991456Sbenno do { 133091456Sbenno switch (fScannerState) { 133191456Sbenno case SCANNER_STATE_TRAILING_MISC: { 133291456Sbenno 133391456Sbenno fEntityScanner.skipSpaces(); 133491456Sbenno //we should have reached the end of the document in 133591456Sbenno //most cases. 133691456Sbenno if(fScannerState == SCANNER_STATE_TERMINATED ){ 133777957Sbenno return XMLEvent.END_DOCUMENT ; 133877957Sbenno } 133990643Sbenno if (fEntityScanner.skipChar('<', null)) { 134090643Sbenno setScannerState(SCANNER_STATE_START_OF_MARKUP); 134177957Sbenno } else { 134290643Sbenno setScannerState(SCANNER_STATE_CONTENT); 134377957Sbenno } 134477957Sbenno break; 134577957Sbenno } 134690643Sbenno case SCANNER_STATE_START_OF_MARKUP: { 134777957Sbenno fMarkupDepth++; 134890643Sbenno if (fEntityScanner.skipChar('?', null)) { 134977957Sbenno setScannerState(SCANNER_STATE_PI); 135077957Sbenno } else if (fEntityScanner.skipChar('!', null)) { 135177957Sbenno setScannerState(SCANNER_STATE_COMMENT); 135290643Sbenno } else if (fEntityScanner.skipChar('/', null)) { 135377957Sbenno reportFatalError("MarkupNotRecognizedInMisc", 135490643Sbenno null); 135577957Sbenno } else if (isValidNameStartChar(fEntityScanner.peekChar()) || 135677957Sbenno isValidNameStartHighSurrogate(fEntityScanner.peekChar())) { 135777957Sbenno reportFatalError("MarkupNotRecognizedInMisc", 135890643Sbenno null); 135990643Sbenno scanStartElement(); 136090643Sbenno setScannerState(SCANNER_STATE_CONTENT); 136177957Sbenno } else { 136277957Sbenno reportFatalError("MarkupNotRecognizedInMisc", 136390643Sbenno null); 136477957Sbenno } 136590643Sbenno break; 136690643Sbenno } 136790643Sbenno } 136890643Sbenno } while(fScannerState == SCANNER_STATE_START_OF_MARKUP || 136980431Speter fScannerState == SCANNER_STATE_TRAILING_MISC); 137090643Sbenno 137190643Sbenno switch (fScannerState){ 137290643Sbenno case SCANNER_STATE_PI: { 137390643Sbenno fContentBuffer.clear(); 137490643Sbenno scanPI(fContentBuffer); 137590643Sbenno setScannerState(SCANNER_STATE_TRAILING_MISC); 137690643Sbenno return XMLEvent.PROCESSING_INSTRUCTION ; 137790643Sbenno } 137890643Sbenno case SCANNER_STATE_COMMENT: { 137990643Sbenno if (!fEntityScanner.skipString(COMMENTSTRING)) { 138090643Sbenno reportFatalError("InvalidCommentStart", null); 138190643Sbenno } 138290643Sbenno scanComment(); 138390643Sbenno setScannerState(SCANNER_STATE_TRAILING_MISC); 138490643Sbenno return XMLEvent.COMMENT; 138590643Sbenno } 138690643Sbenno case SCANNER_STATE_CONTENT: { 138790643Sbenno int ch = fEntityScanner.peekChar(); 138890643Sbenno if (ch == -1) { 138990643Sbenno setScannerState(SCANNER_STATE_TERMINATED); 139090643Sbenno return XMLEvent.END_DOCUMENT ; 139190643Sbenno } else{ 139290643Sbenno reportFatalError("ContentIllegalInTrailingMisc", 139390643Sbenno null); 139490643Sbenno fEntityScanner.scanChar(null); 139590643Sbenno setScannerState(SCANNER_STATE_TRAILING_MISC); 139690643Sbenno return XMLEvent.CHARACTERS; 139790643Sbenno } 139890643Sbenno 139990643Sbenno } 140090643Sbenno case SCANNER_STATE_REFERENCE: { 140190643Sbenno reportFatalError("ReferenceIllegalInTrailingMisc", 140290643Sbenno null); 140390643Sbenno setScannerState(SCANNER_STATE_TRAILING_MISC); 140490643Sbenno return XMLEvent.ENTITY_REFERENCE ; 140590643Sbenno } 140690643Sbenno case SCANNER_STATE_TERMINATED: { 140790643Sbenno //there can't be any element after SCANNER_STATE_TERMINATED or when the parser 140890643Sbenno //has reached the end of document 140990643Sbenno setScannerState(SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION); 141090643Sbenno //xxx what to do when the scanner has reached the terminating state. 141190643Sbenno return XMLEvent.END_DOCUMENT ; 141290643Sbenno } 141390643Sbenno case SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION:{ 141477957Sbenno throw new java.util.NoSuchElementException("No more events to be parsed"); 141577957Sbenno } 141677957Sbenno default: throw new XNIException("Scanner State " + fScannerState + " not Recognized "); 141790643Sbenno }//switch 141877957Sbenno 141990643Sbenno } catch (EOFException e) { 142077957Sbenno // NOTE: This is the only place we're allowed to reach 142177957Sbenno // the real end of the document stream. Unless the 142277957Sbenno // end of file was reached prematurely. 142390643Sbenno if (fMarkupDepth != 0) { 142477957Sbenno reportFatalError("PrematureEOF", null); 142590643Sbenno return -1; 142677957Sbenno //throw e; 142777957Sbenno } 142877957Sbenno //System.out.println("EOFException thrown") ; 142990643Sbenno setScannerState(SCANNER_STATE_TERMINATED); 143083682Smp } 143190643Sbenno 143283682Smp return XMLEvent.END_DOCUMENT; 143383682Smp 143483682Smp }//next 143590643Sbenno 143683682Smp } // class TrailingMiscDriver 143790643Sbenno 143883682Smp /** 143983682Smp * Implements XMLBufferListener interface. 144083682Smp */ 144190643Sbenno 144290643Sbenno 144390643Sbenno /** 144483682Smp * receives callbacks from {@link XMLEntityReader } when buffer 144590643Sbenno * is being changed. 144690643Sbenno * @param refreshPosition 144783682Smp */ 144890643Sbenno public void refresh(int refreshPosition){ 144990643Sbenno super.refresh(refreshPosition); 145083682Smp if(fReadingDTD){ 145190643Sbenno Entity entity = fEntityScanner.getCurrentEntity(); 145290643Sbenno if(entity instanceof Entity.ScannedEntity){ 145390643Sbenno fEndPos=((Entity.ScannedEntity)entity).position; 145490643Sbenno } 145590643Sbenno fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos); 145690643Sbenno fStartPos = refreshPosition; 145790643Sbenno } 145890643Sbenno } 145990643Sbenno 146090643Sbenno} // class XMLDocumentScannerImpl 146190643Sbenno