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