Home » Xerces-J-src.2.9.1 » org.apache.xerces » parsers » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.xerces.parsers;
   19   
   20   import java.io.IOException;
   21   import java.util.ArrayList;
   22   import java.util.HashMap;
   23   import java.util.Locale;
   24   
   25   import org.apache.xerces.impl.Constants;
   26   import org.apache.xerces.util.ParserConfigurationSettings;
   27   import org.apache.xerces.util.SymbolTable;
   28   import org.apache.xerces.xni.XMLDTDContentModelHandler;
   29   import org.apache.xerces.xni.XMLDTDHandler;
   30   import org.apache.xerces.xni.XMLDocumentHandler;
   31   import org.apache.xerces.xni.XNIException;
   32   import org.apache.xerces.xni.parser.XMLComponent;
   33   import org.apache.xerces.xni.parser.XMLComponentManager;
   34   import org.apache.xerces.xni.parser.XMLConfigurationException;
   35   import org.apache.xerces.xni.parser.XMLDocumentSource;
   36   import org.apache.xerces.xni.parser.XMLEntityResolver;
   37   import org.apache.xerces.xni.parser.XMLErrorHandler;
   38   import org.apache.xerces.xni.parser.XMLInputSource;
   39   import org.apache.xerces.xni.parser.XMLParserConfiguration;
   40   
   41   /**
   42    * A very basic parser configuration. This configuration class can
   43    * be used as a base class for custom parser configurations. The
   44    * basic parser configuration creates the symbol table (if not
   45    * specified at construction time) and manages all of the recognized
   46    * features and properties.
   47    * <p>
   48    * The basic parser configuration does <strong>not</strong> mandate
   49    * any particular pipeline configuration or the use of specific 
   50    * components except for the symbol table. If even this is too much
   51    * for a basic parser configuration, the programmer can create a new
   52    * configuration class that implements the 
   53    * <code>XMLParserConfiguration</code> interface.
   54    * <p>
   55    * Subclasses of the basic parser configuration can add their own
   56    * recognized features and properties by calling the
   57    * <code>addRecognizedFeature</code> and 
   58    * <code>addRecognizedProperty</code> methods, respectively.
   59    * <p>
   60    * The basic parser configuration assumes that the configuration
   61    * will be made up of various parser components that implement the
   62    * <code>XMLComponent</code> interface. If subclasses of this
   63    * configuration create their own components for use in the 
   64    * parser configuration, then each component should be added to
   65    * the list of components by calling the <code>addComponent</code>
   66    * method. The basic parser configuration will make sure to call
   67    * the <code>reset</code> method of each registered component
   68    * before parsing an instance document.
   69    * <p>
   70    * This class recognizes the following features and properties:
   71    * <ul>
   72    * <li>Features
   73    *  <ul>
   74    *   <li>http://xml.org/sax/features/validation</li>
   75    *   <li>http://xml.org/sax/features/namespaces</li>
   76    *   <li>http://xml.org/sax/features/external-general-entities</li>
   77    *   <li>http://xml.org/sax/features/external-parameter-entities</li>
   78    *  </ul>
   79    * <li>Properties
   80    *  <ul>
   81    *   <li>http://xml.org/sax/properties/xml-string</li>
   82    *   <li>http://apache.org/xml/properties/internal/symbol-table</li>
   83    *   <li>http://apache.org/xml/properties/internal/error-handler</li>
   84    *   <li>http://apache.org/xml/properties/internal/entity-resolver</li>
   85    *  </ul>
   86    * </ul>
   87    *
   88    * @author Arnaud  Le Hors, IBM
   89    * @author Andy Clark, IBM
   90    *
   91    * @version $Id: BasicParserConfiguration.java 447239 2006-09-18 05:08:26Z mrglavas $
   92    */
   93   public abstract class BasicParserConfiguration
   94       extends ParserConfigurationSettings
   95       implements XMLParserConfiguration {
   96   
   97       //
   98       // Constants
   99       //
  100   
  101       // feature identifiers
  102   
  103       /** Feature identifier: validation. */
  104       protected static final String VALIDATION =
  105           Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
  106       
  107       /** Feature identifier: namespaces. */
  108       protected static final String NAMESPACES =
  109           Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
  110       
  111       /** Feature identifier: external general entities. */
  112       protected static final String EXTERNAL_GENERAL_ENTITIES =
  113           Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE;
  114       
  115       /** Feature identifier: external parameter entities. */
  116       protected static final String EXTERNAL_PARAMETER_ENTITIES =
  117           Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE;
  118       
  119       // property identifiers
  120   
  121       /** Property identifier: xml string. */
  122       protected static final String XML_STRING = 
  123           Constants.SAX_PROPERTY_PREFIX + Constants.XML_STRING_PROPERTY;
  124   
  125       /** Property identifier: symbol table. */
  126       protected static final String SYMBOL_TABLE = 
  127           Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  128   
  129       /** Property identifier: error handler. */
  130       protected static final String ERROR_HANDLER = 
  131           Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
  132   
  133       /** Property identifier: entity resolver. */
  134       protected static final String ENTITY_RESOLVER = 
  135           Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
  136   
  137       //
  138       // Data
  139       //
  140   
  141       // components (non-configurable)
  142   
  143       /** Symbol table. */
  144       protected SymbolTable fSymbolTable;
  145   
  146   
  147       // data
  148   
  149       /** Locale. */
  150       protected Locale fLocale;
  151   
  152       /** Components. */
  153       protected ArrayList fComponents;
  154   
  155       // handlers
  156   
  157       /** The document handler. */
  158       protected XMLDocumentHandler fDocumentHandler;
  159   
  160       /** The DTD handler. */
  161       protected XMLDTDHandler fDTDHandler;
  162   
  163       /** The DTD content model handler. */
  164       protected XMLDTDContentModelHandler fDTDContentModelHandler;
  165   
  166       /** Last component in the document pipeline */     
  167       protected XMLDocumentSource fLastComponent;
  168   
  169       //
  170       // Constructors
  171       //
  172   
  173       /** Default Constructor. */
  174       protected BasicParserConfiguration() {
  175           this(null, null);
  176       } // <init>()
  177   
  178       /** 
  179        * Constructs a parser configuration using the specified symbol table. 
  180        *
  181        * @param symbolTable The symbol table to use.
  182        */
  183       protected BasicParserConfiguration(SymbolTable symbolTable) {
  184           this(symbolTable, null);
  185       } // <init>(SymbolTable)
  186   
  187       /** 
  188        * Constructs a parser configuration using the specified symbol table
  189        * and parent settings.
  190        *
  191        * @param symbolTable    The symbol table to use.
  192        * @param parentSettings The parent settings.
  193        */
  194       protected BasicParserConfiguration(SymbolTable symbolTable,
  195                                          XMLComponentManager parentSettings) {
  196           super(parentSettings);
  197   
  198           // create a vector to hold all the components in use
  199           fComponents = new ArrayList();
  200   
  201           // create storage for recognized features and properties
  202           fRecognizedFeatures = new ArrayList();
  203           fRecognizedProperties = new ArrayList();
  204   
  205           // create table for features and properties
  206           fFeatures = new HashMap();
  207           fProperties = new HashMap();
  208   
  209           // add default recognized features
  210           final String[] recognizedFeatures = {
  211           	PARSER_SETTINGS,
  212               VALIDATION,                 
  213               NAMESPACES, 
  214               EXTERNAL_GENERAL_ENTITIES,  
  215               EXTERNAL_PARAMETER_ENTITIES,
  216           };
  217           addRecognizedFeatures(recognizedFeatures);
  218           fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
  219           // set state for default features
  220   		fFeatures.put(VALIDATION, Boolean.FALSE);
  221   		fFeatures.put(NAMESPACES, Boolean.TRUE);
  222   		fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE);
  223   		fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE);
  224   
  225           // add default recognized properties
  226           final String[] recognizedProperties = {
  227               XML_STRING,     
  228               SYMBOL_TABLE,
  229               ERROR_HANDLER,  
  230               ENTITY_RESOLVER,
  231           };
  232           addRecognizedProperties(recognizedProperties);
  233   
  234           if (symbolTable == null) {
  235               symbolTable = new SymbolTable();
  236           }
  237           fSymbolTable = symbolTable;
  238           fProperties.put(SYMBOL_TABLE, fSymbolTable);
  239   
  240       } // <init>(SymbolTable)
  241   
  242       /** 
  243        * Adds a component to the parser configuration. This method will
  244        * also add all of the component's recognized features and properties
  245        * to the list of default recognized features and properties.
  246        *
  247        * @param component The component to add.
  248        */
  249       protected void addComponent(XMLComponent component) {
  250   
  251           // don't add a component more than once
  252           if (fComponents.contains(component)) {
  253               return;
  254           }
  255           fComponents.add(component);
  256   
  257           // register component's recognized features
  258           String[] recognizedFeatures = component.getRecognizedFeatures();
  259           addRecognizedFeatures(recognizedFeatures);
  260           
  261           // register component's recognized properties
  262           String[] recognizedProperties = component.getRecognizedProperties();
  263           addRecognizedProperties(recognizedProperties);
  264   
  265           // set default values
  266           if (recognizedFeatures != null) {
  267               for (int i = 0; i < recognizedFeatures.length; i++) {
  268                   String featureId = recognizedFeatures[i];
  269                   Boolean state = component.getFeatureDefault(featureId);
  270                   if (state != null) {
  271                       super.setFeature(featureId, state.booleanValue());
  272                   }
  273               }
  274           }
  275           if (recognizedProperties != null) {
  276               for (int i = 0; i < recognizedProperties.length; i++) {
  277                   String propertyId = recognizedProperties[i];
  278                   Object value = component.getPropertyDefault(propertyId);
  279                   if (value != null) {
  280                       super.setProperty(propertyId, value);
  281                   }
  282               }
  283           }
  284   
  285       } // addComponent(XMLComponent)
  286   
  287       //
  288       // XMLParserConfiguration methods
  289       //
  290   
  291       /**
  292        * Parse an XML document.
  293        * <p>
  294        * The parser can use this method to instruct this configuration
  295        * to begin parsing an XML document from any valid input source
  296        * (a character stream, a byte stream, or a URI).
  297        * <p>
  298        * Parsers may not invoke this method while a parse is in progress.
  299        * Once a parse is complete, the parser may then parse another XML
  300        * document.
  301        * <p>
  302        * This method is synchronous: it will not return until parsing
  303        * has ended.  If a client application wants to terminate 
  304        * parsing early, it should throw an exception.
  305        *
  306        * @param inputSource The input source for the top-level of the
  307        *               XML document.
  308        *
  309        * @exception XNIException Any XNI exception, possibly wrapping 
  310        *                         another exception.
  311        * @exception IOException  An IO exception from the parser, possibly
  312        *                         from a byte stream or character stream
  313        *                         supplied by the parser.
  314        */
  315       public abstract void parse(XMLInputSource inputSource) 
  316           throws XNIException, IOException;
  317   
  318       /**
  319        * Sets the document handler on the last component in the pipeline
  320        * to receive information about the document.
  321        * 
  322        * @param documentHandler   The document handler.
  323        */
  324       public void setDocumentHandler(XMLDocumentHandler documentHandler) {
  325           fDocumentHandler = documentHandler;
  326           if (fLastComponent != null) {
  327               fLastComponent.setDocumentHandler(fDocumentHandler);
  328               if (fDocumentHandler !=null){
  329                   fDocumentHandler.setDocumentSource(fLastComponent);
  330               }
  331           }
  332       } // setDocumentHandler(XMLDocumentHandler)
  333   
  334       /** Returns the registered document handler. */
  335       public XMLDocumentHandler getDocumentHandler() {
  336           return fDocumentHandler;
  337       } // getDocumentHandler():XMLDocumentHandler
  338   
  339       /**
  340        * Sets the DTD handler.
  341        * 
  342        * @param dtdHandler The DTD handler.
  343        */
  344       public void setDTDHandler(XMLDTDHandler dtdHandler) {
  345           fDTDHandler = dtdHandler;
  346       } // setDTDHandler(XMLDTDHandler)
  347   
  348       /** Returns the registered DTD handler. */
  349       public XMLDTDHandler getDTDHandler() {
  350           return fDTDHandler;
  351       } // getDTDHandler():XMLDTDHandler
  352   
  353       /**
  354        * Sets the DTD content model handler.
  355        * 
  356        * @param handler The DTD content model handler.
  357        */
  358       public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
  359           fDTDContentModelHandler = handler;
  360       } // setDTDContentModelHandler(XMLDTDContentModelHandler)
  361   
  362       /** Returns the registered DTD content model handler. */
  363       public XMLDTDContentModelHandler getDTDContentModelHandler() {
  364           return fDTDContentModelHandler;
  365       } // getDTDContentModelHandler():XMLDTDContentModelHandler
  366   
  367       /**
  368        * Sets the resolver used to resolve external entities. The EntityResolver
  369        * interface supports resolution of public and system identifiers.
  370        *
  371        * @param resolver The new entity resolver. Passing a null value will
  372        *                 uninstall the currently installed resolver.
  373        */
  374       public void setEntityResolver(XMLEntityResolver resolver) {
  375           // REVISIT: Should this be a property?
  376           fProperties.put(ENTITY_RESOLVER, resolver);
  377       } // setEntityResolver(XMLEntityResolver)
  378   
  379       /**
  380        * Return the current entity resolver.
  381        *
  382        * @return The current entity resolver, or null if none
  383        *         has been registered.
  384        * @see #setEntityResolver
  385        */
  386       public XMLEntityResolver getEntityResolver() {
  387           // REVISIT: Should this be a property?
  388           return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER);
  389       } // getEntityResolver():XMLEntityResolver
  390   
  391       /**
  392        * Allow an application to register an error event handler.
  393        *
  394        * <p>If the application does not register an error handler, all
  395        * error events reported by the SAX parser will be silently
  396        * ignored; however, normal processing may not continue.  It is
  397        * highly recommended that all SAX applications implement an
  398        * error handler to avoid unexpected bugs.</p>
  399        *
  400        * <p>Applications may register a new or different handler in the
  401        * middle of a parse, and the SAX parser must begin using the new
  402        * handler immediately.</p>
  403        *
  404        * @param errorHandler The error handler.
  405        * @exception java.lang.NullPointerException If the handler 
  406        *            argument is null.
  407        * @see #getErrorHandler
  408        */
  409       public void setErrorHandler(XMLErrorHandler errorHandler) {
  410           // REVISIT: Should this be a property?
  411           fProperties.put(ERROR_HANDLER, errorHandler);
  412       } // setErrorHandler(XMLErrorHandler)
  413   
  414       /**
  415        * Return the current error handler.
  416        *
  417        * @return The current error handler, or null if none
  418        *         has been registered.
  419        * @see #setErrorHandler
  420        */
  421       public XMLErrorHandler getErrorHandler() {
  422           // REVISIT: Should this be a property?
  423           return (XMLErrorHandler)fProperties.get(ERROR_HANDLER);
  424       } // getErrorHandler():XMLErrorHandler
  425   
  426       /**
  427        * Set the state of a feature.
  428        *
  429        * Set the state of any feature in a SAX2 parser.  The parser
  430        * might not recognize the feature, and if it does recognize
  431        * it, it might not be able to fulfill the request.
  432        *
  433        * @param featureId The unique identifier (URI) of the feature.
  434        * @param state The requested state of the feature (true or false).
  435        *
  436        * @exception org.apache.xerces.xni.parser.XMLConfigurationException If the
  437        *            requested feature is not known.
  438        */
  439       public void setFeature(String featureId, boolean state)
  440           throws XMLConfigurationException {
  441   
  442           // forward to every component
  443           int count = fComponents.size();
  444           for (int i = 0; i < count; i++) {
  445               XMLComponent c = (XMLComponent) fComponents.get(i);
  446               c.setFeature(featureId, state);
  447           }
  448           // save state if noone "objects"
  449           super.setFeature(featureId, state);
  450   
  451       } // setFeature(String,boolean)
  452   
  453       /**
  454        * setProperty
  455        * 
  456        * @param propertyId 
  457        * @param value 
  458        */
  459       public void setProperty(String propertyId, Object value)
  460           throws XMLConfigurationException {
  461   
  462           // forward to every component
  463           int count = fComponents.size();
  464           for (int i = 0; i < count; i++) {
  465               XMLComponent c = (XMLComponent) fComponents.get(i);
  466               c.setProperty(propertyId, value);
  467           }
  468   
  469           // store value if noone "objects"
  470           super.setProperty(propertyId, value);
  471   
  472       } // setProperty(String,Object)
  473   
  474       /**
  475        * Set the locale to use for messages.
  476        *
  477        * @param locale The locale object to use for localization of messages.
  478        *
  479        * @exception XNIException Thrown if the parser does not support the
  480        *                         specified locale.
  481        */
  482       public void setLocale(Locale locale) throws XNIException {
  483           fLocale = locale;
  484       } // setLocale(Locale)
  485   
  486       /** Returns the locale. */
  487       public Locale getLocale() {
  488           return fLocale;
  489       } // getLocale():Locale
  490   
  491       //
  492       // Protected methods
  493       //
  494   
  495       /**
  496        * reset all components before parsing and namespace context
  497        */
  498       protected void reset() throws XNIException {
  499   
  500           // reset every component
  501           int count = fComponents.size();
  502           for (int i = 0; i < count; i++) {
  503               XMLComponent c = (XMLComponent) fComponents.get(i);
  504               c.reset(this);
  505           }
  506   
  507       } // reset()
  508   
  509       /**
  510        * Check a property. If the property is known and supported, this method
  511        * simply returns. Otherwise, the appropriate exception is thrown.
  512        *
  513        * @param propertyId The unique identifier (URI) of the property
  514        *                   being set.
  515        * @exception org.apache.xerces.xni.parser.XMLConfigurationException If the
  516        *            requested feature is not known or supported.
  517        */
  518       protected void checkProperty(String propertyId)
  519           throws XMLConfigurationException {
  520   
  521           // special cases
  522           if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
  523               final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();	
  524           	
  525               //
  526               // http://xml.org/sax/properties/xml-string
  527               // Value type: String
  528               // Access: read-only
  529               //   Get the literal string of characters associated with the
  530               //   current event.  If the parser recognises and supports this
  531               //   property but is not currently parsing text, it should return
  532               //   null (this is a good way to check for availability before the
  533               //   parse begins).
  534               //
  535               if (suffixLength == Constants.XML_STRING_PROPERTY.length() && 
  536                   propertyId.endsWith(Constants.XML_STRING_PROPERTY)) {
  537                   // REVISIT - we should probably ask xml-dev for a precise
  538                   // definition of what this is actually supposed to return, and
  539                   // in exactly which circumstances.
  540                   short type = XMLConfigurationException.NOT_SUPPORTED;
  541                   throw new XMLConfigurationException(type, propertyId);
  542               }
  543           }
  544   
  545           // check property
  546           super.checkProperty(propertyId);
  547   
  548       } // checkProperty(String)
  549       
  550       
  551       /**
  552        * Check a feature. If feature is know and supported, this method simply
  553        * returns. Otherwise, the appropriate exception is thrown.
  554        *
  555        * @param featureId The unique identifier (URI) of the feature.
  556        *
  557        * @throws XMLConfigurationException Thrown for configuration error.
  558        *                                   In general, components should
  559        *                                   only throw this exception if
  560        *                                   it is <strong>really</strong>
  561        *                                   a critical error.
  562        */
  563       protected void checkFeature(String featureId)
  564           throws XMLConfigurationException {
  565   
  566           //
  567           // Xerces Features
  568           //
  569           if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
  570               final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
  571   
  572               //
  573               // special performance feature: no one by component manager is allowed to set it
  574               //
  575               if (suffixLength == Constants.PARSER_SETTINGS.length() && 
  576                   featureId.endsWith(Constants.PARSER_SETTINGS)) {
  577                   short type = XMLConfigurationException.NOT_SUPPORTED;
  578                   throw new XMLConfigurationException(type, featureId);
  579               }
  580           }
  581   
  582           super.checkFeature(featureId);
  583   
  584        } // checkFeature(String)
  585   
  586   
  587   } // class BasicParserConfiguration

Home » Xerces-J-src.2.9.1 » org.apache.xerces » parsers » [javadoc | source]