FileDocCategorySizeDatePackage
XMLDocumentScannerImpl.javaAPI DocApache Xerces 3.0.155688Fri Sep 14 20:33:56 BST 2007org.apache.xerces.impl

XMLDocumentScannerImpl

public class XMLDocumentScannerImpl extends XMLDocumentFragmentScannerImpl
This class is responsible for scanning XML document structure and content. The scanner acts as the source for the document information which is communicated to the document handler.

This component requires the following features and properties from the component manager that uses it:

  • http://xml.org/sax/features/namespaces
  • http://xml.org/sax/features/validation
  • http://apache.org/xml/features/nonvalidating/load-external-dtd
  • http://apache.org/xml/features/scanner/notify-char-refs
  • http://apache.org/xml/features/scanner/notify-builtin-refs
  • http://apache.org/xml/properties/internal/symbol-table
  • http://apache.org/xml/properties/internal/error-reporter
  • http://apache.org/xml/properties/internal/entity-manager
  • http://apache.org/xml/properties/internal/dtd-scanner
xerces.internal
author
Glenn Marcy, IBM
author
Andy Clark, IBM
author
Arnaud Le Hors, IBM
author
Eric Ye, IBM
version
$Id: XMLDocumentScannerImpl.java 572055 2007-09-02 17:55:43Z mrglavas $

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 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
property identifier: ValidationManager
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 org.apache.xerces.xni.parser.XMLDTDScanner
fDTDScanner
DTD scanner.
protected org.apache.xerces.impl.validation.ValidationManager
fValidationManager
Validation manager .
protected boolean
fScanningDTD
Scanning DTD.
protected String
fDoctypeName
Doctype name.
protected String
fDoctypePublicId
Doctype declaration public identifier.
protected String
fDoctypeSystemId
Doctype declaration system identifier.
protected org.apache.xerces.xni.NamespaceContext
fNamespaceContext
Namespace support.
protected boolean
fLoadExternalDTD
Load external DTD.
protected boolean
fDisallowDoctype
Disallow doctype declaration.
protected boolean
fSeenDoctypeDecl
Seen doctype declaration.
protected final Dispatcher
fXMLDeclDispatcher
XML declaration dispatcher.
protected final Dispatcher
fPrologDispatcher
Prolog dispatcher.
protected final Dispatcher
fDTDDispatcher
DTD dispatcher.
protected final Dispatcher
fTrailingMiscDispatcher
Trailing miscellaneous section dispatcher.
private final String[]
fStrings
Array of 3 strings.
private final org.apache.xerces.xni.XMLString
fString
String.
private final org.apache.xerces.util.XMLStringBuffer
fStringBuffer
String buffer.
private org.apache.xerces.xni.parser.XMLInputSource
fExternalSubsetSource
External subset source.
private final org.apache.xerces.impl.dtd.XMLDTDDescription
fDTDDescription
A DTD Description.
Constructors Summary
public XMLDocumentScannerImpl()
Default constructor.


    //
    // Constructors
    //

       
      
Methods Summary
protected DispatchercreateContentDispatcher()
Creates a content dispatcher.

        return new ContentDispatcher();
    
public voidendEntity(java.lang.String name, org.apache.xerces.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);

        // call handler
        if (fDocumentHandler != null && name.equals("[xml]")) {
            fDocumentHandler.endDocument(null);
        }

    
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 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 voidreset(org.apache.xerces.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;
        fScanningDTD = false;
        fExternalSubsetSource = null;

		if (!fParserSettings) {
			// parser settings have not been changed
			fNamespaceContext.reset();
			// setup dispatcher
			setScannerState(SCANNER_STATE_XML_DECL);
			setDispatcher(fXMLDeclDispatcher);
			return;
		}

        // 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;
        }

        // 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();
        
        // setup dispatcher
        setScannerState(SCANNER_STATE_XML_DECL);
        setDispatcher(fXMLDeclDispatcher);

    
protected booleanscanDoctypeDecl()
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 (!fHasExternalDTD && fExternalSubsetResolver != null) {
            fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null);
            fDTDDescription.setRootName(fDoctypeName);
            fExternalSubsetSource = fExternalSubsetResolver.getExternalSubset(fDTDDescription);
            fHasExternalDTD = fExternalSubsetSource != null;
        }

        // call handler
        if (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;

    
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(org.apache.xerces.xni.parser.XMLInputSource inputSource)
Sets the input source.

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

        fEntityManager.setEntityHandler(this);
        fEntityManager.startDocumentEntity(inputSource);
        //fDocumentSystemId = fEntityManager.expandSystemId(inputSource.getSystemId());
    
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, org.apache.xerces.xni.XMLResourceIdentifier identifier, java.lang.String encoding, org.apache.xerces.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);

        // prepare to look for a TextDecl if external general entity
        if (!name.equals("[xml]") && fEntityScanner.isExternal()) {
            setScannerState(SCANNER_STATE_TEXT_DECL);
        } 

        // call handler
        if (fDocumentHandler != null && name.equals("[xml]")) {
            fDocumentHandler.startDocument(fEntityScanner, encoding, fNamespaceContext, null);
        }