<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">

<!--
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 -->
<s1 title="The Translet API and TrAX">

  <s2 title="Contents">

  <p>Note: This document describes the design of XSLTC's TrAX implementation.
  The XSLTC <link idref="xsltc_trax_api">TrAX API user documentation</link>
  is kept in a separate document.</p>

  <p>The structure of this document is, and should be kept, as follows:</p>

  <ul>
    <li>A brief introduction to TrAX/JAXP</li>
    <li>Overall design of the XSLTC TrAX implementation</li>
    <li>Detailed design of various TrAX components</li>
  </ul>

  <ul>
    <li><link anchor="abstract">Abstract</link></li>
    <li><link anchor="trax">TrAX basics</link></li>
    <li><link anchor="config">TrAX configuration</link></li>
    <li><link anchor="design">XSLTC TrAX architecture</link></li>
    <li><link anchor="detailed_design">XSLTC TrAX detailed design</link></li>
      <ul>
        <li><link anchor="factory_design">TransformerFactory design</link></li>
        <li><link anchor="templates_design">Templates design</link></li>
        <li><link anchor="transformer_design">Transformer design</link></li>
        <li><link anchor="config_design">TrAX configuration design</link></li>
      </ul>
  </ul>
  </s2>

  <!--====================== ABSTRACT SECTION ===========================-->

  <anchor name="abstract"/>
  <s2 title="Abstract">

  <p>JAXP is the Java extension API for XML parsing. TrAX is an API for XML
  transformations and is included in the later versions of JAXP. JAXP includes
  two packages, one for XML parsing and one for XML transformations (TrAX):</p>
<source>
    javax.xml.parsers
    javax.xml.transform</source>

  <p>XSLTC is an XSLT processing engine and fulfills the role as an XML
  transformation engine behind the TrAX portion of the JAXP API. XSLTC is a
  provider for the TrAX API and a client of the JAXP parser API.</p>

  <p>This document describes the design used for integrating XSLTC translets
  with the JAXP TrAX API. The heart of the design is a wrapper class around the
  XSLTC compiler that extends the JAXP <code>SAXTransformerFactory</code>
  interface. This factory delivers translet class definitions (Java bytecodes)
  wrapped inside TrAX <code>Templates</code> objects. These
  <code>Templates</code> objects can be used to instanciate 
  <code>Transformer</code> objects that transform XML documents into markup or
  plain text. Alternatively a <code>Transformer</code> object can be created
  directly by the <code>TransformerFactory</code>, but this approach is not
  recommended with XSLTC. The reason for this will be explained later in this
  document.</p>

  </s2>

  <!--====================== TRAX BASICS SECTION =========================-->

  <anchor name="trax"/>
  <s2 title="TrAX basics">

  <p>The Java API for XML Processing (JAXP) includes an XSLT framework based
  on the Transformation API for XML (TrAX). A JAXP transformation application
  can use the TrAX framework in two ways. The simplest way is:</p>

  <ul>
    <li>create an instance of the TransformerFactory class</li>
    <li>from the factory instance and a given XSLT stylesheet, create a new
    Transformer object</li>
    <li>call the Transformer object's transform() method, specifying the XML
    input and a Result object.</li>
  </ul><source>
    import javax.xml.transform.*;

        public class Compile {

            public void run(Source xsl) {
                ....
                TransformerFactory factory = TransformerFactory.newInstance();
                Transformer transformer = factory.newTransformer(xsl);
                ....
            }
        }</source>

  <p>This suits most conventional XSLT processors that transform XML documents
  in one go. XSLTC needs one extra step to compile the XSL stylesheet into a
  Java class (a &quot;translet&quot;). Fortunately TrAX has another approach
  that suits XSLTC two-step transformation model:</p>

  <ul>
    <li>create an instance of the TransformerFactory class</li>
    <li>from the factory instance and a given XSLTC, stylesheet, create a new
    Templates object (this step will compile the stylesheet and put the
    bytecodes for translet class(es) into the Templates object)</li>
    <li>from the Template object create a Transformer object (this will
    instanciate a new translet object).</li>
    <li>call the Transformer object's transform() method, specifying the XML
    input and a Result object.</li>
  </ul><source>
    import javax.xml.transform.*;

        public class Compile {

            public void run(Source xsl) {
                ....
                TransformerFactory factory = TransformerFactory.newInstance();
                Templates templates = factory.newTemplates(xsl);
                Transformer transformer = templates.newTransformer();
                ....
            }
        }</source>

  <p>Note that the first two steps need be performed only once for each
  stylesheet. Once the stylesheet is compiled into a translet and wrapped in a
  <code>Templates</code> object, the <code>Templates</code> object can be used
  over and over again to create Transformer object (instances of the translet).
  The <code>Templates</code> instances can even be serialized and stored on
  stable storage (ie. in a memory or disk cache) for later use.</p>

  <p>The code below illustrates a simple JAXP transformation application that
  creates the <code>Transformer</code> directly. Remember that this is not the
  ideal approach with XSLTC, as the stylesheet is compiled for each
  transformation.</p><source>
    import javax.xml.transform.stream.StreamSource;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;

    public class Proto {

        public void run(String xmlfile, String xslfile) {
            Transformer transformer;
            TransformerFactory factory = TransformerFactory.newInstance();

        try {
            StreamSource stylesheet = new StreamSource(xslfile);
            transformer = factory.newTransformer(stylesheet);
            transformer.transform(new StreamSource(xmlfile),
                                  new StreamResult(System.out));
        }
        catch (Exception e) {
            // handle errors...
        }
        :
        :
    }</source>

  <p>This approach seems simple is probably used in many applications. But, the
  use of <code>Templates</code> objects is useful when multiple instances of
  the same <code>Transformer</code> are needed. <code>Transformer</code>
  objects are not thread safe, and if a server wants to handle several clients
  requests it would be best off to create one global <code>Templates</code>
  object, and then from this create a <code>Transformer</code> object for each
  thread handling the requests. This approach is also by far the best for
  XSLTC, as the <code>Templates</code> object will hold the class definitions
  that make up the translet and its auxiliary classes. (Note that the bytecodes
  and not the actuall class definitions are stored when serializing a
  <code>Templates</code> object to disk. This is because of class loader
  security restrictions.) To accomodate this second approach to TrAX
  transformations, the above class would be modified  as follows:</p><source>
    try {
        StreamSource stylesheet = new StreamSource(xslfile);
        Templates templates = factory.newTemplates(stylesheet);
        transformer = templates.newTransformer();
        transformer.transform(new StreamSource(inputFilename),
                              new StreamResult(System.out));
    }
    catch (Exception e) {
        // handle errors...
    }</source>

  </s2>

  <!--====================== TRAX CONFIG SECTION =========================-->

  <anchor name="config"/>
  <s2 title="TrAX configuration">

  <p>JAXP's <code>TransformerFactory</code> is configurable similar to the
  other Java extensions. The API supports configuring thefactory by:</p>

  <ul>
    <li>passing vendor-specific attributes from the application, through the
    TrAX interface, to the underlying XSL processor</li>
    <li>registering an ErrorListener that will be used to pass error and
    warning messages from the XSL processor to the application</li>
    <li>registering an URIResolver that the application can use to load XSL
    and XML documents on behalf of the XSL processor (the XSL processor will
    use this to support the xsl:include and xsl:import elements and the
    document() functions.</li>
  </ul>

  <p>The JAXP TransformerFactory can be queried at runtime to discover what
  features it supports. For example, an application might want to know if a
  particular factory implementation supports the use of SAX events as a source,
  or whether it can write out transformation results as a DOM. The factory API
  queries with the getFeature() method. In the above code, we could add the
  following code before the try-catch block:</p><source>
    if (!factory.getFeature(StreamSource.FEATURE) || !factory.getFeature(StreamResult.FEATURE)) {
        System.err.println("Stream Source/Result not supported by TransformerFactory\nExiting....");
        System.exit(1);
    }</source>

  <p>Other elements in the TrAX API are configurable. A Transformer object can
  be passed settings that override the default output settings and the settings
  defined in the stylesheet for indentation, output document type, etc.</p>

  </s2>

  <!--====================== ARCHITECTURE SECTION ========================-->

  <anchor name="design"/>
  <s2 title="XSLTC TrAX architecture">

  <p>XSLTC's architecture fits nicely in behind the TrAX interface. XSLTC's
  compiler is put behind the <code>TransformerFactory</code> interface, the
  translet class definition (either as a set of in-memory
  <code>Class</code> objects or as a two-dimmensional array of bytecodes on
  disk) is encapsulated in the <code>Templates</code> implementation and the
  instanciated translet object is wrapped inside the <code>Transformer</code>
  implementation. Figure 1 (below) shows this two-layered TrAX architecture:
  </p>
  
  <p><img src="trax_translet_wrapping.gif" alt="TransletWrapping"/></p>
  <p><ref>Figure 1: Translet class definitions are wrapped inside Templates objects</ref></p>

  <p>The <code>TransformerFactory</code> implementation also implements the
  <code>SAXTransformerFactory</code> and <code>ErrorListener</code>
  interfaces from the TrAX API.</p>

  <p>The TrAX implementation has intentionally been kept completely separate
  from the XSLTC native code. This prevents users of XSLTC's native API from
  having to include the TrAX code in an application. All the code that makes
  up our TrAX implementation resides in this package:</p><source>
    org.apache.xalan.xsltc.trax</source>

  <p>Message to all XSLTC developers: Keep it this way! Do not mix TrAX
  and Native code!</p>

  </s2>

  <!--======================= TRAX DESIGN SECTION ========================-->

  <anchor name="detailed_design"/>
  <s2 title="TrAX implementation details">

  <p>The main components of our TrAX implementation are:</p>

  <ul>
    <li><link anchor="transformer_factory">the TransformerFactory class</link></li>
    <li><link anchor="templates">the Templates class</link></li>
    <li><link anchor="transformer">the Transformer class</link></li>
    <li><link anchor="transformer">output properties handling</link></li>
  </ul>

  <anchor name="factory_design"/>
  <s3 title="TransformerFactory implementation">

  <p>The methods that make up the basic <code>TransformerFactory</code>
  iterface are: </p><source>
    public Templates newTemplates(Source source);
    public Transformer newTransformer();
    public ErrorListener getErrorListener();
    public void setErrorListener(ErrorListener listener);
    public Object getAttribute(String name);
    public void setAttribute(String name, Object value);
    public boolean getFeature(String name);
    public URIResolver getURIResolver();
    public void setURIResolver(URIResolver resolver);
    public Source getAssociatedStylesheet(Source src, String media, String title, String charset);</source>

  <p>And for the <code>SAXTransformerFactory</code> interface:</p><source>
    public TemplatesHandler   newTemplatesHandler();
    public TransformerHandler newTransformerHandler();
    public TransformerHandler newTransformerHandler(Source src);
    public TransformerHandler newTransformerHandler(Templates templates);
    public XMLFilter newXMLFilter(Source src);
    public XMLFilter newXMLFilter(Templates templates);</source>

  <p>And for the <code>ErrorListener</code> interface:</p><source>
    public void error(TransformerException exception);
    public void fatalError(TransformerException exception);
    public void warning(TransformerException exception);</source>

  <s4 title="TransformerFactory basics">
    <p>The very core of XSLTC TrAX support for XSLTC is the implementation of
    the basic <code>TransformerFactory</code> interface. This factory class is
    more or less a wrapper around the the XSLTC compiler and creates
    <code>Templates</code> objects in which compiled translet classes can
    reside. These <code>Templates</code> objects can then be used to create
    <code>Transformer</code> objects. In cases where the
    <code>Transformer</code>  is created directly by the factory we will use
    the <code>Templates</code> class internally. In that way the transformation
    will appear to be done in one step from the users point of view, while we
    in reality use to steps. As described earler, this is not the best approach
    when using XSLTC, as it causes the stylesheet to be compiled for each and
    every transformation.</p>
  </s4>

  <s4 title="TransformerFactory attribute settings">
    <p>The <code>getAttribute()</code> and <code>setAttribute()</code> methods
    only recognise two attributes: <code>translet-name</code> and
    <code>debug</code>. The latter is obvious - it forces XSLTC to output debug
    information (dumps the stack in the very unlikely case of a failure). The
    <code>translet-name</code> attribute can be used to set the default class
    name for any nameless translet classes that the factory creates. A nameless
    translet will, for instance, be created when the factory compiles a translet
    for the identity transformation. There is a default name,
    <code>GregorSamsa</code>, for nameless translets, so there is no absolute
    need to set this attribute. (Gregor Samsa is the main character from Kafka's
    &quot;Metamorphosis&quot; - transformations, metamorphosis - I am sure you
    see the connection.)</p>
  </s4>

  <s4 title="TransformerFactory stylesheet handling">
    <p>The compiler is can be passed a stylesheet through various methods in
    the <code>TransformerFactory</code> interface. A stylesheet is passed in as
    a <code>Source</code> object that containin either a DOM, a SAX parser or
    a stream. The <code>getInputSource()</code> method handles all inputs and
    converts them, if necessary, to SAX. The TrAX implementation contains an
    adapter that will generate SAX events from a DOM, and this adapter is used
    for DOM input. If the <code>Source</code> object contains a SAX parser, this
    parser is just passed directly to the compiler. A SAX parse is instanciated
    (using JAXP) if the <code>Source</code> object contains a stream.</p>
  </s4>

  <s4 title="TransformerFactory URI resolver">
    <p>A TransformerFactory needs a <code>URIResolver</code> to locate documents
    that are referenced in <code>&lt;xsl:import&gt;</code> and
    <code>&lt;xsl:include&gt;</code> elements. XSLTC has an internal interface
    that shares the same purpose. This internal interface is implemented by the
    <code>TransformerFactory</code>:</p><source>
    public InputSource loadSource(String href, String context, XSLTC xsltc);</source>
    <p>This method will simply use any defined <code>URIResolver</code> and
    proxy the call on to the URI resolver's <code>resolve()</code> method. This
    method returns a <code>Source</code> object, which is converted to SAX
    events and passed back to the compiler.</p>
  </s4>

  </s3>

  <anchor name="template_design"/>
  <s3 title="Templates design">

  <s4 title="Templates creation">
    <p>The <code>TransformerFactory</code> implementation invokes the XSLTC
    compiler to generate the translet class and auxiliary classes. These classes
    are stored inside our <code>Templates</code> implementation in a manner
    which allows the <code>Templates</code> object to be serialized. By making
    it possible to store <code>Templates</code> on stable storage we allow the
    TrAX user to store/cache translet class(es), thus making room for XSLTC's
    one-compilation-multiple-transformations approach. This was done by giving
    the <code>Templates</code> implementation an array of byte-arrays that
    contain the bytecodes for the translet class and its auxiliary classes. When
    the user first requests a <code>Transformer</code> instance from the
    <code>Templates</code> object for the first time we create one or more
    <code>Class</code> objects from these byte arrays. Note that this is done
    only once as long as the <code>Template</code> object resides in memory. The
    <code>Templates</code> object then invokes the JVM's class loader with the
    class definition(s) to instanciate the translet class(es). The translet
    objects are then wraped inside a <code>Transformer</code> object, which is
    returned to the client code:</p><source>

    // Contains the name of the main translet class
    private String   _transletName = null;

    // Contains the actual class definition for the translet class and
    // any auxiliary classes (representing node sort records, predicates, etc.)
    private byte[][] _bytecodes = null;
    
    /**
     * Defines the translet class and auxiliary classes.
     * Returns a reference to the Class object that defines the main class
     */
    private Class defineTransletClasses() {
	TransletClassLoader loader = getTransletClassLoader();

	try {
	    Class transletClass = null;
	    final int classCount = _bytecodes.length;
	    for (int i = 0; i &lt; classCount; i++) {
		Class clazz = loader.defineClass(_bytecodes[i]);
		if (clazz.getName().equals(_transletName))
		    transletClass = clazz;
	    }
	    return transletClass; // Could still be 'null'
	}
	catch (ClassFormatError e) {
	    return null;
	}
    }</source>
  </s4>

  <s4 title="Translet class loader">

    <p>The <code>Templates</code> object will create the actual translet
    <code>Class</code> object(s) the first time the
    <code>newTransformer()</code> method is called. (The "first time" means the
    first time either after the object was instanciated or the first time after
    it has been read from storage using serialization.) These class(es) cannot
    be created using the standard class loader since the method:</p><source>
    Class defineClass(String name, byte[] b, int off, int len);</source>

    <p>of the ClassLoader is protected. XSLTC uses its own class loader that
    extends the standard class loader:</p><source>
    // Our own private class loader - builds Class definitions from bytecodes
    private class TransletClassLoader extends ClassLoader {
        public Class defineClass(byte[] b) {
            return super.defineClass(null, b, 0, b.length);
        }
    }</source>
    <p>This class loader is instanciated inside a privileged code section:</p><source>
    TransletClassLoader loader = 
        (TransletClassLoader) AccessController.doPrivileged(
            new PrivilegedAction() {
                public Object run() {
                    return new TransletClassLoader();
                }
            }
        );</source>

    <p>Then, when the newTransformer() method returns it passes back and
    instance of XSLTC's <code>Transformer</code> implementation that contains
    an instance of the main translet class. (One transformation may need several
    Java classes - for sort-records, predicates, etc. - but there is always one
    main translet class.)</p>

  </s4>

  <s4 title="Class loader security issues">

    <p>When XSLTC is placed inside a JAR-file in the
    <code>$JAVA_HOME/jre/lib/ext</code> it is loaded by the extensions class
    loader and not the default (bootstrap) class loader. The extensions class
    loader does not look for class files/definitions in the user's
    <code>CLASSPATH</code>. This can cause two problems: A) XSLTC does not find
    classes for external Java functions, and B) XSLTC does not find translet or
    auxiliary classes when used through the native API.</p>

    <p>Both of these problems are caused by XSLTC internally calling the
    <code>Class.forName()</code> method. This method will use the current class
    loader to locate the desired class (be it an external Java class or a
    translet/aux class). This is prevented by forcing XSLTC to use the bootstrap
    class loader, as illustrated below:</p>

    <p><img src="class_loader.gif" alt="ClassLoader"/></p>
    <p><ref>Figure 2: Avoiding the extensions class loader</ref></p>

    <p>These are the steps that XSLTC will go through to load a class:</p>

    <ol>
      <li>the application requests an instance of the transformer factory </li>
      <li>the Java extensions mechanism locates XSLTC as the transformer
      factory implementation using the extensions class loader</li>
      <li>the extensions class loader loads XSLTC</li>
      <li>XSLTC's compiler attempts to get a reference to an external Java
      class, but the call to Class.forName() fails, as the extensions class
      loader does not use the user's class path</li>
      <li>XSLTC attempts to get a reference to the bootstrap class loader, and
      requests it to load the external class</li>
      <li>the bootstrap class loader loads the requested class</li>
    </ol>

    <p>Step 5) is only allowed if XSLTC has special permissions. But, remember
    that this problem only occurs when XSLTC is put in the
    <code>$JAVA_HOME/jre/lib/ext</code> directory, where it is given all
    permissions (by the default security file).</p>

  </s4>

  </s3>

  <anchor name="transformer_design"/>
  <s3 title="Transformer detailed design">

    <p>The <code>Transformer</code> class is a simple proxy that passes
    transformation settings on to its translet instance before it invokes the
    translet's <code>doTransform()</code> method. The <code>Transformer</code>'s
    <code>transform()</code> method maps directly to the translet's
    <code>doTransform()</code> method.</p>

    <s4 title="Transformer input and output handling">
      <p>The <code>Transformer</code> handles its input in a manner similar to
      that of the <code>TransformerFactory</code>. It has two methods for
      creating standard SAX input and output handlers for its input and output
      files:</p><source>
    private DOMImpl getDOM(Source source, int mask);
    private ContentHandler getOutputHandler(Result result);</source>

      <p>One aspect of the <code>getDOM</code> method is that it handles four
      various types of <code>Source</code> objects. In addition to the standard
      DOM, SAX and stream types, it also handles an extended
      <code>XSLTCSource</code> input type. This input type is a lightweight
      wrapper from XSLTC's internal DOM-like input tree. This allows the user
      to create a cache or pool of XSLTC's native input data structures
      containing the input XML document. The <code>XSLTCSource</code> class
      is located in:</p><source>
    org.apache.xalan.xsltc.trax.XSLTCSource</source>
    </s4>

    <s4 title="Transformer parameter settings">
      <p>XSLTC's native interface has get/set methods for stylesheet parameters,
      identical to those of the TrAX API. The parameter handling methods of
      the <code>Transformer</code> implementation are pure proxies.</p>
    </s4>

    <s4 title="Transformer output settings">
      <p>The Transformer interface of TrAX has for methods for retrieving and
      defining the transformation output document settings:</p><source>
    public Properties getOutputProperties();
    public String getOutputProperty(String name);
    public void setOutputProperties(Properties properties);
    public void setOutputProperty(String name, String value);</source>

      <p>There are three levels of output settings. First there are the default
      settings defined in the <link anchor="">XSLT 1.0 spec</link>, then there
      are the settings defined in the attributes of the &lt;xsl:output&gt;
      element, and finally there are the settings passed in through the TrAX
      get/setOutputProperty() methods.</p>

      <p><img src="trax_output_settings.gif" alt="Output settings"/></p>
      <p><ref>Figure 3: Passing output settings from TrAX to the translet</ref></p>

      <p>The AbstractTranslet class has a series of fields that contain the
      default values for the output settings. The compiler/Output class will
      compile code into the translet's constructor that updates these values
      depending on the attributes in the &lt;xsl:output&gt; element. The
      Transformer implementation keeps in instance of the java.util.Properties
      class where it keeps all properties that are set by the
      <code>setOutputProperty()</code> and the
      <code>setOutputProperties()</code> methods. These settings are written to
      the translet's output settings fields prior to initiating the
      transformation.</p>

    </s4>

    <s4 title="Transformer URI resolver">
      <p>The <code>uriResolver()</code> method of the Transformer interface is
      used to set a locator for documents referenced by the document() function
      in XSL. The native XSLTC API has a defined interface for a DocumentCache.
      The functionality provided by XSLTC's internal <code>DocumentCache</code>
      interface is somewhat complimentary to the <code>URIResolver</code>, and
      can be used side-by-side. To acomplish this we needed to find out in which
      ways the translet can load an external document:</p>

      <p><img src="uri_resolver.gif" alt="URIResolver"/></p>
      <p><ref>Figure 4: Using URIResolver and DocumentCache objects</ref></p>

      <p>From the diagram we see that these three ways are:</p>
      <ul>
        <li>LoadDocument -> .xml</li>
        <li>LoadDocument -> DocumentCache -> .xml</li>
        <li>LoadDocument -> URIResolver -> .xml</li>
        <li>LoadDocument -> DocumentCache -> URIResolver -> .xml</li>
      </ul>

    </s4>

    </s3>
  </s2>
</s1>
