<?xml version="1.0" encoding="ISO-8859-1"?>
<document url="http://castor.codehaus.org/xml-best-practice.xml">
  <properties>
    <title>Castor XML -- Best practices</title>
    <abstract>
       Castor XML -- Best practices
    </abstract>
    <status>Draft</status>
  </properties>

  <body>
    <title>Castor XML -- Best practices</title>
    <header>
    </header>

    <section title="Introduction">

      <p>
        There are many users of Castor XML who (want to) use Castor XML in in
        high-volume applications. To fine-tune Castor for such an environment,
        it is necessary to understand many of the product features in detail
        and to be able to balance their use according to the application needs.
        Even though many of these features are documented in various places,
        people frequently asked for a 'best practises' document, a document
        that brings together these technical topics in one place and that
        presents them as a set of easy-to-use recipes.
      </p>

      <p>
        Please be aware that this document is <i>under construction</i>.  But
        still we believe that this document -- even when in its conception
        phase -- provides valuable information to users of Castor XML.
      </p>

    </section>

    <section title="General">
      <section title="Source Generator">
        <p>
          It is not generally recommended to generate code into the default
          package, especially since code in the default package cannot be
          referenced from code in any other package.
        </p>

        <p>
          Additionally, we recommend that generated code go into a different
          package then the code that makes use of the generated code.  For
          example, if your application uses Castor to process an XML
          configuration file that is used by code in the package
          <tt>org.example.userdialog</tt> then we do not recommend that the
          generated code also go into that package.  However, it would be
          reasonable to generate source to process this XML configuration file
          into the package <tt>org.example.userdialog.xmlconfig</tt>.
        </p>

        <!-- FIXME:  Add section about:  do not store generated code in SCM -->
      </section>
    </section>

    <section title="Performance Considerations">
    
      <section title="General">
      
        <p>
          Creating instances of <api>org.exolab.castor.xml.Marshaller</api> and
          <api>org.exolab.castor.xml.Unmarshaller</api> for the purpose of XML
          data binding is easy to achieve at the API usage level.  However,
          details of API use have an impact on application performance; each
          instance creation involves setup operations.
        </p>

        <p>
          This is generally not an issue for one-off invocations; however, in a
          multi-threaded, high volume use scenario this can be become a serious
          issue. Internally, Castor uses a collection of <i>Descriptor</i>
          classes to keep information about the Java entities to be marshaled
          and unmarshaled. With each instance creation of (Un)Marshaller, this
          collection will be built from scratch (again and again).
        </p>

        <p>
          To avoid this initial configuration 'penalty', Castor allows you to
          cache these Descriptor classes through its
          <api>org.exolab.castor.xml.ClassDescriptorResolver</api> component.
          This cache allows reuse of these Descriptor instances between
          (Un)Marshaller invocations.
        </p>
           
      </section>

      <section title="Use of XMLContext - With and without a mapping file">

        <p>
          With the introduction of the new <tt><api class="org.exolab.castor.xml.XMLContext">XMLContext</api></tt> class, the use of a 
          <tt>ClassDescriptorResolver</tt> has been greatly simplified in that such
          an instance is managed by the XMLContext per default. As such, there's no need
          to pass a <tt>ClassDescriptorResolver</tt> instance to <tt>Marshaller</tt>/
          <tt>Unmarshaller</tt> instances anymore, as this is done automatically
          when such instances are created through
          
          <ul>
            <li><api class="org.exolab.castor.xml.XMLContext">createMarshaller()</api></li>
            <li><api class="org.exolab.castor.xml.XMLContext">createUnmarshaller()</api></li>
          </ul>
          
          For example, to create a <tt>Marshaller</tt> instance that is pre-configured
          with an instance of <tt>ClassDescriptorResolver</tt>, use the following code 
          fragment:
        </p>

        <code-panel>
Mapping mapping = new Mapping();
mapping.loadMapping(new InputSource(...));
        
XMLContext context = new XMLContext();
context.addMapping(mapping);

Marshaller marshaller = <font color="red">context.createMarshaller()</font>;</code-panel>

         <p>
            In the case where no mapping file is used, it is still possible 
            to instruct the <tt><api class="org.exolab.castor.xml.XMLContext">XMLContext</api></tt> to <i>pre-load</i>
            class descriptors for a given package via the methods enlisted
            below.</p>

         <p>
            As above, create an instance of <tt><api class="org.exolab.castor.xml.XMLContext">XMLContext</api></tt> and configure it 
            according to your needs as shown below:
         </p>

        <code-panel>
XMLContext context = new XMLContext();
<font color="red">context.addPackage("your.package.name");</font>

Marshaller marshaller = context.createMarshaller();</code-panel>

         <p>
            The <tt><api class="org.exolab.castor.xml.XMLContext">XMLContext</api></tt> class 
            provides for various methods to load class descriptors for individual classes 
            and/or packages.
         </p>

         <ctable>
            <cheader>
               <td>Method</td>
               <td>Description</td>
               <td>.castor.cdr</td>
            </cheader>
            <crow>
               <td><tt><api class="org.exolab.castor.xml.XMLContext">addClass(Class)</api></tt></td>
               <td>Loads the class descriptor for one class.</td>
               <td>n/a</td>
            </crow>
            <crow>
               <td><tt><api class="org.exolab.castor.xml.XMLContext">addClass(Class[])</api></tt></td>
               <td>Loads the class descriptors for a collection of classes.</td>
               <td>n/a</td>
            </crow>
            <crow>
               <td><tt><api class="org.exolab.castor.xml.XMLContext">addPackage(String)</api></tt></td>
               <td>Loads the class descriptor for all classes in the defined package.</td>
               <td>Required</td>
            </crow>
            <crow>
               <td><tt><api class="org.exolab.castor.xml.XMLContext">addPackages(String[])</api></tt></td>
               <td>Loads the class descriptor for all classes in the defined packages.</td>
               <td>Required</td>
            </crow>
         </ctable>
           
         <note>
            For some of the methods, pre-loading class descriptords will only work if you provide 
            the <tt>.castor.cdr</tt> file with your generated classes (as generated by the XML 
            code generator). If no such file is shipped, Castor will not be able to pre-load the 
            descriptors, and will fall back to its default descriptor loading mechanism.
         </note>
         
      </section>
      
      <section title="Use of Marshaller/Unmarshaller">
      
         <section title="Use of ClassDescriptorResolver">
   
           <p>
             When you do not use the <tt>XMLContext</tt> class, you will have to manually
             manage your <tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">XMLClassDescriptorResolver</api></tt>. To do so, first create an 
             instance of <tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">XMLClassDescriptorResolver</api></tt> using the following code fragment:
           </p>
   
           <code-panel>
XMLClassDescriptorResolver classDescriptorResolver = 
   (XMLClassDescriptorResolver) ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML);
MappingUnmarshaller mappingUnmarshaller = new MappingUnmarshaller();
MappingLoader mappingLoader = 
   mappingUnmarshaller.getMappingLoader(mapping, BindingType.XML);
classDescriptorResolver.setMappingLoader(mappingLoader);</code-panel>
   
           <p>and then reuse this instance as shown below:</p>
   
           <code-panel>
   Unmarshaller unmarshaller = new Unmarshaller();
   unmarshaller.setResolver(classDescriptorResolver);
   unmarshaller.unmarshal(...);</code-panel>
   
         </section>
   
         <section title="Use of ClassDescriptorResolver with no mappings">
         
         	<p>In the case where there's no mapping file, it is still possible 
         	   to instruct the <tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">XMLClassDescriptorResolver</api></tt> to <i>pre-load</i>
         	   class descriptors for a given package via the 
         	   <tt>loadClassDescriptors(String)</tt> method.</p>
   
           <p>
             As above, create an instance of <tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">XMLClassDescriptorResolver</api></tt> using the
             following code fragment:
           </p>
   
           <code-panel>
   XMLClassDescriptorResolver classDescriptorResolver = (XMlClassDescriptorResolver)
      ClassDescriptorResolverFactory.createClassDescriptorResolver(BindingType.XML);
   classDescriptorResolver.setClassLoader(...);
   classDescriptorResolver.addPackage("your.package.name");</code-panel>
   
           <p>and then reuse this instance as shown above. The 
              <tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">XMLClassDescriptorResolver</api></tt>
              interface provides various other methods to load class descriptors for individual
              classes and/or packages.</p>
              
           <ctable>
           	<cheader>
           		<td>Method</td>
           		<td>Description</td>
           		<td>.castor.cdr</td>
           	</cheader>
           	<crow>
           		<td><tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">addClass(String)</api></tt></td>
           		<td>Loads the class descriptor for one class.</td>
           		<td>n/a</td>
           	</crow>
           	<crow>
           		<td><tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">addClass(String[])</api></tt></td>
           		<td>Loads the class descriptors for a collection of classes.</td>
           		<td>n/a</td>
           	</crow>
           	<crow>
           		<td><tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">addPackage(String)</api></tt></td>
           		<td>Loads the class descriptor for all classes in the defined package.</td>
           		<td>Required</td>
           	</crow>
           	<crow>
           		<td><tt><api class="org.exolab.castor.xml.XMLClassDescriptorResolver">addPackages(String[])</api></tt></td>
           		<td>Loads the class descriptor for all classes in the defined packages.</td>
           		<td>Required</td>
           	</crow>
           </ctable>
           
           <note>For some of the methods, pre-loading class descriptords will only work if you provide 
                 the <tt>.castor.cdr</tt> file with your generated classes (as generated by the XML 
                 code generator). If no such file is shipped, Castor will not be able to pre-load the 
                 descriptors, and will fall back to its default descriptor loading mechanism.</note>
           
   
       </section>
    
    </section>
    
   </section>

  </body>

</document>
