<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE s1 SYSTEM 'dtd/document.dtd'>
<s1 title='XNI Parser Configuration'>
 <s2 title='Parser Configuration'>
  <p>
   Parser configurations built using the Xerces Native Interface
   are made from a series of parser components. This document
   details the XNI API for these components and how they are put
   together to construct a parser configuration in the following
   sections:
  </p>
  <ul>
   <li><link anchor='components'>Components</link></li>
   <li><link anchor='configurations'>Configurations</link></li>
   <li><link anchor='pipelines'>Pipelines</link></li>
  </ul>
  <p>
   In addition, several <link anchor='examples'>examples</link>
   are included to show how to create some parser components and 
   configurations:
  </p>
  <ul>
   <li><link anchor='abstract-parser-config'>Abstract Parser Configuration</link></li>
   <li><link anchor='csv-parser-config'>CSV Parser Configuration</link></li>
  </ul>
  <note>
   All of the interfaces and classes defined in this document
   reside in the <code>org.apache.xerces.xni.parser</code> package
   but may use various interfaces and classes from the core XNI
   package, <code>org.apache.xerces.xni</code>.
  </note>
  <note>
   The source code for the samples in this document are included
   in the downloaded packages for Xerces2.
  </note>
 </s2>
 <anchor name='components'/>
 <s2 title='Components'>
  <p>
   Parser configurations are comprised of a number of parser
   components that perform various tasks. For example, a parser
   component may be responsible for the actual scanning of XML
   documents to generate document "streaming" information
   events; another component may manage commonly used symbols
   within the parser configuration in order to improve
   performance; and a third component may even manage the
   resolution of external parsed entities and the transcoding
   of these entities from various international encodings into
   <jump href='http://www.unicode.org/'>Unicode</jump> used 
   within the Java virtual machine. When these components are
   assembled in a certain way, they constitute a single parser
   configuration but they can also be used interchangeably with
   other components that implement the appropriate interfaces.
  </p>
  <p>
   <strong>Note:</strong>
   Even though a parser is comprised of a number of components,
   not all of these components are <em>configurable</em>. In
   other words, some components depend on knowing the state of
   certain features and properties of the parser configuration
   while others can operate completely independent of the parser
   configuration. However, when we use the term "component" when
   talking about XNI, we are talking about a <em>configurable
   component</em> within the parser configuration.
  </p>
  <p>
   The following diagram shows an example of this collection of 
   parser components: (Please note that this is not the <em>only</em>
   configuration of parser components.)
  </p>
  <p>
   <img alt='Parser Components' src='xni-components-overview.gif'/>
  </p>
  <p>
   The only distinguishing feature of a component
   is that it can be notified of the state
   of parser features and properties. Features represent parser
   state of type <code>boolean</code> whereas properties represent
   parser state of type <code>java.lang.Object</code>. Each
   component can also be queried for which features and properties
   it recognizes.
  </p>
  <anchor name='component'/>
  <s3 title='Interface XMLComponent'>
   <p>
    This interface is the basic configurable component in a parser
    configuration. It is managed by the
    <link anchor='component-manager'>XMLComponentManager</link>
    which holds the parser state.
   </p>
   <table>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void reset(
           <link anchor='component-manager'>XMLComponentManager</link> manager
           ) throws <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setFeature(
           String featureId,
           boolean state
           ) throws <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setProperty(
           String propertyId,
	   Object value
           ) throws <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
    <tr><td><code>public String[] getRecognizedFeatures();</code></td></tr>
    <tr><td><code>public String[] getRecognizedProperties();</code></td></tr>
   </table>
  </s3>
  <anchor name='configuration-exception'/>
  <s3 title='Class XMLConfigurationException'>
   <p>
   </p>
   <table>
    <tr>
     <th>
      Extends <link idref='xni-core' anchor='exception'>XNIException</link>
     </th>
    </tr>
    <tr><th>Constants</th></tr>
    <tr>
     <td><code>public static final short NOT_RECOGNIZED;</code></td>
    </tr>
    <tr>
     <td><code>public static final short NOT_SUPPORTED;</code></td>
    </tr>
    <tr><th>Constructors</th></tr>
    <tr>
     <td>
      <code>
       public XMLConfigurationException(
           short type,
	   String identifier
           );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public XMLConfigurationException(
           short type,
	   String identifier,
	   String message
           );
      </code>
     </td>
    </tr>
    <tr><th>Methods</th></tr>
    <tr><td><code>public short getType();</code></td></tr>
    <tr><td><code>public String getIdentifier();</code></td></tr>
   </table>
  </s3>
  <p>
   Components are managed by a component manager. The component
   manager keeps track of the parser state for features and 
   properties.  The component manager is responsible for notifying
   each component when the value of those features and properties
   change.
  </p>
  <p>
   Before parsing a document, a parser configuration <em>must</em>
   use the component manager to reset all of the parser components.
   Then, during parsing, each time a feature or property value is
   modified, all of the components <em>must</em> be informed of the 
   change.
  </p>
  <anchor name='component-manager'/>
  <s3 title='Interface XMLComponentManager'>
   <p>
    The component manager interface allows components to query
    needed features and properties during a call to the
    <code>XMLComponent#reset(XMLComponentManager)</code> method.
    However, components <em>should not</em> keep a reference to
    the component manager. In other words, all necessary state
    should be queried when the component is reset.
   </p>
   <table>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public boolean getFeature(
           String featureId
           ) throws <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public Object getProperty(
           String propertyId
           ) throws <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <p>
   <strong>Note:</strong>
   A compliant XNI parser configuration is <em>not</em>
   required to use any components that implement the
   <code><link anchor='component'>XMLComponent</link></code>
   interface. That interface is included as a convenience for
   people building modular and configurable parser components.
   The Xerces2 reference implementation uses the component
   interface to implement its components so that they can be
   used interchangeably in various configurations.
  </p>
 </s2>
 <anchor name='configurations'/>
 <s2 title='Configurations'>
  <p>
   An XNI parser configuration defines the entry point for a
   parser to set features and properties, initiate a parse of
   an XML instance document, perform entity resolution, and
   receive notification of errors that occurred in the document.
  </p>
  <p>
   A parser configuration is typically comprised of a series of
   parser components. Some of these components may be
   connected together to form the parsing pipeline. This parser
   configuration is then used by a specific parser implementation
   that generates a particular API, such as DOM or SAX. The
   separation between the parser configuration and parser instance
   allows the same API-generating parser to be used with an
   unlimited number of different parser configurations.
  </p>
  <p>
   When a document is parsed, the parser configuration resets the
   configurable components and initiates the scanning of the
   document. Typically, a scanner starts scanning the document
   which generates XNI information set events that are sent to
   the next component in the pipeline (e.g. the validator). The
   information set events coming out of the end of the pipeline
   are then communicated to the document and DTD handlers that
   are registered with the parser configuration. 
  </p>
  <p>
   The following diagram shows both the generic parsing pipeline
   contained within a parser configuration and the separation of 
   parser configuration and specific parser classes.
  </p>
  <p>
   <img alt='Parser Configuration' src='xni-parser-configuration.gif'/>
  </p>
  <p>
   There are two parser configuration interfaces defined in XNI:
   the <code>XMLParserConfiguration</code> and the
   <code>XMLPullParserConfiguration</code>. For most purposes, the
   standard parser configuration will suffice. Document and DTD
   handler interfaces will be registered on the parser configuration
   and the document will be parsed completely by calling the
   <code>parse(XMLInputSource)</code> method. In this situation,
   the application is driven by the output of the configuration.
  </p>
  <p>
   However, the <code>XMLPullParserConfiguration</code> interface
   extends the <code>XMLParserConfiguration</code> interface to
   provide methods that allow the application to drive the
   configuration. Any configuration class that implements this
   interface guarantees that it can be driven in a pull parsing
   fashion but does not make any statement as to how much or how
   little pull parsing will be performed at each step.
  </p>
  <anchor name='parser-configuration'/>
  <s3 title='Interface XMLParserConfiguration'>
   <p>
    The parser configuration is the primary connection to specific
    parser instances. Because the parser configuration is responsible
    for holding the parser state, the 
    <code>addRecognizedFeatures(String[])</code> and
    <code>addRecognizedProperties(String[])</code> methods allow the
    parser instance to add recognized features and properties that
    the parser configuration will store.
   </p>
   <table>
    <tr>
     <th>
      Extends <link anchor='component-manager'>XMLComponentManager</link>
     </th>
    </tr>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void setFeature(
           String featureId,
	   boolean state
	   ) throws <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setProperty(
           String propertyId,
	   Object value
	   ) throws <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>public void addRecognizedFeatures(String[] featureIds);</code>
     </td>
    </tr>
    <tr>
     <td>
      <code>public void addRecognizedProperties(String[] propertyIds);</code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setEntityResolver(
           <link anchor='entity-resolver'>XMLEntityResolver</link> resolver
	   );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public <link anchor='entity-resolver'>XMLEntityResolver</link>
           getEntityResolver();
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setErrorHandler(
           <link anchor='error-handler'>XMLErrorHandler</link> handler
	   );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public <link anchor='error-handler'>XMLErrorHandler</link>
           getErrorHandler();
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setDocumentHandler(
           <link idref='xni-core' anchor='document-handler'>XMLDocumentHandler</link> handler
	   );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public <link anchor='document-handler'>XMLDocumentHandler</link>
           getDocumentHandler();
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setDTDHandler(
           <link idref='xni-core' anchor='dtd-handler'>XMLDTDHandler</link> handler
	   );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public <link anchor='dtd-handler'>XMLDTDHandler</link>
           getDTDHandler();
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void setDTDContentModelHandler(
           <link idref='xni-core' anchor='dtd-content-model-handler'>XMLDTDContentModelHandler</link> handler
	   );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public <link anchor='dtd-content-model-handler'>XMLDTDContentModelHandler</link>
           getDTDContentModelHandler();
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void parse(
           <link anchor='input-source'>XMLInputSource</link> source
	   ) throws java.io.IOException, <link anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
    <tr><td><code>public void setLocale(java.util.Locale);</code></td></tr>
    <tr><td><code>public Locale getLocale();</code></td></tr>
   </table>
  </s3>
  <anchor name='pull-parser-configuration'/>
  <s3 title='Interface XMLPullParserConfiguration'>
   <p>
    Parser configurations that implement this interface state that they
    can be driven by the application in a pull parser fashion.
   </p>
   <table>
    <tr>
     <th>
      Extends <link anchor='parser-configuration'>XMLParserConfiguration</link>
     </th>
    </tr>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void setInputSource(
           <link anchor='input-source'>XMLInputSource</link> source
	   ) throws java.io.IOException, 
                    <link anchor='configuration-exception'>XMLConfigurationException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public boolean parse(boolean complete)
	   throws java.io.IOException, 
                  <link anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <anchor name='entity-resolver'/>
  <s3 title='Interface XMLEntityResolver'>
   <p>
    This interface allows resolution of the external DTD subset and
    external parsed entities appearing in the document instance.
   </p>
   <table>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public <link anchor='input-source'>XMLInputSource</link> resolveEntity(
           String publicId,
	   String systemId,
	   String baseSystemId
	   ) throws java.io.IOException, <link anchor='parse-exception'>XMLParseException</link>;
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <anchor name='error-handler'/>
  <s3 title='Interface XMLErrorHandler'>
   <table>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void warning(
           String domain,
	   String key,
           <link anchor='parse-exception'>XMLParseException</link> exception
	   ) throws <link idref='xni-core' anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void error(
           String domain,
	   String key,
           <link anchor='parse-exception'>XMLParseException</link> exception
	   ) throws <link idref='xni-core' anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public void fatalError(
           String domain,
	   String key,
           <link anchor='parse-exception'>XMLParseException</link> exception
	   ) throws <link idref='xni-core' anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <anchor name='input-source'/>
  <s3 title='Class XMLInputSource'>
   <table>
    <tr><th>Constructors</th></tr>
    <tr>
     <td>
      <code>
       public XMLInputSource(
           String publicId,
	   String systemId,
	   String baseSystemId
           );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public XMLInputSource(
           String publicId,
	   String systemId,
	   String baseSystemId,
	   java.io.InputStream byteStream,
	   String encoding
           );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public XMLInputSource(
           String publicId,
	   String systemId,
	   String baseSystemId
	   java.io.Reader characterStream,
	   String encoding
           );
      </code>
     </td>
    </tr>
    <tr><th>Methods</th></tr>
    <tr><td><code>public void setPublicId(String publicId);</code></td></tr>
    <tr><td><code>public String getPublicId();</code></td></tr>
    <tr><td><code>public void setSystemId(String systemId);</code></td></tr>
    <tr><td><code>public String getSystemId();</code></td></tr>
    <tr><td><code>public void getBaseSystemId(String baseSystemId);</code></td></tr>
    <tr><td><code>public String getBaseSystemId();</code></td></tr>
    <tr><td><code>public void getByteStream(java.io.InputStream byteStream);</code></td></tr>
    <tr><td><code>public java.io.InputStream getByteStream();</code></td></tr>
    <tr><td><code>public void getCharacterStream(java.io.Reader characterStream);</code></td></tr>
    <tr><td><code>public java.io.Reader getCharacterStream();</code></td></tr>
    <tr><td><code>public void setEncoding(String encoding);</code></td></tr>
    <tr><td><code>public String getEncoding();</code></td></tr>
   </table>
  </s3>
  <anchor name='parse-exception'/>
  <s3 title='Class XMLParseException'>
   <table>
    <tr>
     <th>
      Extends <link idref='xni-core' anchor='exception'>XNIException</link>
     </th>
    </tr>
    <tr><th>Constructors</th></tr>
    <tr>
     <td>
      <code>
       public XMLParseException(
           <link idref='xni-core' anchor='locator'>XMLLocator</link> location,
	   String message
           );
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public XMLParseException(
           <link idref='xni-core' anchor='locator'>XMLLocator</link> location,
	   String message,
	   Exception exception
           );
      </code>
     </td>
    </tr>
    <tr><th>Methods</th></tr>
    <tr><td><code>public String getPublicId();</code></td></tr>
    <tr><td><code>public String getSystemId();</code></td></tr>
    <tr><td><code>public String getBaseSystemId();</code></td></tr>
    <tr><td><code>public int getLineNumber();</code></td></tr>
    <tr><td><code>public int getColumnNumber();</code></td></tr>
   </table>
  </s3>
 </s2>
 <anchor name='pipelines'/>
 <s2 title='Pipelines'>
  <p>
   The <link idref='xni-core'>Core Interfaces</link> provide
   interfaces for the streaming information set. While these
   interfaces are sufficient for communicating the document and
   DTD information, it does not provide an easy way to construct
   the pipeline or initiate the pipeline to start parsing an
   XML document. The <code>org.apache.xerces.xni.parser</code> 
   package has additional interfaces to fill exactly this need.
  </p>
  <p>
   Each parser configuration can be thought of as two separate
   pipelines: one for document information and one for DTD
   information. Each pipeline starts with a scanner and is followed
   by zero or more filters (objects that implement interfaces
   to handle the incoming information as well as register
   handlers for the outgoing information). The information that
   comes out the end of the pipeline is usually forwarded by
   the parser configuration to the registered handlers.
  </p>
  <p>
   There are two scanner interfaces defined: the XMLDocumentScanner
   and the XMLDTDScanner:
  </p>
  <anchor name='document-scanner'/>
  <s3 title='Interface XMLDocumentScanner'>
   <p>This interface defines an XML document scanner.</p>
   <table>
    <tr>
     <th>
      Extends <link anchor='document-source'>XMLDocumentSource</link>
     </th>
    </tr>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void setInputSource(
           <link anchor='input-source'>XMLInputSource</link> source
           ) throws java.io.IOException;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public boolean scanDocument(boolean complete)
           throws java.io.IOException, <link anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <anchor name='dtd-scanner'/>
  <s3 title='Interface XMLDTDScanner'>
   <p>
    This interface defines a DTD scanner. Typically, scanning of
    the DTD internal subset is initiated from the XML document 
    scanner so the input source is implicitly the same as the
    one used by the document scanner. Therefore, the 
    <code>setInputSource</code> method should only be called before
    scanning of the DTD external subset.
   </p>
   <table>
    <tr>
     <th>
      Extends <link anchor='dtd-source'>XMLDTDSource</link>,
      <link anchor='dtd-content-model-source'>XMLDTDContentModelSource</link>
     </th>
    </tr>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void setInputSource(
           <link anchor='input-source'>XMLInputSource</link> source
           ) throws java.io.IOException;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public boolean scanDTDInternalSubset(
           boolean complete,
	   boolean standalone,
	   boolean hasExternalSubset
	   ) throws java.io.IOException, <link anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
    <tr>
     <td>
      <code>
       public boolean scanDTDExternalSubset(
           boolean complete
	   ) throws java.io.IOException, <link anchor='exception'>XNIException</link>;
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <p>
   Notice how each scanner interface's scanning methods take a
   <code>complete</code> parameter and returns a boolean. This
   allows (but does not require) scanners that implement these
   interfaces to provide "pull" parsing behaviour in which the
   application drives the parser's operation instead of having
   parsing events "pushed" to the registered handlers.
  </p>
  <p>
   After the scanners, zero or filters may be present in a parser
   configuration pipeline. A document pipeline filter implements the
   <link idref='xni-core' anchor='document-handler'>XMLDocumentHandler</link>
   interface from the XNI Core Interfaces as well as the
   <link anchor='document-source'>XMLDocumentSource</link>
   interface which allows filters to be chained together in
   the pipeline. There are equivalents source interfaces for the
   DTD information as well.
  </p>
  <anchor name='document-source'/>
  <s3 title='Interface XMLDocumentSource'>
   <p>This interface allows a document handler to be registered.</p>
   <table>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void setDocumentHandler(
           <link idref='xni-core' anchor='document-handler'>XMLDocumentHandler</link> handler
           );
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <anchor name='document-filter'/>
  <s3 title='Interface XMLDocumentFilter'>
   <p>
    Defines a document filter that acts as both a receiver and 
    an emitter of document events.
   </p>
   <table>
    <tr>
     <th> Extends 
      <link idref='xni-core' anchor='document-handler'>XMLDocumentHandler</link>,
      <link anchor='document-source'>XMLDocumentSource</link>
     </th>
    </tr>
   </table>
  </s3>
  <anchor name='dtd-source'/>
  <s3 title='Interface XMLDTDSource'>
   <p>This interface allows a DTD handler to be registered.</p>
   <table>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void setDTDHandler(
           <link idref='xni-core' anchor='dtd-handler'>XMLDTDHandler</link> handler
           );
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <anchor name='dtd-filter'/>
  <s3 title='Interface XMLDTDFilter'>
   <p>
    Defines a DTD filter that acts as both a receiver and 
    an emitter of DTD events.
   </p>
   <table>
    <tr>
     <th> Extends 
      <link idref='xni-core' anchor='dtd-handler'>XMLDTDHandler</link>,
      <link anchor='dtd-source'>XMLDTDSource</link>
     </th>
    </tr>
   </table>
  </s3>
  <anchor name='dtd-content-model-source'/>
  <s3 title='Interface XMLDTDContentModelSource'>
   <p>This interface allows a DTD content model handler to be registered.</p>
   <table>
    <tr><th>Methods</th></tr>
    <tr>
     <td>
      <code>
       public void setDTDContentModelHandler(
           <link idref='xni-core' anchor='dtd-content-model-handler'>XMLDTDContentModelHandler</link> handler
           );
      </code>
     </td>
    </tr>
   </table>
  </s3>
  <anchor name='dtd-filter'/>
  <s3 title='Interface XMLDTDContentModelFilter'>
   <p>
    Defines a DTD content model filter that acts as both a receiver and 
    an emitter of DTD content model events.
   </p>
   <table>
    <tr>
     <th> Extends 
      <link idref='xni-core' anchor='dtd-content-model-handler'>XMLDTDContentModelHandler</link>,
      <link anchor='dtd-content-model-source'>XMLDTDContentModelSource</link>
     </th>
    </tr>
   </table>
  </s3>
  <p>
   The next section gives some basic examples for using the XNI
   framework to construct filters and parser configurations.
  </p>
 </s2>
 <anchor name='examples'/>
 <s2 title='Examples'>
  <p>
   The following samples show how to create various parser components
   and parser configurations. The XNI samples included with the Xerces2
   reference release provide a convenient way to test a parser
   configuration. For example, to test the 
   <link anchor='csv-parser-config'>CSV Parser Configuration</link>
   example, run the following command:
  </p>
  <source>java xni.DocumentTracer -p CSVConfiguration document.csv</source>
  <p>
   Or a new CSV parser can be constructed that produces standard
   SAX events. For example:
  </p>
  <source>import org.apache.xerces.parsers.AbstractSAXParser;

public class CSVParser
    extends AbstractSAXParser {

    // Constructors

    public CSVParser() {
        super(new CSVConfiguration());
    }

} // class CSVParser</source>
  <p>
   The following samples are available:
  </p>
  <ul>
   <li><link anchor='abstract-parser-config'>Abstract Parser Configuration</link></li>
   <li><link anchor='csv-parser-config'>CSV Parser Configuration</link></li>
  </ul>
  <anchor name='abstract-parser-config'/>
  <s3 title='Abstract Parser Configuration'>
   <p>
    This abstract parser configuration simply helps manage
    components, features and properties, and other tasks common to
    all parser configurations.
   </p>
   <source><![CDATA[import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Vector;

import org.apache.xerces.xni.XMLDocumentHandler;
import org.apache.xerces.xni.XMLDTDHandler;
import org.apache.xerces.xni.XMLDTDContentModelHandler;
import org.apache.xerces.xni.XNIException;

import org.apache.xerces.xni.parser.XMLComponent;
import org.apache.xerces.xni.parser.XMLConfigurationException;
import org.apache.xerces.xni.parser.XMLEntityResolver;
import org.apache.xerces.xni.parser.XMLErrorHandler;
import org.apache.xerces.xni.parser.XMLInputSource;
import org.apache.xerces.xni.parser.XMLParserConfiguration;

public abstract class AbstractConfiguration 
    implements XMLParserConfiguration {

    // Data

    protected final Vector fRecognizedFeatures = new Vector();
    protected final Vector fRecognizedProperties = new Vector();
    protected final Hashtable fFeatures = new Hashtable();
    protected final Hashtable fProperties = new Hashtable();

    protected XMLEntityResolver fEntityResolver;
    protected XMLErrorHandler fErrorHandler;
    protected XMLDocumentHandler fDocumentHandler;
    protected XMLDTDHandler fDTDHandler;
    protected XMLDTDContentModelHandler fDTDContentModelHandler;
    
    protected Locale fLocale;

    protected final Vector fComponents = new Vector();

    // XMLParserConfiguration methods

    public void addRecognizedFeatures(String[] featureIds) {
        int length = featureIds != null ? featureIds.length : 0;
        for (int i = 0; i < length; i++) {
            String featureId = featureIds[i];
            if (!fRecognizedFeatures.contains(featureId)) {
                fRecognizedFeatures.addElement(featureId);
            }
        }
    }
    
    public void setFeature(String featureId, boolean state)
        throws XMLConfigurationException {
        if (!fRecognizedFeatures.contains(featureId)) {
            short type = XMLConfigurationException.NOT_RECOGNIZED;
            throw new XMLConfigurationException(type, featureId);
        }
        fFeatures.put(featureId, state ? Boolean.TRUE : Boolean.FALSE);
        int length = fComponents.size();
        for (int i = 0; i < length; i++) {
            XMLComponent component = (XMLComponent)fComponents.elementAt(i);
            component.setFeature(featureId, state);
        }
    }

    public boolean getFeature(String featureId) 
        throws XMLConfigurationException {
        if (!fRecognizedFeatures.contains(featureId)) {
            short type = XMLConfigurationException.NOT_RECOGNIZED;
            throw new XMLConfigurationException(type, featureId);
        }
        Boolean state = (Boolean)fFeatures.get(featureId);
        return state != null ? state.booleanValue() : false;
    }
    
    public void addRecognizedProperties(String[] propertyIds) {
        int length = propertyIds != null ? propertyIds.length : 0;
        for (int i = 0; i < length; i++) {
            String propertyId = propertyIds[i];
            if (!fRecognizedProperties.contains(propertyId)) {
                fRecognizedProperties.addElement(propertyId);
            }
        }
    }

    public void setProperty(String propertyId, Object value) 
        throws XMLConfigurationException {
        if (!fRecognizedProperties.contains(propertyId)) {
            short type = XMLConfigurationException.NOT_RECOGNIZED;
            throw new XMLConfigurationException(type, propertyId);
        }
        if (value != null) {
            fProperties.put(propertyId, value);
        }
        else {
            fProperties.remove(propertyId);
        }
        int length = fComponents.size();
        for (int i = 0; i < length; i++) {
            XMLComponent component = (XMLComponent)fComponents.elementAt(i);
            component.setProperty(propertyId, value);
        }
    }

    public Object getProperty(String propertyId) 
        throws XMLConfigurationException {
        if (!fRecognizedProperties.contains(propertyId)) {
            short type = XMLConfigurationException.NOT_RECOGNIZED;
            throw new XMLConfigurationException(type, propertyId);
        }
        Object value = fProperties.get(propertyId);
        return value;
    }

    public void setEntityResolver(XMLEntityResolver resolver) {
        fEntityResolver = resolver;
    }
    
    public XMLEntityResolver getEntityResolver() {
        return fEntityResolver;
    }

    public void setErrorHandler(XMLErrorHandler handler) {
        fErrorHandler = handler;
    }
    
    public XMLErrorHandler getErrorHandler() {
        return fErrorHandler;
    }

    public void setDocumentHandler(XMLDocumentHandler handler) {
        fDocumentHandler = handler;
    }

    public XMLDocumentHandler getDocumentHandler() {
        return fDocumentHandler;
    }

    public void setDTDHandler(XMLDTDHandler handler) {
        fDTDHandler = handler;
    }

    public XMLDTDHandler getDTDHandler() {
        return fDTDHandler;
    }

    public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
        fDTDContentModelHandler = handler;
    }
    
    public XMLDTDContentModelHandler getDTDContentModelHandler() {
        return fDTDContentModelHandler;
    }

    public abstract void parse(XMLInputSource inputSource) 
        throws IOException, XNIException;
    
    public void setLocale(Locale locale) {
        fLocale = locale;
    }
    
    // Protected methods

    protected void addComponent(XMLComponent component) {
        if (!fComponents.contains(component)) {
            fComponents.addElement(component);
            addRecognizedFeatures(component.getRecognizedFeatures());
            addRecognizedProperties(component.getRecognizedProperties());
        }
    }

    protected void resetComponents() 
        throws XMLConfigurationException {
        int length = fComponents.size();
        for (int i = 0; i < length; i++) {
            XMLComponent component = (XMLComponent)fComponents.elementAt(i);
            component.reset(this);
        }
    }

    protected void openInputSourceStream(XMLInputSource source)
        throws IOException {
        if (source.getCharacterStream() != null) {
            return;
        }
        InputStream stream = source.getByteStream();
        if (stream == null) {
            String systemId = source.getSystemId();
            try {
                URL url = new URL(systemId);
                stream = url.openStream();
            }
            catch (MalformedURLException e) {
                stream = new FileInputStream(systemId);
            }
            source.setByteStream(stream);
        }
    }

} // class AbstractConfiguration]]></source>
  </s3>
  <anchor name='csv-parser-config'/>
  <s3 title='CSV Parser Configuration'>
   <p>
    This example is a very simple parser configuration that can
    parse files with comma-separated values (CSV) to generate
    XML events. For example, the following CSV document:
   </p>
   <source>Andy Clark,16 Jan 1973,Cincinnati</source>
   <p>
    produces the following XML "document" as represented by the
    XNI streaming document information:
   </p>
   <source><![CDATA[<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE csv [
<!ELEMENT csv (row)*>
<!ELEMENT row (col)*>
<!ELEMENT col (#PCDATA)>
]>
<csv>
 <row>
  <col>Andy Clark</col>
  <col>16 Jan 1973</col>
  <col>Cincinnati</col>
 </row>
</csv>]]></source>
   <p>
    Here is the source code for the CSV parser configuration. 
    Notice that it does not use any components. Rather, it implements
    the CSV parsing directly in the parser configuration's 
    <code>parse(XMLInputSource)</code> method. This demonstrates
    that you are <em>not</em> required to use the 
    <code>XMLComponent</code> interface but it is there for
    building modular components that can be used in other
    configurations.
   </p>
   <source><![CDATA[import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.Reader;
import java.util.StringTokenizer;

import org.apache.xerces.util.XMLAttributesImpl;
import org.apache.xerces.util.XMLStringBuffer;

import org.apache.xerces.xni.QName;
import org.apache.xerces.xni.XMLAttributes;
import org.apache.xerces.xni.XMLDTDContentModelHandler;
import org.apache.xerces.xni.XNIException;

import org.apache.xerces.xni.parser.XMLInputSource;

public class CSVConfiguration
    extends AbstractConfiguration {

    // Constants

    protected static final QName CSV = new QName(null, null, "csv", null);
    protected static final QName ROW = new QName(null, null, "row", null);
    protected static final QName COL = new QName(null, null, "col", null);
    protected static final XMLAttributes EMPTY_ATTRS = new XMLAttributesImpl();

    // Data

    private final XMLStringBuffer fStringBuffer = new XMLStringBuffer();

    // XMLParserConfiguration methods

    public void setFeature(String featureId, boolean state) {}
    public boolean getFeature(String featureId) { return false; }
    public void setProperty(String propertyId, Object value) {}
    public Object getProperty(String propertyId) { return null; }

    public void parse(XMLInputSource source) 
        throws IOException, XNIException {

        // get reader
        openInputSourceStream(source);
        Reader reader = source.getCharacterStream();
        if (reader == null) {
            InputStream stream = source.getByteStream();
            reader = new InputStreamReader(stream);
        }
        BufferedReader bufferedReader = new BufferedReader(reader);

        // start document
        if (fDocumentHandler != null) {
            fDocumentHandler.startDocument(null, "UTF-8");
            fDocumentHandler.xmlDecl("1.0", "UTF-8", null);
            fDocumentHandler.doctypeDecl("csv", null, null);
        }
        if (fDTDHandler != null) {
            fDTDHandler.startDTD(null);
            fDTDHandler.elementDecl("csv", "(row)*");
            fDTDHandler.elementDecl("row", "(col)*");
            fDTDHandler.elementDecl("col", "(#PCDATA)");
        }
        if (fDTDContentModelHandler != null) {
            fDTDContentModelHandler.startContentModel("csv");
            fDTDContentModelHandler.startGroup();
            fDTDContentModelHandler.element("row");
            fDTDContentModelHandler.endGroup();
            short csvOccurs = XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE;
            fDTDContentModelHandler.occurrence(csvOccurs);
            fDTDContentModelHandler.endContentModel();
            
            fDTDContentModelHandler.startContentModel("row");
            fDTDContentModelHandler.startGroup();
            fDTDContentModelHandler.element("col");
            fDTDContentModelHandler.endGroup();
            short rowOccurs = XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE;
            fDTDContentModelHandler.occurrence(rowOccurs);
            fDTDContentModelHandler.endContentModel();
        
            fDTDContentModelHandler.startContentModel("col");
            fDTDContentModelHandler.startGroup();
            fDTDContentModelHandler.pcdata();
            fDTDContentModelHandler.endGroup();
            fDTDContentModelHandler.endContentModel();
        }
        if (fDTDHandler != null) {
            fDTDHandler.endDTD();
        }
        if (fDocumentHandler != null) {
            fDocumentHandler.startElement(CSV, EMPTY_ATTRS);
        }

        // read lines
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            if (fDocumentHandler != null) {
                fDocumentHandler.startElement(ROW, EMPTY_ATTRS);
                StringTokenizer tokenizer = new StringTokenizer(line, ",");
                while (tokenizer.hasMoreTokens()) {
                    fDocumentHandler.startElement(COL, EMPTY_ATTRS);
                    String token = tokenizer.nextToken();
                    fStringBuffer.clear();
                    fStringBuffer.append(token);
                    fDocumentHandler.characters(fStringBuffer);
                    fDocumentHandler.endElement(COL);
                }
                fDocumentHandler.endElement(ROW);
            }
        }
        bufferedReader.close();

        // end document
        if (fDocumentHandler != null) {
            fDocumentHandler.endElement(CSV);
            fDocumentHandler.endDocument();
        }

    }
    
} // class CSVConfiguration]]></source>
  <p>
   The source code is longer than it actually needs to be because
   it also emits the DTD information necessary for a validating
   parser to validate the document. The real core of the example
   is the following:
  </p>
  <source><![CDATA[fDocumentHandler.startDocument(null, "UTF-8");
fDocumentHandler.startElement(CSV, EMPTY_ATTRS);

String line;
while ((line = bufferedReader.readLine()) != null) {
    if (fDocumentHandler != null) {
        fDocumentHandler.startElement(ROW, EMPTY_ATTRS);
        
	StringTokenizer tokenizer = new StringTokenizer(line, ",");
        while (tokenizer.hasMoreTokens()) {
            fDocumentHandler.startElement(COL, EMPTY_ATTRS);
            String token = tokenizer.nextToken();
            fStringBuffer.clear();
            fStringBuffer.append(token);
            fDocumentHandler.characters(fStringBuffer);
            fDocumentHandler.endElement(COL);
        }
	
        fDocumentHandler.endElement(ROW);
    }
}

fDocumentHandler.endElement(CSV);
fDocumentHandler.endDocument();]]></source>
  </s3>
 </s2>
</s1>
