Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » impl » [javadoc | source]
    1   /*
    2    * Portions Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    */
    4   
    5   /*
    6    * Copyright 2005 The Apache Software Foundation.
    7    *
    8    * Licensed under the Apache License, Version 2.0 (the "License");
    9    * you may not use this file except in compliance with the License.
   10    * You may obtain a copy of the License at
   11    *
   12    *      http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing, software
   15    * distributed under the License is distributed on an "AS IS" BASIS,
   16    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   17    * See the License for the specific language governing permissions and
   18    * limitations under the License.
   19    */
   20   
   21   package com.sun.org.apache.xerces.internal.impl;
   22   
   23   
   24   import com.sun.xml.internal.stream.Entity;
   25   import com.sun.xml.internal.stream.StaxXMLInputSource;
   26   import com.sun.xml.internal.stream.dtd.DTDGrammarUtil;
   27   import java.io.EOFException;
   28   import java.io.IOException;
   29   import javax.xml.stream.XMLInputFactory;
   30   import javax.xml.stream.events.XMLEvent;
   31   
   32   import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
   33   import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
   34   import com.sun.org.apache.xerces.internal.util.XMLChar;
   35   import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
   36   import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
   37   import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
   38   import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
   39   import com.sun.org.apache.xerces.internal.xni.XMLString;
   40   import com.sun.org.apache.xerces.internal.xni.XNIException;
   41   import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
   42   import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
   43   import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
   44   import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
   45   import com.sun.org.apache.xerces.internal.xni.Augmentations;
   46   import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription;
   47   import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
   48   
   49   
   50   /**
   51    * This class is responsible for scanning XML document structure
   52    * and content.
   53    *
   54    * This class has been modified as per the new design which is more suited to
   55    * efficiently build pull parser. Lot of improvements have been done and
   56    * the code has been added to support stax functionality/features.
   57    *
   58    * @author Neeraj Bajaj, Sun Microsystems
   59    * @author K.Venugopal, Sun Microsystems
   60    * @author Glenn Marcy, IBM
   61    * @author Andy Clark, IBM
   62    * @author Arnaud  Le Hors, IBM
   63    * @author Eric Ye, IBM
   64    * @author Sunitha Reddy, Sun Microsystems
   65    */
   66   public class XMLDocumentScannerImpl
   67           extends XMLDocumentFragmentScannerImpl{
   68   
   69       //
   70       // Constants
   71       //
   72   
   73       // scanner states
   74   
   75       /** Scanner state: XML declaration. */
   76       protected static final int SCANNER_STATE_XML_DECL = 42;
   77   
   78       /** Scanner state: prolog. */
   79       protected static final int SCANNER_STATE_PROLOG = 43;
   80   
   81       /** Scanner state: trailing misc. */
   82       protected static final int SCANNER_STATE_TRAILING_MISC = 44;
   83   
   84       /** Scanner state: DTD internal declarations. */
   85       protected static final int SCANNER_STATE_DTD_INTERNAL_DECLS = 45;
   86   
   87       /** Scanner state: open DTD external subset. */
   88       protected static final int SCANNER_STATE_DTD_EXTERNAL = 46;
   89   
   90       /** Scanner state: DTD external declarations. */
   91       protected static final int SCANNER_STATE_DTD_EXTERNAL_DECLS = 47;
   92   
   93       /** Scanner state: NO MORE ELEMENTS. */
   94       protected static final int SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION = 48;
   95   
   96       // feature identifiers
   97   
   98       /** Property identifier document scanner: */
   99       protected static final String DOCUMENT_SCANNER =
  100               Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;
  101   
  102       /** Feature identifier: load external DTD. */
  103       protected static final String LOAD_EXTERNAL_DTD =
  104               Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
  105   
  106       /** Feature identifier: load external DTD. */
  107       protected static final String DISALLOW_DOCTYPE_DECL_FEATURE =
  108               Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
  109   
  110       // property identifiers
  111   
  112       /** Property identifier: DTD scanner. */
  113       protected static final String DTD_SCANNER =
  114               Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;
  115   
  116       // property identifier:  ValidationManager
  117       protected static final String VALIDATION_MANAGER =
  118               Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
  119   
  120       /** property identifier:  NamespaceContext */
  121       protected static final String NAMESPACE_CONTEXT =
  122           Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;
  123   
  124       // recognized features and properties
  125   
  126       /** Recognized features. */
  127       private static final String[] RECOGNIZED_FEATURES = {
  128           LOAD_EXTERNAL_DTD,
  129                   DISALLOW_DOCTYPE_DECL_FEATURE,
  130       };
  131   
  132       /** Feature defaults. */
  133       private static final Boolean[] FEATURE_DEFAULTS = {
  134           Boolean.TRUE,
  135                   Boolean.FALSE,
  136       };
  137   
  138       /** Recognized properties. */
  139       private static final String[] RECOGNIZED_PROPERTIES = {
  140           DTD_SCANNER,
  141                   VALIDATION_MANAGER
  142       };
  143   
  144       /** Property defaults. */
  145       private static final Object[] PROPERTY_DEFAULTS = {
  146           null,
  147                   null
  148       };
  149   
  150       //
  151       // Data((Boolean)propertyManager.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE)).booleanValue();
  152       //
  153   
  154       // properties
  155   
  156       /** DTD scanner. */
  157       protected XMLDTDScanner fDTDScanner = null;
  158   
  159       /** Validation manager . */
  160       //xxx: fValidationManager code needs to be added yet!
  161       protected ValidationManager fValidationManager;
  162   
  163       protected XMLStringBuffer fDTDDecl = null;
  164       protected boolean fReadingDTD = false;
  165       protected boolean fAddedListener = false;
  166   
  167       // protected data
  168   
  169       // other info
  170   
  171       /** Doctype name. */
  172       protected String fDoctypeName;
  173   
  174       /** Doctype declaration public identifier. */
  175       protected String fDoctypePublicId;
  176   
  177       /** Doctype declaration system identifier. */
  178       protected String fDoctypeSystemId;
  179   
  180       /** Namespace support. */
  181       protected NamespaceContext fNamespaceContext = new NamespaceSupport();
  182   
  183       // features
  184   
  185       /** Load external DTD. */
  186       protected boolean fLoadExternalDTD = true;
  187   
  188       /** Disallow doctype declaration. */
  189       protected boolean fDisallowDoctype = false;
  190   
  191       // state
  192   
  193       /** Seen doctype declaration. */
  194       protected boolean fSeenDoctypeDecl;
  195   
  196       protected boolean fScanEndElement;
  197   
  198       //protected int fScannerLastState ;
  199   
  200       // drivers
  201   
  202       /** XML declaration driver. */
  203       protected Driver fXMLDeclDriver = new XMLDeclDriver();
  204   
  205       /** Prolog driver. */
  206       protected Driver fPrologDriver = new PrologDriver();
  207   
  208       /** DTD driver. */
  209       protected Driver fDTDDriver = null ;
  210   
  211       /** Trailing miscellaneous section driver. */
  212       protected Driver fTrailingMiscDriver = new TrailingMiscDriver();
  213       protected int fStartPos = 0;
  214       protected int fEndPos = 0;
  215       protected boolean fSeenInternalSubset= false;
  216       // temporary variables
  217   
  218       /** Array of 3 strings. */
  219       private String[] fStrings = new String[3];
  220   
  221       /** External subset source. */
  222       private XMLInputSource fExternalSubsetSource = null;
  223   
  224       /** A DTD Description. */
  225       private final XMLDTDDescription fDTDDescription = new XMLDTDDescription(null, null, null, null, null);
  226   
  227       /** String. */
  228       private XMLString fString = new XMLString();
  229   
  230       public static final char [] DOCTYPE = {'D','O','C','T','Y','P','E'};
  231       public static final char [] COMMENTSTRING = {'-','-'};
  232   
  233       //
  234       // Constructors
  235       //
  236   
  237       /** Default constructor. */
  238       public XMLDocumentScannerImpl() {} // <init>()
  239   
  240   
  241       //
  242       // XMLDocumentScanner methods
  243       //
  244   
  245   
  246       /**
  247        * Sets the input source.
  248        *
  249        * @param inputSource The input source.
  250        *
  251        * @throws IOException Thrown on i/o error.
  252        */
  253       public void setInputSource(XMLInputSource inputSource) throws IOException {
  254           fEntityManager.setEntityHandler(this);
  255           //this starts a new entity and sets the current entity to the document entity.
  256           fEntityManager.startDocumentEntity(inputSource);
  257           // fDocumentSystemId = fEntityManager.expandSystemId(inputSource.getSystemId());
  258           setScannerState(XMLEvent.START_DOCUMENT);
  259       } // setInputSource(XMLInputSource)
  260   
  261   
  262   
  263       /**return the state of the scanner */
  264       public int getScannetState(){
  265           return fScannerState ;
  266       }
  267   
  268   
  269   
  270   
  271       public void reset(PropertyManager propertyManager) {
  272           super.reset(propertyManager);
  273           // other settings
  274           fDoctypeName = null;
  275           fDoctypePublicId = null;
  276           fDoctypeSystemId = null;
  277           fSeenDoctypeDecl = false;
  278           fNamespaceContext.reset();
  279           fDisallowDoctype = !((Boolean)propertyManager.getProperty(XMLInputFactory.SUPPORT_DTD)).booleanValue();
  280   
  281           // xerces features
  282           fLoadExternalDTD = true ;
  283           setScannerState(XMLEvent.START_DOCUMENT);
  284           setDriver(fXMLDeclDriver);
  285           fSeenInternalSubset = false;
  286           if(fDTDScanner != null){
  287               ((XMLDTDScannerImpl)fDTDScanner).reset(propertyManager);
  288           }
  289           fEndPos = 0;
  290           fStartPos = 0;
  291           if(fDTDDecl != null){
  292               fDTDDecl.clear();
  293           }
  294   
  295       }
  296   
  297       /**
  298        * Resets the component. The component can query the component manager
  299        * about any features and properties that affect the operation of the
  300        * component.
  301        *
  302        * @param componentManager The component manager.
  303        *
  304        * @throws SAXException Thrown by component on initialization error.
  305        *                      For example, if a feature or property is
  306        *                      required for the operation of the component, the
  307        *                      component manager may throw a
  308        *                      SAXNotRecognizedException or a
  309        *                      SAXNotSupportedException.
  310        */
  311       public void reset(XMLComponentManager componentManager)
  312       throws XMLConfigurationException {
  313   
  314           super.reset(componentManager);
  315   
  316           // other settings
  317           fDoctypeName = null;
  318           fDoctypePublicId = null;
  319           fDoctypeSystemId = null;
  320           fSeenDoctypeDecl = false;
  321           fExternalSubsetSource = null;
  322   
  323           // xerces features
  324           try {
  325               fLoadExternalDTD = componentManager.getFeature(LOAD_EXTERNAL_DTD);
  326           } catch (XMLConfigurationException e) {
  327               fLoadExternalDTD = true;
  328           }
  329   
  330           try {
  331               fDisallowDoctype = componentManager.getFeature(DISALLOW_DOCTYPE_DECL_FEATURE);
  332           } catch (XMLConfigurationException e) {
  333               fDisallowDoctype = false;
  334           }
  335   
  336           try {
  337               fNamespaces = componentManager.getFeature(NAMESPACES);
  338           } catch (XMLConfigurationException e) {
  339               fNamespaces = true;
  340           }
  341   
  342           fSeenInternalSubset = false;
  343           // xerces properties
  344           fDTDScanner = (XMLDTDScanner)componentManager.getProperty(DTD_SCANNER);
  345   
  346           try {
  347               fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER);
  348           }
  349           catch (XMLConfigurationException e) {
  350               fValidationManager = null;
  351           }
  352   
  353           try {
  354               fNamespaceContext = (NamespaceContext)componentManager.getProperty(NAMESPACE_CONTEXT);
  355           }
  356           catch (XMLConfigurationException e) { }
  357           if (fNamespaceContext == null) {
  358               fNamespaceContext = new NamespaceSupport();
  359           }
  360           fNamespaceContext.reset();
  361   
  362           fEndPos = 0;
  363           fStartPos = 0;
  364           if(fDTDDecl != null)
  365               fDTDDecl.clear();
  366   
  367   
  368           //fEntityScanner.registerListener((XMLBufferListener)componentManager.getProperty(DOCUMENT_SCANNER));
  369   
  370           // setup driver
  371           setScannerState(SCANNER_STATE_XML_DECL);
  372           setDriver(fXMLDeclDriver);
  373   
  374       } // reset(XMLComponentManager)
  375   
  376   
  377       /**
  378        * Returns a list of feature identifiers that are recognized by
  379        * this component. This method may return null if no features
  380        * are recognized by this component.
  381        */
  382       public String[] getRecognizedFeatures() {
  383           String[] featureIds = super.getRecognizedFeatures();
  384           int length = featureIds != null ? featureIds.length : 0;
  385           String[] combinedFeatureIds = new String[length + RECOGNIZED_FEATURES.length];
  386           if (featureIds != null) {
  387               System.arraycopy(featureIds, 0, combinedFeatureIds, 0, featureIds.length);
  388           }
  389           System.arraycopy(RECOGNIZED_FEATURES, 0, combinedFeatureIds, length, RECOGNIZED_FEATURES.length);
  390           return combinedFeatureIds;
  391       } // getRecognizedFeatures():String[]
  392   
  393       /**
  394        * Sets the state of a feature. This method is called by the component
  395        * manager any time after reset when a feature changes state.
  396        * <p>
  397        * <strong>Note:</strong> Components should silently ignore features
  398        * that do not affect the operation of the component.
  399        *
  400        * @param featureId The feature identifier.
  401        * @param state     The state of the feature.
  402        *
  403        * @throws SAXNotRecognizedException The component should not throw
  404        *                                   this exception.
  405        * @throws SAXNotSupportedException The component should not throw
  406        *                                  this exception.
  407        */
  408       public void setFeature(String featureId, boolean state)
  409       throws XMLConfigurationException {
  410   
  411           super.setFeature(featureId, state);
  412   
  413           // Xerces properties
  414           if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
  415               final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
  416   
  417               if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
  418                   featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
  419                   fLoadExternalDTD = state;
  420                   return;
  421               }
  422               else if (suffixLength == Constants.DISALLOW_DOCTYPE_DECL_FEATURE.length() &&
  423                   featureId.endsWith(Constants.DISALLOW_DOCTYPE_DECL_FEATURE)) {
  424                   fDisallowDoctype = state;
  425                   return;
  426               }
  427           }
  428   
  429       } // setFeature(String,boolean)
  430   
  431       /**
  432        * Returns a list of property identifiers that are recognized by
  433        * this component. This method may return null if no properties
  434        * are recognized by this component.
  435        */
  436       public String[] getRecognizedProperties() {
  437           String[] propertyIds = super.getRecognizedProperties();
  438           int length = propertyIds != null ? propertyIds.length : 0;
  439           String[] combinedPropertyIds = new String[length + RECOGNIZED_PROPERTIES.length];
  440           if (propertyIds != null) {
  441               System.arraycopy(propertyIds, 0, combinedPropertyIds, 0, propertyIds.length);
  442           }
  443           System.arraycopy(RECOGNIZED_PROPERTIES, 0, combinedPropertyIds, length, RECOGNIZED_PROPERTIES.length);
  444           return combinedPropertyIds;
  445       } // getRecognizedProperties():String[]
  446   
  447       /**
  448        * Sets the value of a property. This method is called by the component
  449        * manager any time after reset when a property changes value.
  450        * <p>
  451        * <strong>Note:</strong> Components should silently ignore properties
  452        * that do not affect the operation of the component.
  453        *
  454        * @param propertyId The property identifier.
  455        * @param value      The value of the property.
  456        *
  457        * @throws SAXNotRecognizedException The component should not throw
  458        *                                   this exception.
  459        * @throws SAXNotSupportedException The component should not throw
  460        *                                  this exception.
  461        */
  462       public void setProperty(String propertyId, Object value)
  463       throws XMLConfigurationException {
  464   
  465           super.setProperty(propertyId, value);
  466   
  467           // Xerces properties
  468           if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
  469               final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
  470   
  471               if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
  472                   propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
  473                   fDTDScanner = (XMLDTDScanner)value;
  474               }
  475               if (suffixLength == Constants.NAMESPACE_CONTEXT_PROPERTY.length() &&
  476                   propertyId.endsWith(Constants.NAMESPACE_CONTEXT_PROPERTY)) {
  477                   if (value != null) {
  478                       fNamespaceContext = (NamespaceContext)value;
  479                   }
  480               }
  481   
  482               return;
  483           }
  484   
  485       } // setProperty(String,Object)
  486   
  487       /**
  488        * Returns the default state for a feature, or null if this
  489        * component does not want to report a default value for this
  490        * feature.
  491        *
  492        * @param featureId The feature identifier.
  493        *
  494        * @since Xerces 2.2.0
  495        */
  496       public Boolean getFeatureDefault(String featureId) {
  497   
  498           for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
  499               if (RECOGNIZED_FEATURES[i].equals(featureId)) {
  500                   return FEATURE_DEFAULTS[i];
  501               }
  502           }
  503           return super.getFeatureDefault(featureId);
  504       } // getFeatureDefault(String):Boolean
  505   
  506       /**
  507        * Returns the default state for a property, or null if this
  508        * component does not want to report a default value for this
  509        * property.
  510        *
  511        * @param propertyId The property identifier.
  512        *
  513        * @since Xerces 2.2.0
  514        */
  515       public Object getPropertyDefault(String propertyId) {
  516           for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
  517               if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
  518                   return PROPERTY_DEFAULTS[i];
  519               }
  520           }
  521           return super.getPropertyDefault(propertyId);
  522       } // getPropertyDefault(String):Object
  523   
  524       //
  525       // XMLEntityHandler methods
  526       //
  527   
  528       /**
  529        * This method notifies of the start of an entity. The DTD has the
  530        * pseudo-name of "[dtd]" parameter entity names start with '%'; and
  531        * general entities are just specified by their name.
  532        *
  533        * @param name     The name of the entity.
  534        * @param identifier The resource identifier.
  535        * @param encoding The auto-detected IANA encoding name of the entity
  536        *                 stream. This value will be null in those situations
  537        *                 where the entity encoding is not auto-detected (e.g.
  538        *                 internal entities or a document entity that is
  539        *                 parsed from a java.io.Reader).
  540        *
  541        * @throws XNIException Thrown by handler to signal an error.
  542        */
  543       public void startEntity(String name,
  544               XMLResourceIdentifier identifier,
  545               String encoding, Augmentations augs) throws XNIException {
  546   
  547           super.startEntity(name, identifier, encoding,augs);
  548   
  549           //register current document scanner as a listener for XMLEntityScanner
  550           fEntityScanner.registerListener(this);
  551   
  552           // prepare to look for a TextDecl if external general entity
  553           if (!name.equals("[xml]") && fEntityScanner.isExternal()) {
  554               // Don't do this if we're skipping the entity!
  555               if (augs == null || !((Boolean) augs.getItem(Constants.ENTITY_SKIPPED)).booleanValue()) {
  556                   setScannerState(SCANNER_STATE_TEXT_DECL);
  557               }
  558           }
  559   
  560           // call handler
  561           /** comment this part.. LOCATOR problem.. */
  562           if (fDocumentHandler != null && name.equals("[xml]")) {
  563               fDocumentHandler.startDocument(fEntityScanner, encoding, fNamespaceContext, null);
  564           }
  565   
  566       } // startEntity(String,identifier,String)
  567   
  568   
  569       /**
  570        * This method notifies the end of an entity. The DTD has the pseudo-name
  571        * of "[dtd]" parameter entity names start with '%'; and general entities
  572        * are just specified by their name.
  573        *
  574        * @param name The name of the entity.
  575        *
  576        * @throws XNIException Thrown by handler to signal an error.
  577        */
  578       public void endEntity(String name, Augmentations augs) throws IOException, XNIException {
  579   
  580           super.endEntity(name, augs);
  581   
  582           if(name.equals("[xml]")){
  583               //if fMarkupDepth has reached 0.
  584               //and driver is fTrailingMiscDriver (which
  585               //handles end of document in normal case)
  586               //set the scanner state of SCANNER_STATE_TERMINATED
  587               if(fMarkupDepth == 0 && fDriver == fTrailingMiscDriver){
  588                   //set the scanner set to SCANNER_STATE_TERMINATED
  589                   setScannerState(SCANNER_STATE_TERMINATED) ;
  590               } else{
  591                   //else we have reached the end of document prematurely
  592                   //so throw EOFException.
  593                   throw new java.io.EOFException();
  594               }
  595   
  596               //this is taken care in wrapper which generates XNI callbacks, There are no next events
  597   
  598               //if (fDocumentHandler != null) {
  599                   //fDocumentHandler.endDocument(null);
  600               //}
  601           }
  602       } // endEntity(String)
  603   
  604   
  605       public XMLStringBuffer getDTDDecl(){
  606           Entity entity = fEntityScanner.getCurrentEntity();
  607           fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos);
  608           if(fSeenInternalSubset)
  609               fDTDDecl.append("]>");
  610           return fDTDDecl;
  611       }
  612   
  613       public String getCharacterEncodingScheme(){
  614           return fDeclaredEncoding;
  615       }
  616   
  617       /** return the next state on the input
  618        *
  619        * @return int
  620        */
  621   
  622       public int next() throws IOException, XNIException {
  623           return fDriver.next();
  624       }
  625   
  626       //getNamespaceContext
  627       public NamespaceContext getNamespaceContext(){
  628           return fNamespaceContext ;
  629       }
  630   
  631   
  632   
  633       //
  634       // Protected methods
  635       //
  636   
  637       // driver factory methods
  638   
  639       /** Creates a content driver. */
  640       protected Driver createContentDriver() {
  641           return new ContentDriver();
  642       } // createContentDriver():Driver
  643   
  644       // scanning methods
  645   
  646       /** Scans a doctype declaration. */
  647       protected boolean scanDoctypeDecl(boolean ignore) throws IOException, XNIException {
  648   
  649           // spaces
  650           if (!fEntityScanner.skipSpaces()) {
  651               reportFatalError("MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL",
  652                       null);
  653           }
  654   
  655           // root element name
  656           fDoctypeName = fEntityScanner.scanName();
  657           if (fDoctypeName == null) {
  658               reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null);
  659           }
  660   
  661           // external id
  662           if (fEntityScanner.skipSpaces()) {
  663               scanExternalID(fStrings, false);
  664               fDoctypeSystemId = fStrings[0];
  665               fDoctypePublicId = fStrings[1];
  666               fEntityScanner.skipSpaces();
  667           }
  668   
  669           fHasExternalDTD = fDoctypeSystemId != null;
  670   
  671           // Attempt to locate an external subset with an external subset resolver.
  672           if (!ignore && !fHasExternalDTD && fExternalSubsetResolver != null) {
  673               fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null);
  674               fDTDDescription.setRootName(fDoctypeName);
  675               fExternalSubsetSource = fExternalSubsetResolver.getExternalSubset(fDTDDescription);
  676               fHasExternalDTD = fExternalSubsetSource != null;
  677           }
  678   
  679           // call handler
  680           if (!ignore && fDocumentHandler != null) {
  681               // NOTE: I don't like calling the doctypeDecl callback until
  682               //       end of the *full* doctype line (including internal
  683               //       subset) is parsed correctly but SAX2 requires that
  684               //       it knows the root element name and public and system
  685               //       identifier for the startDTD call. -Ac
  686               if (fExternalSubsetSource == null) {
  687                   fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null);
  688               }
  689               else {
  690                   fDocumentHandler.doctypeDecl(fDoctypeName, fExternalSubsetSource.getPublicId(), fExternalSubsetSource.getSystemId(), null);
  691               }
  692           }
  693   
  694           // is there an internal subset?
  695           boolean internalSubset = true;
  696           if (!fEntityScanner.skipChar('[')) {
  697               internalSubset = false;
  698               fEntityScanner.skipSpaces();
  699               if (!fEntityScanner.skipChar('>')) {
  700                   reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
  701               }
  702               fMarkupDepth--;
  703           }
  704           return internalSubset;
  705   
  706       } // scanDoctypeDecl():boolean
  707   
  708       //
  709       // Private methods
  710       //
  711   
  712       /** Returns the scanner state name. */
  713       protected String getScannerStateName(int state) {
  714   
  715           switch (state) {
  716               case SCANNER_STATE_XML_DECL: return "SCANNER_STATE_XML_DECL";
  717               case SCANNER_STATE_PROLOG: return "SCANNER_STATE_PROLOG";
  718               case SCANNER_STATE_TRAILING_MISC: return "SCANNER_STATE_TRAILING_MISC";
  719               case SCANNER_STATE_DTD_INTERNAL_DECLS: return "SCANNER_STATE_DTD_INTERNAL_DECLS";
  720               case SCANNER_STATE_DTD_EXTERNAL: return "SCANNER_STATE_DTD_EXTERNAL";
  721               case SCANNER_STATE_DTD_EXTERNAL_DECLS: return "SCANNER_STATE_DTD_EXTERNAL_DECLS";
  722           }
  723           return super.getScannerStateName(state);
  724   
  725       } // getScannerStateName(int):String
  726   
  727       //
  728       // Classes
  729       //
  730   
  731       /**
  732        * Driver to handle XMLDecl scanning.
  733        *
  734        * This class has been modified as per the new design which is more suited to
  735        * efficiently build pull parser. Lots of performance improvements have been done and
  736        * the code has been added to support stax functionality/features.
  737        *
  738        * @author Neeraj Bajaj, Sun Microsystems.
  739        *
  740        * @author Andy Clark, IBM
  741        */
  742       protected final class XMLDeclDriver
  743               implements Driver {
  744   
  745           //
  746           // Driver methods
  747           //
  748   
  749   
  750           public int next() throws IOException, XNIException {
  751               if(DEBUG_NEXT){
  752                   System.out.println("NOW IN XMLDeclDriver");
  753               }
  754   
  755               // next driver is prolog regardless of whether there
  756               // is an XMLDecl in this document
  757               setScannerState(SCANNER_STATE_PROLOG);
  758               setDriver(fPrologDriver);
  759   
  760               //System.out.println("fEntityScanner = " + fEntityScanner);
  761               // scan XMLDecl
  762               try {
  763                   if (fEntityScanner.skipString(xmlDecl)) {
  764                       fMarkupDepth++;
  765                       // NOTE: special case where document starts with a PI
  766                       //       whose name starts with "xml" (e.g. "xmlfoo")
  767                       if (XMLChar.isName(fEntityScanner.peekChar())) {
  768                           fStringBuffer.clear();
  769                           fStringBuffer.append("xml");
  770                           while (XMLChar.isName(fEntityScanner.peekChar())) {
  771                               fStringBuffer.append((char)fEntityScanner.scanChar());
  772                           }
  773                           String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
  774                           //this function should fill the data.. and set the fEvent object to this event.
  775                           fStringBuffer.clear() ;
  776                           scanPIData(target, fStringBuffer);
  777                           //REVISIT:where else we can set this value to 'true'
  778                           fEntityManager.fCurrentEntity.mayReadChunks = true;
  779                           //return PI event since PI was encountered
  780                           return XMLEvent.PROCESSING_INSTRUCTION ;
  781                       }
  782                       // standard XML declaration
  783                       else {
  784                           scanXMLDeclOrTextDecl(false);
  785                           //REVISIT:where else we can set this value to 'true'
  786                           fEntityManager.fCurrentEntity.mayReadChunks = true;
  787                           return XMLEvent.START_DOCUMENT;
  788                       }
  789                   } else{
  790                       //REVISIT:where else we can set this value to 'true'
  791                       fEntityManager.fCurrentEntity.mayReadChunks = true;
  792                       //In both case return the START_DOCUMENT. ony difference is that first block will
  793                       //cosume the XML declaration if any.
  794                       return XMLEvent.START_DOCUMENT;
  795                   }
  796   
  797   
  798                   //START_OF_THE_DOCUMENT
  799   
  800   
  801               }
  802   
  803               // premature end of file
  804               catch (EOFException e) {
  805                   reportFatalError("PrematureEOF", null);
  806                   return -1;
  807                   //throw e;
  808               }
  809   
  810           }
  811       } // class XMLDeclDriver
  812   
  813       /**
  814        * Driver to handle prolog scanning.
  815        *
  816        * @author Andy Clark, IBM
  817        */
  818       protected final class PrologDriver
  819               implements Driver {
  820   
  821           /**
  822            * Drives the parser to the next state/event on the input. Parser is guaranteed
  823            * to stop at the next state/event.
  824            *
  825            * Internally XML document is divided into several states. Each state represents
  826            * a sections of XML document. When this functions returns normally, it has read
  827            * the section of XML document and returns the state corresponding to section of
  828            * document which has been read. For optimizations, a particular driver
  829            * can read ahead of the section of document (state returned) just read and
  830            * can maintain a different internal state.
  831            *
  832            * @return state representing the section of document just read.
  833            *
  834            * @throws IOException  Thrown on i/o error.
  835            * @throws XNIException Thrown on parse error.
  836            */
  837   
  838           public int next() throws IOException, XNIException {
  839               //System.out.println("here in next");
  840   
  841               if(DEBUG_NEXT){
  842                   System.out.println("NOW IN PrologDriver");
  843               }
  844               try {
  845                   do {
  846                       switch (fScannerState) {
  847                           case SCANNER_STATE_PROLOG: {
  848                               fEntityScanner.skipSpaces();
  849                               if (fEntityScanner.skipChar('<')) {
  850                                   setScannerState(SCANNER_STATE_START_OF_MARKUP);
  851                               } else if (fEntityScanner.skipChar('&')) {
  852                                   setScannerState(SCANNER_STATE_REFERENCE);
  853                               } else {
  854                                   setScannerState(SCANNER_STATE_CONTENT);
  855                               }
  856                               break;
  857                           }
  858   
  859                           case SCANNER_STATE_START_OF_MARKUP: {
  860                               fMarkupDepth++;
  861   
  862                               if (fEntityScanner.skipChar('?')) {
  863                                   setScannerState(SCANNER_STATE_PI);
  864                               } else if (fEntityScanner.skipChar('!')) {
  865                                   if (fEntityScanner.skipChar('-')) {
  866                                       if (!fEntityScanner.skipChar('-')) {
  867                                           reportFatalError("InvalidCommentStart",
  868                                                   null);
  869                                       }
  870                                       setScannerState(SCANNER_STATE_COMMENT);
  871                                   } else if (fEntityScanner.skipString(DOCTYPE)) {
  872                                       setScannerState(SCANNER_STATE_DOCTYPE);
  873                                       Entity entity = fEntityScanner.getCurrentEntity();
  874                                       if(entity instanceof Entity.ScannedEntity){
  875                                           fStartPos=((Entity.ScannedEntity)entity).position;
  876                                       }
  877                                       fReadingDTD=true;
  878                                       if(fDTDDecl == null)
  879                                           fDTDDecl = new XMLStringBuffer();
  880                                       fDTDDecl.append("<!DOCTYPE");
  881   
  882                                   } else {
  883                                       reportFatalError("MarkupNotRecognizedInProlog",
  884                                               null);
  885                                   }
  886                               } else if (XMLChar.isNameStart(fEntityScanner.peekChar())) {
  887                                   setScannerState(SCANNER_STATE_ROOT_ELEMENT);
  888                                   setDriver(fContentDriver);
  889                                   //from now onwards this would be handled by fContentDriver,in the same next() call
  890                                   return fContentDriver.next();
  891   
  892                               } else {
  893                                   reportFatalError("MarkupNotRecognizedInProlog",
  894                                           null);
  895                               }
  896                               break;
  897                           }
  898                       }
  899                   } while (fScannerState == SCANNER_STATE_PROLOG || fScannerState == SCANNER_STATE_START_OF_MARKUP );
  900   
  901                   switch(fScannerState){
  902                       /**
  903                       //this part is handled by FragmentContentHandler
  904                       case SCANNER_STATE_ROOT_ELEMENT: {
  905                           //we have read '<' and beginning of reading the start element tag
  906                           setScannerState(SCANNER_STATE_START_ELEMENT_TAG);
  907                           setDriver(fContentDriver);
  908                           //from now onwards this would be handled by fContentDriver,in the same next() call
  909                           return fContentDriver.next();
  910                       }
  911                        */
  912                       case SCANNER_STATE_COMMENT: {
  913                           //this function fills the data..
  914                           scanComment();
  915                           setScannerState(SCANNER_STATE_PROLOG);
  916                           return XMLEvent.COMMENT;
  917                           //setScannerState(SCANNER_STATE_PROLOG);
  918                           //break;
  919                       }
  920                       case SCANNER_STATE_PI: {
  921                           fContentBuffer.clear() ;
  922                           scanPI(fContentBuffer);
  923                           setScannerState(SCANNER_STATE_PROLOG);
  924                           return XMLEvent.PROCESSING_INSTRUCTION;
  925                       }
  926   
  927                       case SCANNER_STATE_DOCTYPE: {
  928   
  929                           if (fSeenDoctypeDecl) {
  930                               reportFatalError("AlreadySeenDoctype", null);
  931                           }
  932                           fSeenDoctypeDecl = true;
  933                           if(fDTDDriver == null){
  934                               fDTDDriver = new DTDDriver();
  935                           }
  936   
  937                           // scanDoctypeDecl() sends XNI doctypeDecl event that
  938                           // in SAX is converted to startDTD() event.
  939                           if (scanDoctypeDecl(fDisallowDoctype)) {
  940                               setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS);
  941                               fSeenInternalSubset = true;
  942                               setDriver(fContentDriver);
  943                               int dtdEvent = fDTDDriver.next();
  944                               // If no DTD support, ignore and continue parsing
  945                               return fDisallowDoctype ? next() : dtdEvent;
  946                           }
  947   
  948                           /** xxx:check this part again
  949                           if(fSeenDoctypeDecl){
  950                               Entity entity = fEntityScanner.getCurrentEntity();
  951                               if(entity instanceof Entity.ScannedEntity){
  952                                   fEndPos = ((Entity.ScannedEntity)entity).position;
  953                               }
  954                               fReadingDTD = false;
  955                           }
  956                            */
  957   
  958                           if (fDisallowDoctype) {
  959                               setScannerState(SCANNER_STATE_PROLOG);
  960                               return next();
  961                           }
  962   
  963                           // handle external subset
  964                           if (fDoctypeSystemId != null) {
  965                               if (((fValidation || fLoadExternalDTD)
  966                                   && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {
  967                                   setScannerState(SCANNER_STATE_DTD_EXTERNAL);
  968                                   setDriver(fContentDriver);
  969                                   return fDTDDriver.next();
  970   
  971                               }
  972                           }
  973                           else if (fExternalSubsetSource != null) {
  974                               if (((fValidation || fLoadExternalDTD)
  975                                   && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {
  976                                   // This handles the case of a DOCTYPE that had neither an internal subset or an external subset.
  977                                   fDTDScanner.setInputSource(fExternalSubsetSource);
  978                                   fExternalSubsetSource = null;
  979                                   setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
  980                                   setDriver(fContentDriver);
  981                                   return fDTDDriver.next();
  982                               }
  983                           }
  984   
  985                           // Send endDTD() call if:
  986                           // a) systemId is null or if an external subset resolver could not locate an external subset.
  987                           // b) "load-external-dtd" and validation are false
  988                           // c) DTD grammar is cached
  989   
  990                           // in XNI this results in 3 events:  doctypeDecl, startDTD, endDTD
  991                           // in SAX this results in 2 events: startDTD, endDTD
  992                           if (fDTDScanner != null) {
  993                               fDTDScanner.setInputSource(null);
  994                           }
  995                           setScannerState(SCANNER_STATE_PROLOG);
  996                           return XMLEvent.DTD;
  997                       }
  998   
  999                       case SCANNER_STATE_CONTENT: {
 1000                           reportFatalError("ContentIllegalInProlog", null);
 1001                           fEntityScanner.scanChar();
 1002                       }
 1003                       case SCANNER_STATE_REFERENCE: {
 1004                           reportFatalError("ReferenceIllegalInProlog", null);
 1005                       }
 1006   
 1007                       /**
 1008                        * if (complete) {
 1009                        * if (fEntityScanner.scanChar() != '<') {
 1010                        * reportFatalError("RootElementRequired", null);
 1011                        * }
 1012                        * setScannerState(SCANNER_STATE_ROOT_ELEMENT);
 1013                        * setDriver(fContentDriver);
 1014                        * }
 1015                        */
 1016                   }
 1017               }
 1018               // premature end of file
 1019               catch (EOFException e) {
 1020                   reportFatalError("PrematureEOF", null);
 1021                   //xxx  what should be returned here.... ???
 1022                   return -1 ;
 1023                   //throw e;
 1024               }
 1025               //xxx  what should be returned here.... ???
 1026               return -1;
 1027   
 1028           }
 1029   
 1030   
 1031       } // class PrologDriver
 1032   
 1033       /**
 1034        * Driver to handle the internal and external DTD subsets.
 1035        *
 1036        * @author Andy Clark, IBM
 1037        */
 1038       protected final class DTDDriver
 1039               implements Driver {
 1040   
 1041           //
 1042           // Driver methods
 1043           //
 1044   
 1045           public int next() throws IOException, XNIException{
 1046               // throw new XNIException("DTD Parsing is currently not supported");
 1047               if(DEBUG_NEXT){
 1048                   System.out.println("Now in DTD Driver");
 1049               }
 1050   
 1051               dispatch(true);
 1052   
 1053               if(DEBUG_NEXT){
 1054                   System.out.println("After calling dispatch(true) -- At this point whole DTD is read.");
 1055               }
 1056   
 1057               //xxx: remove this hack and align this with reusing DTD components
 1058               //currently this routine will only be executed from Stax
 1059               if(fPropertyManager != null){
 1060                   dtdGrammarUtil =  new DTDGrammarUtil(((XMLDTDScannerImpl)fDTDScanner).getGrammar(),fSymbolTable, fNamespaceContext);
 1061               }
 1062   
 1063               return XMLEvent.DTD ;
 1064           }
 1065   
 1066           /**
 1067            * Dispatch an XML "event".
 1068            *
 1069            * @param complete True if this driver is intended to scan
 1070            *                 and dispatch as much as possible.
 1071            *
 1072            * @return True if there is more to dispatch either from this
 1073            *          or a another driver.
 1074            *
 1075            * @throws IOException  Thrown on i/o error.
 1076            * @throws XNIException Thrown on parse error.
 1077            */
 1078           public boolean dispatch(boolean complete)
 1079           throws IOException, XNIException {
 1080               fEntityManager.setEntityHandler(null);
 1081               try {
 1082                   boolean again;
 1083                   XMLResourceIdentifierImpl resourceIdentifier = new XMLResourceIdentifierImpl();
 1084                   if( fDTDScanner == null){
 1085   
 1086                       if (fEntityManager.getEntityScanner() instanceof XML11EntityScanner){
 1087                           fDTDScanner = new XML11DTDScannerImpl();
 1088                       } else
 1089   
 1090                       fDTDScanner = new XMLDTDScannerImpl();
 1091   
 1092                       ((XMLDTDScannerImpl)fDTDScanner).reset(fPropertyManager);
 1093                   }
 1094                   do {
 1095                       again = false;
 1096                       switch (fScannerState) {
 1097                           case SCANNER_STATE_DTD_INTERNAL_DECLS: {
 1098                               // REVISIT: Should there be a feature for
 1099                               //          the "complete" parameter?
 1100                               boolean completeDTD = true;
 1101   
 1102                               boolean moreToScan = fDTDScanner.scanDTDInternalSubset(completeDTD, fStandalone, fHasExternalDTD && fLoadExternalDTD);
 1103                               Entity entity = fEntityScanner.getCurrentEntity();
 1104                               if(entity instanceof Entity.ScannedEntity){
 1105                                   fEndPos=((Entity.ScannedEntity)entity).position;
 1106                               }
 1107                               fReadingDTD=false;
 1108                               if (!moreToScan) {
 1109                                   // end doctype declaration
 1110                                   if (!fEntityScanner.skipChar(']')) {
 1111                                       reportFatalError("EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET",
 1112                                               null);
 1113                                   }
 1114                                   fEntityScanner.skipSpaces();
 1115                                   if (!fEntityScanner.skipChar('>')) {
 1116                                       reportFatalError("DoctypedeclUnterminated", new Object[]{fDoctypeName});
 1117                                   }
 1118                                   fMarkupDepth--;
 1119   
 1120                                   // scan external subset next
 1121                                   if (!XMLDocumentScannerImpl.this.fDisallowDoctype &&
 1122                                           fDoctypeSystemId != null && (fValidation || fLoadExternalDTD)) {
 1123                                       setScannerState(SCANNER_STATE_DTD_EXTERNAL);
 1124                                   }
 1125   
 1126                                   // break out of here
 1127                                   else {
 1128                                       setScannerState(SCANNER_STATE_PROLOG);
 1129                                       setDriver(fPrologDriver);
 1130                                       fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
 1131                                       return true;
 1132                                   }
 1133                               }
 1134                               break;
 1135                           }
 1136                           case SCANNER_STATE_DTD_EXTERNAL: {
 1137                               /**
 1138                               fDTDDescription.setValues(fDoctypePublicId, fDoctypeSystemId, null, null);
 1139                               fDTDDescription.setRootName(fDoctypeName);
 1140                               XMLInputSource xmlInputSource =
 1141                                   fEntityManager.resolveEntity(fDTDDescription);
 1142                               fDTDScanner.setInputSource(xmlInputSource);
 1143                               setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
 1144                               again = true;
 1145                               break;
 1146                                */
 1147   
 1148                               resourceIdentifier.setValues(fDoctypePublicId, fDoctypeSystemId, null, null);
 1149                               XMLInputSource xmlInputSource = null ;
 1150                               StaxXMLInputSource staxInputSource =  fEntityManager.resolveEntityAsPerStax(resourceIdentifier);
 1151                               xmlInputSource = staxInputSource.getXMLInputSource();
 1152                               fDTDScanner.setInputSource(xmlInputSource);
 1153                               setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
 1154                               again = true;
 1155                               break;
 1156                           }
 1157                           case SCANNER_STATE_DTD_EXTERNAL_DECLS: {
 1158                               // REVISIT: Should there be a feature for
 1159                               //          the "complete" parameter?
 1160                               boolean completeDTD = true;
 1161                               boolean moreToScan = fDTDScanner.scanDTDExternalSubset(completeDTD);
 1162                               if (!moreToScan) {
 1163                                   setScannerState(SCANNER_STATE_PROLOG);
 1164                                   setDriver(fPrologDriver);
 1165                                   fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
 1166                                   return true;
 1167                               }
 1168                               break;
 1169                           }
 1170                           default: {
 1171                               throw new XNIException("DTDDriver#dispatch: scanner state="+fScannerState+" ("+getScannerStateName(fScannerState)+')');
 1172                           }
 1173                       }
 1174                   } while (complete || again);
 1175               }
 1176   
 1177               // premature end of file
 1178               catch (EOFException e) {
 1179                   e.printStackTrace();
 1180                   reportFatalError("PrematureEOF", null);
 1181                   return false;
 1182                   //throw e;
 1183               }
 1184   
 1185               // cleanup
 1186               finally {
 1187                   fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
 1188               }
 1189   
 1190               return true;
 1191   
 1192           }
 1193   
 1194           // dispatch(boolean):boolean
 1195   
 1196       } // class DTDDriver
 1197   
 1198       /**
 1199        * Driver to handle content scanning.
 1200        *
 1201        * @author Andy Clark, IBM
 1202        * @author Eric Ye, IBM
 1203        */
 1204       protected class ContentDriver
 1205               extends FragmentContentDriver {
 1206   
 1207           //
 1208           // Protected methods
 1209           //
 1210   
 1211           // hooks
 1212   
 1213           // NOTE: These hook methods are added so that the full document
 1214           //       scanner can share the majority of code with this class.
 1215   
 1216           /**
 1217            * Scan for DOCTYPE hook. This method is a hook for subclasses
 1218            * to add code to handle scanning for a the "DOCTYPE" string
 1219            * after the string "<!" has been scanned.
 1220            *
 1221            * @return True if the "DOCTYPE" was scanned; false if "DOCTYPE"
 1222            *          was not scanned.
 1223            */
 1224           protected boolean scanForDoctypeHook()
 1225           throws IOException, XNIException {
 1226   
 1227               if (fEntityScanner.skipString(DOCTYPE)) {
 1228                   setScannerState(SCANNER_STATE_DOCTYPE);
 1229                   //                fEntityScanner.markStartOfDTD();
 1230                   return true;
 1231               }
 1232               return false;
 1233   
 1234           } // scanForDoctypeHook():boolean
 1235   
 1236           /**
 1237            * Element depth iz zero. This methos is a hook for subclasses
 1238            * to add code to handle when the element depth hits zero. When
 1239            * scanning a document fragment, an element depth of zero is
 1240            * normal. However, when scanning a full XML document, the
 1241            * scanner must handle the trailing miscellanous section of
 1242            * the document after the end of the document's root element.
 1243            *
 1244            * @return True if the caller should stop and return true which
 1245            *          allows the scanner to switch to a new scanning
 1246            *          driver. A return value of false indicates that
 1247            *          the content driver should continue as normal.
 1248            */
 1249           protected boolean elementDepthIsZeroHook()
 1250           throws IOException, XNIException {
 1251   
 1252               setScannerState(SCANNER_STATE_TRAILING_MISC);
 1253               setDriver(fTrailingMiscDriver);
 1254               return true;
 1255   
 1256           } // elementDepthIsZeroHook():boolean
 1257   
 1258           /**
 1259            * Scan for root element hook. This method is a hook for
 1260            * subclasses to add code that handles scanning for the root
 1261            * element. When scanning a document fragment, there is no
 1262            * "root" element. However, when scanning a full XML document,
 1263            * the scanner must handle the root element specially.
 1264            *
 1265            * @return True if the caller should stop and return true which
 1266            *          allows the scanner to switch to a new scanning
 1267            *          driver. A return value of false indicates that
 1268            *          the content driver should continue as normal.
 1269            */
 1270           protected boolean scanRootElementHook()
 1271           throws IOException, XNIException {
 1272   
 1273               if (scanStartElement()) {
 1274                   setScannerState(SCANNER_STATE_TRAILING_MISC);
 1275                   setDriver(fTrailingMiscDriver);
 1276                   return true;
 1277               }
 1278               return false;
 1279   
 1280           } // scanRootElementHook():boolean
 1281   
 1282           /**
 1283            * End of file hook. This method is a hook for subclasses to
 1284            * add code that handles the end of file. The end of file in
 1285            * a document fragment is OK if the markup depth is zero.
 1286            * However, when scanning a full XML document, an end of file
 1287            * is always premature.
 1288            */
 1289           protected void endOfFileHook(EOFException e)
 1290           throws IOException, XNIException {
 1291   
 1292               reportFatalError("PrematureEOF", null);
 1293               // in case continue-after-fatal-error set, should not do this...
 1294               //throw e;
 1295   
 1296           } // endOfFileHook()
 1297   
 1298           protected void resolveExternalSubsetAndRead()
 1299           throws IOException, XNIException {
 1300   
 1301               fDTDDescription.setValues(null, null, fEntityManager.getCurrentResourceIdentifier().getExpandedSystemId(), null);
 1302               fDTDDescription.setRootName(fElementQName.rawname);
 1303               XMLInputSource src = fExternalSubsetResolver.getExternalSubset(fDTDDescription);
 1304   
 1305               if (src != null) {
 1306                   fDoctypeName = fElementQName.rawname;
 1307                   fDoctypePublicId = src.getPublicId();
 1308                   fDoctypeSystemId = src.getSystemId();
 1309                   // call document handler
 1310                   if (fDocumentHandler != null) {
 1311                       // This inserts a doctypeDecl event into the stream though no
 1312                       // DOCTYPE existed in the instance document.
 1313                       fDocumentHandler.doctypeDecl(fDoctypeName, fDoctypePublicId, fDoctypeSystemId, null);
 1314                   }
 1315                   try {
 1316                       fDTDScanner.setInputSource(src);
 1317                       while (fDTDScanner.scanDTDExternalSubset(true));
 1318                   } finally {
 1319                       fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
 1320                   }
 1321               }
 1322           } // resolveExternalSubsetAndRead()
 1323   
 1324   
 1325   
 1326       } // class ContentDriver
 1327   
 1328       /**
 1329        * Driver to handle trailing miscellaneous section scanning.
 1330        *
 1331        * @author Andy Clark, IBM
 1332        * @author Eric Ye, IBM
 1333        */
 1334       protected final class TrailingMiscDriver
 1335               implements Driver {
 1336   
 1337           //
 1338           // Driver methods
 1339           //
 1340           public int next() throws IOException, XNIException{
 1341               //this could for cases like <foo/>
 1342               //look at scanRootElementHook
 1343               if(fEmptyElement){
 1344                   fEmptyElement = false;
 1345                   return XMLEvent.END_ELEMENT;
 1346               }
 1347   
 1348               try {
 1349                   if(fScannerState == SCANNER_STATE_TERMINATED){
 1350                       return XMLEvent.END_DOCUMENT ;}
 1351                   do {
 1352                       switch (fScannerState) {
 1353                           case SCANNER_STATE_TRAILING_MISC: {
 1354   
 1355                               fEntityScanner.skipSpaces();
 1356                               //we should have reached the end of the document in
 1357                               //most cases.
 1358                               if(fScannerState == SCANNER_STATE_TERMINATED ){
 1359                                   return XMLEvent.END_DOCUMENT ;
 1360                               }
 1361                               if (fEntityScanner.skipChar('<')) {
 1362                                   setScannerState(SCANNER_STATE_START_OF_MARKUP);
 1363                               } else {
 1364                                   setScannerState(SCANNER_STATE_CONTENT);
 1365                               }
 1366                               break;
 1367                           }
 1368                           case SCANNER_STATE_START_OF_MARKUP: {
 1369                               fMarkupDepth++;
 1370                               if (fEntityScanner.skipChar('?')) {
 1371                                   setScannerState(SCANNER_STATE_PI);
 1372                               } else if (fEntityScanner.skipChar('!')) {
 1373                                   setScannerState(SCANNER_STATE_COMMENT);
 1374                               } else if (fEntityScanner.skipChar('/')) {
 1375                                   reportFatalError("MarkupNotRecognizedInMisc",
 1376                                           null);
 1377                               } else if (XMLChar.isNameStart(fEntityScanner.peekChar())) {
 1378                                   reportFatalError("MarkupNotRecognizedInMisc",
 1379                                           null);
 1380                                   scanStartElement();
 1381                                   setScannerState(SCANNER_STATE_CONTENT);
 1382                               } else {
 1383                                   reportFatalError("MarkupNotRecognizedInMisc",
 1384                                           null);
 1385                               }
 1386                               break;
 1387                           }
 1388                       }
 1389                   }while(fScannerState == SCANNER_STATE_START_OF_MARKUP || fScannerState == SCANNER_STATE_TRAILING_MISC);
 1390                   if(DEBUG_NEXT){
 1391                       System.out.println("State set by deciding while loop [TrailingMiscellaneous] is = " + getScannerStateName(fScannerState));
 1392                   }
 1393                   switch (fScannerState){
 1394                       case SCANNER_STATE_PI: {
 1395                           fContentBuffer.clear();
 1396                           scanPI(fContentBuffer);
 1397                           setScannerState(SCANNER_STATE_TRAILING_MISC);
 1398                           return XMLEvent.PROCESSING_INSTRUCTION ;
 1399                       }
 1400                       case SCANNER_STATE_COMMENT: {
 1401                           if (!fEntityScanner.skipString(COMMENTSTRING)) {
 1402                               reportFatalError("InvalidCommentStart", null);
 1403                           }
 1404                           scanComment();
 1405                           setScannerState(SCANNER_STATE_TRAILING_MISC);
 1406                           return XMLEvent.COMMENT;
 1407                       }
 1408                       case SCANNER_STATE_CONTENT: {
 1409                           int ch = fEntityScanner.peekChar();
 1410                           if (ch == -1) {
 1411                               setScannerState(SCANNER_STATE_TERMINATED);
 1412                               return XMLEvent.END_DOCUMENT ;
 1413                           } else{
 1414                               reportFatalError("ContentIllegalInTrailingMisc",
 1415                                       null);
 1416                               fEntityScanner.scanChar();
 1417                               setScannerState(SCANNER_STATE_TRAILING_MISC);
 1418                               return XMLEvent.CHARACTERS;
 1419                           }
 1420   
 1421                       }
 1422                       case SCANNER_STATE_REFERENCE: {
 1423                           reportFatalError("ReferenceIllegalInTrailingMisc",
 1424                                   null);
 1425                           setScannerState(SCANNER_STATE_TRAILING_MISC);
 1426                           return XMLEvent.ENTITY_REFERENCE ;
 1427                       }
 1428                       case SCANNER_STATE_TERMINATED: {
 1429                           //there can't be any element after SCANNER_STATE_TERMINATED or when the parser
 1430                           //has reached the end of document
 1431                           setScannerState(SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION);
 1432                           //xxx what to do when the scanner has reached the terminating state.
 1433                           return XMLEvent.END_DOCUMENT ;
 1434                       }
 1435                       case SCANNER_STATE_NO_SUCH_ELEMENT_EXCEPTION:{
 1436                           throw new java.util.NoSuchElementException("No more events to be parsed");
 1437                       }
 1438                       default: throw new XNIException("Scanner State " + fScannerState + " not Recognized ");
 1439                   }//switch
 1440   
 1441               } catch (EOFException e) {
 1442                   // NOTE: This is the only place we're allowed to reach
 1443                   //       the real end of the document stream. Unless the
 1444                   //       end of file was reached prematurely.
 1445                   if (fMarkupDepth != 0) {
 1446                       reportFatalError("PrematureEOF", null);
 1447                       return -1;
 1448                       //throw e;
 1449                   }
 1450                   System.out.println("EOFException thrown") ;
 1451                   setScannerState(SCANNER_STATE_TERMINATED);
 1452               }
 1453   
 1454               return XMLEvent.END_DOCUMENT;
 1455   
 1456           }//next
 1457   
 1458       } // class TrailingMiscDriver
 1459   
 1460       /**
 1461        * Implements XMLBufferListener interface.
 1462        */
 1463   
 1464   
 1465       /**
 1466        * receives callbacks from {@link XMLEntityReader } when buffer
 1467        * is being changed.
 1468        * @param refreshPosition
 1469        */
 1470       public void refresh(int refreshPosition){
 1471           super.refresh(refreshPosition);
 1472           if(fReadingDTD){
 1473               Entity entity = fEntityScanner.getCurrentEntity();
 1474               if(entity instanceof Entity.ScannedEntity){
 1475                   fEndPos=((Entity.ScannedEntity)entity).position;
 1476               }
 1477               fDTDDecl.append(((Entity.ScannedEntity)entity).ch,fStartPos , fEndPos-fStartPos);
 1478               fStartPos = refreshPosition;
 1479           }
 1480       }
 1481   
 1482   } // class XMLDocumentScannerImpl

Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » impl » [javadoc | source]