FileDocCategorySizeDatePackage
XMLDocumentScannerImpl.javaAPI DocJava SE 6 API62445Tue Jun 10 00:22:38 BST 2008com.sun.org.apache.xerces.internal.impl

XMLDocumentScannerImpl

public class XMLDocumentScannerImpl extends XMLDocumentFragmentScannerImpl
This class is responsible for scanning XML document structure and content. This class has been modified as per the new design which is more suited to efficiently build pull parser. Lot of improvements have been done and the code has been added to support stax functionality/features.
author
Neeraj Bajaj, Sun Microsystems
author
K.Venugopal, Sun Microsystems
author
Glenn Marcy, IBM
author
Andy Clark, IBM
author
Arnaud Le Hors, IBM
author
Eric Ye, IBM
author
Sunitha Reddy, Sun Microsystems Refer to the table in unit-test javax.xml.stream.XMLStreamReaderTest.SupportDTD for changes related to property SupportDTD.
author
Joe Wang, Sun Microsystems
version
$Id: XMLDocumentScannerImpl.java,v 1.9 2007/05/09 15:23:31 ndw Exp $

Fields Summary
protected static final int
SCANNER_STATE_XML_DECL
Scanner state: XML declaration.
protected static final int
SCANNER_STATE_PROLOG
Scanner state: prolog.
protected static final int
SCANNER_STATE_TRAILING_MISC
Scanner state: trailing misc.
protected static final int
SCANNER_STATE_DTD_INTERNAL_DECLS
Scanner state: DTD internal declarations.
protected static final int
SCANNER_STATE_DTD_EXTERNAL
Scanner state: open DTD external subset.
protected static final int
SCANNER_STATE_DTD_EXTERNAL_DECLS
Scanner state: DTD external declarations.
protected static final int
SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION
Scanner state: NO MORE ELEMENTS.
protected static final String
DOCUMENT_SCANNER
Property identifier document scanner:
protected static final String
LOAD_EXTERNAL_DTD
Feature identifier: load external DTD.
protected static final String
DISALLOW_DOCTYPE_DECL_FEATURE
Feature identifier: load external DTD.
protected static final String
DTD_SCANNER
Property identifier: DTD scanner.
protected static final String
VALIDATION_MANAGER
protected static final String
NAMESPACE_CONTEXT
property identifier: NamespaceContext
private static final String[]
RECOGNIZED_FEATURES
Recognized features.
private static final Boolean[]
FEATURE_DEFAULTS
Feature defaults.
private static final String[]
RECOGNIZED_PROPERTIES
Recognized properties.
private static final Object[]
PROPERTY_DEFAULTS
Property defaults.
protected XMLDTDScanner
fDTDScanner
DTD scanner.
protected ValidationManager
fValidationManager
Validation manager .
protected XMLStringBuffer
fDTDDecl
protected boolean
fReadingDTD
protected boolean
fAddedListener
protected String
fDoctypeName
Doctype name.
protected String
fDoctypePublicId
Doctype declaration public identifier.
protected String
fDoctypeSystemId
Doctype declaration system identifier.
protected NamespaceContext
fNamespaceContext
Namespace support.
protected boolean
fLoadExternalDTD
Load external DTD.
protected boolean
fSeenDoctypeDecl
Seen doctype declaration.
protected boolean
fScanEndElement
protected Driver
fXMLDeclDriver
XML declaration driver.
protected Driver
fPrologDriver
Prolog driver.
protected Driver
fDTDDriver
DTD driver.
protected Driver
fTrailingMiscDriver
Trailing miscellaneous section driver.
protected int
fStartPos
protected int
fEndPos
protected boolean
fSeenInternalSubset
private String[]
fStrings
Array of 3 strings.
private XMLInputSource
fExternalSubsetSource
External subset source.
private final XMLDTDDescription
fDTDDescription
A DTD Description.
private XMLString
fString
String.
private static final char[]
DOCTYPE
private static final char[]
COMMENTSTRING
Constructors Summary
public XMLDocumentScannerImpl()
Default constructor.

        
    //
    // Constructors
    //
    
       
      
Methods Summary
protected DrivercreateContentDriver()
Creates a content driver.

        return new ContentDriver();
    
public voidendEntity(java.lang.String name, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
This method notifies the end of an entity. The DTD has the pseudo-name of "[dtd]" parameter entity names start with '%'; and general entities are just specified by their name.

param
name The name of the entity.
throws
XNIException Thrown by handler to signal an error.

        
        super.endEntity(name, augs);
        
        if(name.equals("[xml]")){
            //if fMarkupDepth has reached 0.
            //and driver is fTrailingMiscDriver (which
            //handles end of document in normal case)
            //set the scanner state of SCANNER_STATE_TERMINATED
            if(fMarkupDepth == 0 && fDriver == fTrailingMiscDriver){
                //set the scanner set to SCANNER_STATE_TERMINATED
                setScannerState(SCANNER_STATE_TERMINATED) ;
            } else{
                //else we have reached the end of document prematurely
                //so throw EOFException.
                throw new java.io.EOFException();
            }
            
            //this is taken care in wrapper which generates XNI callbacks, There are no next events
            
            //if (fDocumentHandler != null) {
                //fDocumentHandler.endDocument(null);
            //}
        }
    
public java.lang.StringgetCharacterEncodingScheme()

        return fDeclaredEncoding;
    
public com.sun.org.apache.xerces.internal.util.XMLStringBuffergetDTDDecl()

        Entity entity = fEntityScanner.getCurrentEntity();
        fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos);
        if(fSeenInternalSubset)
            fDTDDecl.append("]>");
        return fDTDDecl;
    
public java.lang.BooleangetFeatureDefault(java.lang.String featureId)
Returns the default state for a feature, or null if this component does not want to report a default value for this feature.

param
featureId The feature identifier.
since
Xerces 2.2.0

        
        for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
            if (RECOGNIZED_FEATURES[i].equals(featureId)) {
                return FEATURE_DEFAULTS[i];
            }
        }
        return super.getFeatureDefault(featureId);
    
public com.sun.org.apache.xerces.internal.xni.NamespaceContextgetNamespaceContext()

        return fNamespaceContext ;
    
public java.lang.ObjectgetPropertyDefault(java.lang.String propertyId)
Returns the default state for a property, or null if this component does not want to report a default value for this property.

param
propertyId The property identifier.
since
Xerces 2.2.0

        for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
            if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
                return PROPERTY_DEFAULTS[i];
            }
        }
        return super.getPropertyDefault(propertyId);
    
public java.lang.String[]getRecognizedFeatures()
Returns a list of feature identifiers that are recognized by this component. This method may return null if no features are recognized by this component.

        String[] featureIds = super.getRecognizedFeatures();
        int length = featureIds != null ? featureIds.length : 0;
        String[] combinedFeatureIds = new String[length + RECOGNIZED_FEATURES.length];
        if (featureIds != null) {
            System.arraycopy(featureIds, 0, combinedFeatureIds, 0, featureIds.length);
        }
        System.arraycopy(RECOGNIZED_FEATURES, 0, combinedFeatureIds, length, RECOGNIZED_FEATURES.length);
        return combinedFeatureIds;
    
public java.lang.String[]getRecognizedProperties()
Returns a list of property identifiers that are recognized by this component. This method may return null if no properties are recognized by this component.

        String[] propertyIds = super.getRecognizedProperties();
        int length = propertyIds != null ? propertyIds.length : 0;
        String[] combinedPropertyIds = new String[length + RECOGNIZED_PROPERTIES.length];
        if (propertyIds != null) {
            System.arraycopy(propertyIds, 0, combinedPropertyIds, 0, propertyIds.length);
        }
        System.arraycopy(RECOGNIZED_PROPERTIES, 0, combinedPropertyIds, length, RECOGNIZED_PROPERTIES.length);
        return combinedPropertyIds;
    
protected java.lang.StringgetScannerStateName(int state)
Returns the scanner state name.

        
        switch (state) {
            case SCANNER_STATE_XML_DECL: return "SCANNER_STATE_XML_DECL";
            case SCANNER_STATE_PROLOG: return "SCANNER_STATE_PROLOG";
            case SCANNER_STATE_TRAILING_MISC: return "SCANNER_STATE_TRAILING_MISC";
            case SCANNER_STATE_DTD_INTERNAL_DECLS: return "SCANNER_STATE_DTD_INTERNAL_DECLS";
            case SCANNER_STATE_DTD_EXTERNAL: return "SCANNER_STATE_DTD_EXTERNAL";
            case SCANNER_STATE_DTD_EXTERNAL_DECLS: return "SCANNER_STATE_DTD_EXTERNAL_DECLS";
        }
        return super.getScannerStateName(state);
        
    
public intgetScannetState()
return the state of the scanner

        return fScannerState ;
    
public intnext()
return the next state on the input

return
int

        return fDriver.next();
    
public voidrefresh(int refreshPosition)
receives callbacks from {@link XMLEntityReader } when buffer is being changed.

param
refreshPosition

        super.refresh(refreshPosition);
        if(fReadingDTD){
            Entity entity = fEntityScanner.getCurrentEntity();
            if(entity instanceof Entity.ScannedEntity){
                fEndPos=((Entity.ScannedEntity)entity).position;
            }
            fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos);
            fStartPos = refreshPosition;
        }
    
public voidreset(com.sun.org.apache.xerces.internal.impl.PropertyManager propertyManager)

        super.reset(propertyManager);
        // other settings
        fDoctypeName = null;
        fDoctypePublicId = null;
        fDoctypeSystemId = null;
        fSeenDoctypeDecl = false;
        fNamespaceContext.reset();
        fDisallowDoctype = !((Boolean)propertyManager.getProperty(XMLInputFactory.SUPPORT_DTD)).booleanValue();
        
        // xerces features
        fLoadExternalDTD = true ;
        setScannerState(XMLEvent.START_DOCUMENT);
        setDriver(fXMLDeclDriver);
        fSeenInternalSubset = false;
        if(fDTDScanner != null){
            ((XMLDTDScannerImpl)fDTDScanner).reset(propertyManager);
        }
        fEndPos = 0;
        fStartPos = 0;
        if(fDTDDecl != null){
            fDTDDecl.clear();
        }
                
    
public voidreset(com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager componentManager)
Resets the component. The component can query the component manager about any features and properties that affect the operation of the component.

param
componentManager The component manager.
throws
SAXException Thrown by component on initialization error. For example, if a feature or property is required for the operation of the component, the component manager may throw a SAXNotRecognizedException or a SAXNotSupportedException.

        
        super.reset(componentManager);
        
        // other settings
        fDoctypeName = null;
        fDoctypePublicId = null;
        fDoctypeSystemId = null;
        fSeenDoctypeDecl = false;
        fExternalSubsetSource = null;
        
        // xerces features
        try {
            fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD);
        } catch (XMLConfigurationException e) {
            fLoadExternalDTD = true;
        }
        
        try {
            fDisallowDoctype = componentManager.getFeature(DISALLOW_DOCTYPE_DECL_FEATURE);
        } catch (XMLConfigurationException e) {
            fDisallowDoctype = false;
        }
        
        try {
            fNamespaces = componentManager.getFeature(NAMESPACES);
        } catch (XMLConfigurationException e) {
            fNamespaces = true;
        }
        
        fSeenInternalSubset = false;
        // xerces properties
        fDTDScanner = (XMLDTDScanner)componentManager.getProperty(DTD_SCANNER);        
        
        try {
            fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER);
        }
        catch (XMLConfigurationException e) {
            fValidationManager = null;
        }

        try {
            fNamespaceContext = (NamespaceContext)componentManager.getProperty(NAMESPACE_CONTEXT);
        }
        catch (XMLConfigurationException e) { }
        if (fNamespaceContext == null) {
            fNamespaceContext = new NamespaceSupport();
        }
        fNamespaceContext.reset();
        
        fEndPos = 0;
        fStartPos = 0;
        if(fDTDDecl != null)
            fDTDDecl.clear();
            

        //fEntityScanner.registerListener((XMLBufferListener)componentManager.getProperty(DOCUMENT_SCANNER));
        
        // setup driver
        setScannerState(SCANNER_STATE_XML_DECL);
        setDriver(fXMLDeclDriver);
        
    
protected booleanscanDoctypeDecl(boolean ignore)
Scans a doctype declaration.

        
        // spaces
        if (!fEntityScanner.skipSpaces()) {
            reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL",
                    null);
        }
        
        // root element name
        fDoctypeName = fEntityScanner.scanName();
        if (fDoctypeName == null) {
            reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null);
        }
        
        // external id
        if (fEntityScanner.skipSpaces()) {
            scanExternalID(fStrings, false);
            fDoctypeSystemId = fStrings[0];
            fDoctypePublicId = fStrings[1];
            fEntityScanner.skipSpaces();
        }
        
        fHasExternalDTD = fDoctypeSystemId != null;
        
        // Attempt to locate an external subset with an external subset resolver.
        if (!ignore && !fHasExternalDTD && fExternalSubsetResolver != null) {
            fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null);
            fDTDDescription.setRootName(fDoctypeName);
            fExternalSubsetSource = fExternalSubsetResolver.getExternalSubset(fDTDDescription);
            fHasExternalDTD = fExternalSubsetSource != null;
        }
        
        // call handler
        if (!ignore && fDocumentHandler != null) {
            // NOTE: I don't like calling the doctypeDecl callback until
            //       end of the *full* doctype line (including internal
            //       subset) is parsed correctly but SAX2 requires that
            //       it knows the root element name and public and system
            //       identifier for the startDTD call. -Ac
            if (fExternalSubsetSource == null) {
                fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null);
            }
            else {
                fDocumentHandler.doctypeDecl(fDoctypeName, fExternalSubsetSource.getPublicId(), fExternalSubsetSource.getSystemId(), null);
            }            
        }
        
        // is there an internal subset?
        boolean internalSubset = true;
        if (!fEntityScanner.skipChar('[")) {
            internalSubset = false;
            fEntityScanner.skipSpaces();
            if (!fEntityScanner.skipChar('>")) {
                reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
            }
            fMarkupDepth--;
        }
        return internalSubset;
        
    
protected voidsetEndDTDScanState()
Set the scanner state after scanning DTD

        setScannerState(SCANNER_STATE_PROLOG);
        setDriver(fPrologDriver);
        fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
    
public voidsetFeature(java.lang.String featureId, boolean state)
Sets the state of a feature. This method is called by the component manager any time after reset when a feature changes state.

Note: Components should silently ignore features that do not affect the operation of the component.

param
featureId The feature identifier.
param
state The state of the feature.
throws
SAXNotRecognizedException The component should not throw this exception.
throws
SAXNotSupportedException The component should not throw this exception.

        
        super.setFeature(featureId, state);
        
        // Xerces properties
        if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
            final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
        	
            if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && 
                featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
                fLoadExternalDTD = state;
                return;
            }
            else if (suffixLength == Constants.DISALLOW_DOCTYPE_DECL_FEATURE.length() && 
                featureId.endsWith(Constants.DISALLOW_DOCTYPE_DECL_FEATURE)) {
                fDisallowDoctype = state;
                return;
            }
        }
                
    
public voidsetInputSource(com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource inputSource)
Sets the input source.

param
inputSource The input source.
throws
IOException Thrown on i/o error.

        fEntityManager.setEntityHandler(this);
        //this starts a new entity and sets the current entity to the document entity.
        fEntityManager.startDocumentEntity(inputSource);
        // fDocumentSystemId = fEntityManager.expandSystemId(inputSource.getSystemId());
        setScannerState(XMLEvent.START_DOCUMENT);
    
public voidsetProperty(java.lang.String propertyId, java.lang.Object value)
Sets the value of a property. This method is called by the component manager any time after reset when a property changes value.

Note: Components should silently ignore properties that do not affect the operation of the component.

param
propertyId The property identifier.
param
value The value of the property.
throws
SAXNotRecognizedException The component should not throw this exception.
throws
SAXNotSupportedException The component should not throw this exception.

        
        super.setProperty(propertyId, value);
        
        // Xerces properties
        if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
            final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
            
            if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && 
                propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
                fDTDScanner = (XMLDTDScanner)value;
            }
            if (suffixLength == Constants.NAMESPACE_CONTEXT_PROPERTY.length() && 
                propertyId.endsWith(Constants.NAMESPACE_CONTEXT_PROPERTY)) {
                if (value != null) {
                    fNamespaceContext = (NamespaceContext)value;
                }
            }

            return;
        }        
        
    
public voidstartEntity(java.lang.String name, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier identifier, java.lang.String encoding, com.sun.org.apache.xerces.internal.xni.Augmentations augs)
This method notifies of the start of an entity. The DTD has the pseudo-name of "[dtd]" parameter entity names start with '%'; and general entities are just specified by their name.

param
name The name of the entity.
param
identifier The resource identifier.
param
encoding The auto-detected IANA encoding name of the entity stream. This value will be null in those situations where the entity encoding is not auto-detected (e.g. internal entities or a document entity that is parsed from a java.io.Reader).
throws
XNIException Thrown by handler to signal an error.

        
        super.startEntity(name, identifier, encoding,augs);
        
        //register current document scanner as a listener for XMLEntityScanner
        fEntityScanner.registerListener(this);
        
        // prepare to look for a TextDecl if external general entity
        if (!name.equals("[xml]") && fEntityScanner.isExternal()) {
            // Don't do this if we're skipping the entity!
            if (augs == null || !((Boolean) augs.getItem(Constants.ENTITY_SKIPPED)).booleanValue()) {
                setScannerState(SCANNER_STATE_TEXT_DECL);
            }
        }
        
        // call handler
        /** comment this part.. LOCATOR problem.. */
        if (fDocumentHandler != null && name.equals("[xml]")) {
            fDocumentHandler.startDocument(fEntityScanner, encoding, fNamespaceContext, null);
        }