Home » Xerces-J-src.2.9.1 » xni » parser » [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 xni.parser;
   19   
   20   import java.io.FileInputStream;
   21   import java.io.InputStream;
   22   import java.io.IOException;
   23   import java.net.MalformedURLException;
   24   import java.net.URL;
   25   import java.util.Hashtable;
   26   import java.util.Locale;
   27   import java.util.Vector;
   28   
   29   import org.apache.xerces.xni.XMLDocumentHandler;
   30   import org.apache.xerces.xni.XMLDTDHandler;
   31   import org.apache.xerces.xni.XMLDTDContentModelHandler;
   32   import org.apache.xerces.xni.XNIException;
   33   
   34   import org.apache.xerces.xni.parser.XMLComponent;
   35   import org.apache.xerces.xni.parser.XMLConfigurationException;
   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    * This abstract parser configuration simply helps manage components, 
   43    * features and properties, and other tasks common to all parser
   44    * configurations. In order to subclass this configuration and use
   45    * it effectively, the subclass is required to do the following:
   46    * <ul>
   47    * <li>
   48    *  Add all configurable components using the <code>addComponent</code>
   49    *  method,</li>
   50    * <li>Implement the <code>parse</code> method, and</li>
   51    * <li>Call the <code>resetComponents</code> before parsing.</li>
   52    * </ul>
   53    *
   54    * @author Andy Clark, IBM
   55    *
   56    * @version $Id: AbstractConfiguration.java 447690 2006-09-19 02:41:53Z mrglavas $
   57    */
   58   public abstract class AbstractConfiguration 
   59       implements XMLParserConfiguration {
   60   
   61       //
   62       // Data
   63       //
   64   
   65       // features and properties
   66   
   67       /** Recognized features. */
   68       protected final Vector fRecognizedFeatures = new Vector();
   69   
   70       /** Recognized properties. */
   71       protected final Vector fRecognizedProperties = new Vector();
   72   
   73       /** Features. */
   74       protected final Hashtable fFeatures = new Hashtable();
   75   
   76       /** Properties. */
   77       protected final Hashtable fProperties = new Hashtable();
   78   
   79       // other parser configuration fields
   80   
   81       /** The registered entity resolver. */
   82       protected XMLEntityResolver fEntityResolver;
   83   
   84       /** The registered error handler. */
   85       protected XMLErrorHandler fErrorHandler;
   86   
   87       /** The registered document handler. */
   88       protected XMLDocumentHandler fDocumentHandler;
   89   
   90       /** The registered DTD handler. */
   91       protected XMLDTDHandler fDTDHandler;
   92   
   93       /** The registered DTD content model handler. */
   94       protected XMLDTDContentModelHandler fDTDContentModelHandler;
   95       
   96       /** Locale for error messages. */
   97       protected Locale fLocale;
   98   
   99       // components
  100   
  101       /** List of configurable components. */
  102       protected final Vector fComponents = new Vector();
  103   
  104       //
  105       // XMLParserConfiguration methods
  106       //
  107   
  108       /**
  109        * Allows a parser to add parser specific features to be recognized
  110        * and managed by the parser configuration.
  111        *
  112        * @param featureIds An array of the additional feature identifiers 
  113        *                   to be recognized.
  114        */
  115       public void addRecognizedFeatures(String[] featureIds) {
  116           int length = featureIds != null ? featureIds.length : 0;
  117           for (int i = 0; i < length; i++) {
  118               String featureId = featureIds[i];
  119               if (!fRecognizedFeatures.contains(featureId)) {
  120                   fRecognizedFeatures.addElement(featureId);
  121               }
  122           }
  123       } // addRecognizedFeatures(String[])
  124       
  125       /**
  126        * Sets the state of a feature. This method is called by the parser
  127        * and gets propagated to components in this parser configuration.
  128        * 
  129        * @param featureId The feature identifier.
  130        * @param state     The state of the feature.
  131        *
  132        * @throws XMLConfigurationException Thrown if there is a configuration
  133        *                                   error.
  134        */
  135       public void setFeature(String featureId, boolean state)
  136           throws XMLConfigurationException {
  137           if (!fRecognizedFeatures.contains(featureId)) {
  138               short type = XMLConfigurationException.NOT_RECOGNIZED;
  139               throw new XMLConfigurationException(type, featureId);
  140           }
  141           fFeatures.put(featureId, state ? Boolean.TRUE : Boolean.FALSE);
  142           int length = fComponents.size();
  143           for (int i = 0; i < length; i++) {
  144               XMLComponent component = (XMLComponent)fComponents.elementAt(i);
  145               component.setFeature(featureId, state);
  146           }
  147       } // setFeature(String,boolean)
  148   
  149       /**
  150        * Returns the state of a feature.
  151        * 
  152        * @param featureId The feature identifier.
  153        * 
  154        * @throws XMLConfigurationException Thrown if there is a configuration
  155        *                                   error.
  156        */
  157       public boolean getFeature(String featureId) 
  158           throws XMLConfigurationException {
  159           if (!fRecognizedFeatures.contains(featureId)) {
  160               short type = XMLConfigurationException.NOT_RECOGNIZED;
  161               throw new XMLConfigurationException(type, featureId);
  162           }
  163           Boolean state = (Boolean)fFeatures.get(featureId);
  164           return state != null ? state.booleanValue() : false;
  165       } // getFeature(String):boolean
  166       
  167       /**
  168        * Allows a parser to add parser specific properties to be recognized
  169        * and managed by the parser configuration.
  170        *
  171        * @param propertyIds An array of the additional property identifiers 
  172        *                    to be recognized.
  173        */
  174       public void addRecognizedProperties(String[] propertyIds) {
  175           int length = propertyIds != null ? propertyIds.length : 0;
  176           for (int i = 0; i < length; i++) {
  177               String propertyId = propertyIds[i];
  178               if (!fRecognizedProperties.contains(propertyId)) {
  179                   fRecognizedProperties.addElement(propertyId);
  180               }
  181           }
  182       } // addRecognizedProperties(String[])
  183   
  184       /**
  185        * Sets the value of a property. This method is called by the parser
  186        * and gets propagated to components in this parser configuration.
  187        * 
  188        * @param propertyId The property identifier.
  189        * @param value      The value of the property.
  190        *
  191        * @throws XMLConfigurationException Thrown if there is a configuration
  192        *                                   error.
  193        */
  194       public void setProperty(String propertyId, Object value) 
  195           throws XMLConfigurationException {
  196           if (!fRecognizedProperties.contains(propertyId)) {
  197               short type = XMLConfigurationException.NOT_RECOGNIZED;
  198               throw new XMLConfigurationException(type, propertyId);
  199           }
  200           if (value != null) {
  201               fProperties.put(propertyId, value);
  202           }
  203           else {
  204               fProperties.remove(propertyId);
  205           }
  206           int length = fComponents.size();
  207           for (int i = 0; i < length; i++) {
  208               XMLComponent component = (XMLComponent)fComponents.elementAt(i);
  209               component.setProperty(propertyId, value);
  210           }
  211       } // setProperty(String,Object)
  212   
  213       /**
  214        * Returns the value of a property.
  215        * 
  216        * @param propertyId The property identifier.
  217        * 
  218        * @throws XMLConfigurationException Thrown if there is a configuration
  219        *                                   error.
  220        */
  221       public Object getProperty(String propertyId) 
  222           throws XMLConfigurationException {
  223           if (!fRecognizedProperties.contains(propertyId)) {
  224               short type = XMLConfigurationException.NOT_RECOGNIZED;
  225               throw new XMLConfigurationException(type, propertyId);
  226           }
  227           Object value = fProperties.get(propertyId);
  228           return value;
  229       } // getProperty(String):Object
  230   
  231       /**
  232        * Sets the entity resolver.
  233        *
  234        * @param resolver The new entity resolver.
  235        */
  236       public void setEntityResolver(XMLEntityResolver resolver) {
  237           fEntityResolver = resolver;
  238       } // setEntityResolver(XMLEntityResolver)
  239   
  240       /** Returns the registered entity resolver. */
  241       public XMLEntityResolver getEntityResolver() {
  242           return fEntityResolver;
  243       } // getEntityResolver():XMLEntityResolver
  244   
  245       /**
  246        * Sets the error handler.
  247        *
  248        * @param handler The error resolver.
  249        */
  250       public void setErrorHandler(XMLErrorHandler handler) {
  251           fErrorHandler = handler;
  252       } // setErrorHandler(XMLErrorHandler)
  253   
  254       /** Returns the registered error handler. */
  255       public XMLErrorHandler getErrorHandler() {
  256           return fErrorHandler;
  257       } // getErrorHandler():XMLErrorHandler
  258   
  259       /**
  260        * Sets the document handler to receive information about the document.
  261        * 
  262        * @param handler The document handler.
  263        */
  264       public void setDocumentHandler(XMLDocumentHandler handler) {
  265           fDocumentHandler = handler;
  266       } // setDocumentHandler(XMLDocumentHandler)
  267   
  268       /** Returns the registered document handler. */
  269       public XMLDocumentHandler getDocumentHandler() {
  270           return fDocumentHandler;
  271       } // getDocumentHandler():XMLDocumentHandler
  272   
  273       /**
  274        * Sets the DTD handler.
  275        * 
  276        * @param handler The DTD handler.
  277        */
  278       public void setDTDHandler(XMLDTDHandler handler) {
  279           fDTDHandler = handler;
  280       } // setDTDHandler(XMLDTDHandler)
  281   
  282       /** Returns the registered DTD handler. */
  283       public XMLDTDHandler getDTDHandler() {
  284           return fDTDHandler;
  285       } // getDTDHandler():XMLDTDHandler
  286   
  287       /**
  288        * Sets the DTD content model handler.
  289        * 
  290        * @param handler The DTD content model handler.
  291        */
  292       public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
  293           fDTDContentModelHandler = handler;
  294       } // setDTDContentModelHandler(XMLDTDContentModelHandler)
  295   
  296       /** Returns the registered DTD content model handler. */
  297       public XMLDTDContentModelHandler getDTDContentModelHandler() {
  298           return fDTDContentModelHandler;
  299       } // getDTDContentModelHandler():XMLDTDContentModelHandler 
  300   
  301       /**
  302        * Parse an XML document.
  303        * <p>
  304        * The parser can use this method to instruct this configuration
  305        * to begin parsing an XML document from any valid input source
  306        * (a character stream, a byte stream, or a URI).
  307        * <p>
  308        * Parsers may not invoke this method while a parse is in progress.
  309        * Once a parse is complete, the parser may then parse another XML
  310        * document.
  311        * <p>
  312        * This method is synchronous: it will not return until parsing
  313        * has ended.  If a client application wants to terminate 
  314        * parsing early, it should throw an exception.
  315        * <p>
  316        * <strong>Note:</strong> This method needs to be implemented
  317        * by the subclass.
  318        *
  319        * @param source The input source for the top-level of the
  320        *               XML document.
  321        *
  322        * @exception XNIException Any XNI exception, possibly wrapping 
  323        *                         another exception.
  324        * @exception IOException  An IO exception from the parser, possibly
  325        *                         from a byte stream or character stream
  326        *                         supplied by the parser.
  327        */
  328       public abstract void parse(XMLInputSource inputSource) 
  329           throws IOException, XNIException;
  330       
  331       /**
  332        * Set the locale to use for messages.
  333        *
  334        * @param locale The locale object to use for localization of messages.
  335        *
  336        * @exception XNIException Thrown if the parser does not support the
  337        *                         specified locale.
  338        */
  339       public void setLocale(Locale locale) {
  340           fLocale = locale;
  341       } // setLocale(Locale)
  342   
  343   
  344       /** Returns the locale. */
  345       public Locale getLocale() {
  346           return fLocale;
  347       } // getLocale():Locale
  348   
  349       //
  350       // Protected methods
  351       //
  352   
  353       /** 
  354        * Adds a component to list of configurable components. If the
  355        * same component is added multiple times, the component is
  356        * added only the first time. 
  357        * <p>
  358        * This method helps manage the components in the configuration.
  359        * Therefore, all subclasses should call this method to add the
  360        * components specific to the configuration.
  361        *
  362        * @param component The component to add.
  363        *
  364        * @see #resetComponents
  365        */
  366       protected void addComponent(XMLComponent component) {
  367           if (!fComponents.contains(component)) {
  368               fComponents.addElement(component);
  369               addRecognizedFeatures(component.getRecognizedFeatures());
  370               addRecognizedProperties(component.getRecognizedProperties());
  371           }
  372       } // addComponent(XMLComponent)
  373   
  374       /**
  375        * Resets all of the registered components. Before the subclassed
  376        * configuration begins parsing, it should call this method to
  377        * reset the components.
  378        *
  379        * @see #addComponent
  380        */
  381       protected void resetComponents() 
  382           throws XMLConfigurationException {
  383           int length = fComponents.size();
  384           for (int i = 0; i < length; i++) {
  385               XMLComponent component = (XMLComponent)fComponents.elementAt(i);
  386               component.reset(this);
  387           }
  388       } // resetComponents()
  389   
  390       /**
  391        * This method tries to open the necessary stream for the given
  392        * XMLInputSource. If the input source already has a character
  393        * stream (java.io.Reader) or a byte stream (java.io.InputStream)
  394        * set, this method returns immediately. However, if no character
  395        * or byte stream is already open, this method attempts to open
  396        * an input stream using the source's system identifier.
  397        *
  398        * @param source The input source to open.
  399        */
  400       protected void openInputSourceStream(XMLInputSource source)
  401           throws IOException {
  402           if (source.getCharacterStream() != null) {
  403               return;
  404           }
  405           InputStream stream = source.getByteStream();
  406           if (stream == null) {
  407               String systemId = source.getSystemId();
  408               try {
  409                   URL url = new URL(systemId);
  410                   stream = url.openStream();
  411               }
  412               catch (MalformedURLException e) {
  413                   stream = new FileInputStream(systemId);
  414               }
  415               source.setByteStream(stream);
  416           }
  417       } // openInputSourceStream(XMLInputSource)
  418   
  419   } // class AbstractConfiguration

Home » Xerces-J-src.2.9.1 » xni » parser » [javadoc | source]