=======================================================================
CONTENTS OF THIS DOCUMENT:

  o) HOW TO PROVIDE XSL TRANSFORMATIONS AS A WEB SERVICE
  o) HOW TO INVOKE TRANSLETS FROM A SERVLET
  o) BUILDING YOUR OWN DOM CACHE

-----------------------------------------------------------------------
HOW TO PROVIDE XSL TRANSFORMATIONS AS A WEB SERVICE

With XSLTC, XSL transformations can be run from within a servlet. 
This sample code demonstrates how that can be implemented.

The CompiledEJB and CompiledBrazil sample code demonstrate other 
aproaches to providing XSL transformations as a web service.

-----------------------------------------------------------------------
HOW TO INVOKE TRANSLETS FROM A SERVLET

The CompiledServlet directory contains the example source code:

    TransformServlet.java

This file contains a minimal implementation of an XSL transformation 
servlet. It utilizes a cache to store the DOM trees for frequently 
accessed XML documents. These are not W3C DOM objects; They are 
specialized DOMs, native to XSLTC and optimzed for use with compiled 
translets. In addition to the initial input XML documents, the cache 
may contain DOMs for other XML input documents the translet requires 
at runtime, when the xsl:document() function is used in the stylesheet.

Here's the essential code in the servlet for doing the transformation:

    // Get a reference to the translet class
    Class cls = Class.forName(transletName);

    // Instanciate a translet object (inherits AbstractTranslet)
    AbstractTranslet translet = (AbstractTranslet)cls.newInstance();

    // The translet needs a reference to the cache in case
    // in needs to load additional XML documents.
    translet.setDOMCache(cache);

    // Get the DOM from the DOM cache if current, otherwise
    // build and cache the DOM first
    DOMImpl dom = cache.retrieveDocument(documentURI, 0, translet);

    // Create output handler (you can plug in your own)
    DefaultSAXOutputHandler saxHandler;
    saxHandler = new DefaultSAXOutputHandler(out);

    // Start the transformation
    translet.transform(dom, new TextOutput(saxHandler));

-----------------------------------------------------------------------
BUILDING YOUR OWN DOM CACHE

The interface for the DOM cache consists of a single method,
and its definition can be found in:

    org/apache/xalan/xsltc/DOMCache.java

The method contained in the interface is:

    public DOMImpl retrieveDocument(String uri,
                                    int mask,
                                    Translet translet);

The responsibilities of this method are:

 A) Build new a DOMImpl and DTDMonitor for XML documents
    that are not already in the cache:

        // Instanciate a DOMImpl object
        Parser  parser = new Parser();
        DOMImpl dom = new DOMImpl();
        // Set URI for imports, includes, and document() functions
        dom.setDocumentURI(uri);
        parser = factory.newSAXParser();
        reader = parser.getXMLReader();
        reader.setContentHandler(dom.getBuilder());

        // Use a DTDMonitor to track ID references in DTD
        DTDMonitor dtdMonitor = new DTDMonitor();
        dtdMonitor.handleDTD(reader);

        // Parse the input document and build DOM
        reader.parse(uri);

    At this point the DOMImpl and DTDMonitor objects are
    populated with the necessary data. The two objects
    are ready to be put in the cache (using the URI as
    the lookup key).

 B) For each time a new document is requested by a translet:

        // Expand translet's index array to fit this DOM
        translet.setIndexSize(dom.getSize());

        // Build indices for this DOM's DTD's ID references
        dtdMonitor.buildIdIndex(dom, mask, translet);

        // Pass unparsed entity URIs to the translet
        translet.setUnparsedEntityURIs(dtd.getUnparsedEntityURIs());

Step A) must be done every time a document is read into the
cache, and step B) every time a document is given to a
translet.

The XSLTC package contains an example implementation of a
DOM cache, based on a very simple round-robin caching
algorithm:

    org/apache/xalan/xsltc/dom/DocumentCache.java

-----------------------------------------------------------------------
DOING TRANSFORMATIONS WITHOUT A DOM CACHE

Alternatively, you can program a servlet to perform the same basic
steps as the XSLTC command-line tool

    org.apache.xalan.xsltc.cmdline.Transform

as follows:


    // Obtain a reference to the translet class
    Class cls = Class.forName(transletName);
    // Instanciate a translet object (inherits AbstractTranslet)
    AbstractTranslet translet = (AbstractTranslet)cls.newInstance();

    // Prepare the internal DOM tree
    final DOMImpl dom = new DOMImpl();
    dom.setDocumentURI(inputURI);

    // Create a parser for the input document
    // org.apache.xalan.xsltc.runtime.Constants sets NAMESPACE_FEATURE
    final SAXParserFactory facory = SAXFactory.newInstance();
    try {
      factory.setFeature(NAMESPACE_FEATURE,true);
    }
    catch (Exception e) {
      factory.setNamespaceAware(true);
    }
    parser = factory.newSAXParser();
    reader = parser.getXMLReader();
    reader.setContentHandler(dom.getBuilder());

    // Create a DTDMonitor for handling ID references in the DTD
    DTDMonitor dtdMonitor = new DTDMonitor();
    dtdMonitor.handleDTD(reader);

    // Create output handler (you can plug in your own)
    DefaultSAXOutputHandler saxHandler;
    saxHandler = new DefaultSAXOutputHandler(out);

    // Parse the document and build the internal DOM
    reader.parse(inputURI);

    // Pass information on id/key indicies to the translet
    translet.setIndexSize(dom.getSize());
    dtdMonitor.buildIdIndex(dom, 0, translet);
    translet.setUnparsedEntityURIs(dtdMonitor.getUnparsedEntityURIs());

    // Start the transformation
    translet.transform(dom, new TextOutput(saxHandler));


------------------------------------------------------------
END OF README
