<?xml version="1.0"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
-->

<document>

  <properties>
    <title>Parser Component</title>
    <author email="epugh@opensourceconnections.com">Eric Pugh</author>
  </properties>

  <body>

  <section name="Overview">
    <p>
      This Service functions as a repository for Parser components.
    </p>

    <p>
      It is written
      for use in Turbine but it can be used in any container compatible
      with Avalon's ECM container.
    </p>
    
    <p>
      The component uses the following services from the Fulcrum Repository
      <ul>
        <li>
          <a href="http://turbine.apache.org/fulcrum/fulcrum-pool/">Fulcrum Pool Service</a>
        </li>
        <li>
          <a href="http://turbine.apache.org/fulcrum/fulcrum-upload/">Fulcrum Upload Service</a>
          (optional)
        </li>
      </ul>
    </p>
  </section>

<section name="Configuration">
    <subsection name="Role Configuration">
      <source><![CDATA[
    <role
        name="org.apache.fulcrum.parser.ParserService"
        shorthand="parser"
        default-class="org.apache.fulcrum.parser.DefaultParserService"/>
      ]]></source>
    </subsection>
    
    <subsection name="Component Configuration">
      <table>
        <tr>
          <th>Item</th>
          <th>Datatype</th>
          <th>Cardinality</th>
          <th>Description</th>
        </tr>
        <tr>
          <td>urlCaseFolding</td>
          <td>String</td>
          <td>[0|1]</td>
          <td>
            This setting controls how parameter names are to be folded during
            processing. Valid values are <code>none</code> (no folding), 
            <code>upper</code> (all names upper case) and <code>lower</code>
            (all names lower case). The default is <code>none</code>.
          </td>
        </tr>
        <tr>
          <td>parameterEncoding</td>
          <td>String</td>
          <td>[0|1]</td>
          <td>
            The parameter encoding to use when converting strings to bytes or
            vice versa. This encoding is used when no explicit encoding is specified.
            This must be a valid encoding string for the JVM in use. The default is
            <code>iso-8859-1</code>.
          </td>
        </tr>
        <tr>
          <td>automaticUpload</td>
          <td>boolean</td>
          <td>[0|1]</td>
          <td>
            If set to <code>true</code>, parsing the multipart request for attachments
            will be performed automatically. Otherwise, the request may be parsed manually
            by calling <code>parseUpload(HttpServletRequest)</code>. The default value is
            <code>false</code>. When set to true, the component must have the 
            <a href="http://turbine.apache.org/fulcrum/fulcrum-upload/">Fulcrum Upload Service</a>
            available to parse the request.
          </td>
        </tr>
      </table>
    </subsection>

    <subsection name="Component Configuration Example">
      <source><![CDATA[
    <parser>
        <urlCaseFolding>lower</urlCaseFolding>
        <parameterEncoding>utf-8</parameterEncoding>
        <automaticUpload>true</automaticUpload>
    </parser>
      ]]></source>
    </subsection>
  </section>

  <section name="Usage">
    <p>
    You get a parser from the service like this:
    </p>

    <source><![CDATA[
    // Get a ValueParser instance
    ValueParser parser = (ValueParser) parserService.getParser(BaseValueParser.class);

    parser.add(...);
    Double d = parser.getDoubleObject(...);
    
    // Return the instance to the service
    parserService.putParser(parser);
    ]]></source>

    <p>
    Parsers are pooled inside the service. You can use this service to manage any types of
    parsers, you just need to provide the class you want to manage. If the parser class 
    implements LogEnabled it will get an (Avalon) logger injected. If the parser class 
    implements ParserServiceSupport it will get an instance of this service injected. 
    </p>

  </section>

</body>
</document>
