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

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

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

This sample code illustrates how Xalan/XSLTC can be used to
offer XSL transformations as a web service without using a
full web server. We have chosen to use the Brazil prototype
for the web interface, available from Sunlabs:
    http://www.sun.com/research/brazil/
but we could easily have used some other web interface such
as Tomcat. The supplied Java code implements a Brazil
"handler", which very much resembles a servlet.

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

------------------------------------------------------------
HOW TO INVOKE TRANSLETS FROM A BRAZIL HANDLER

The .CompiledBrazil directory contains the example source code:

    TransformHandler.java

This file contains a minimal implementation of an XSL
transformation handler. The handler performs the same basic
steps as the class implementing the XSLTC command-line tool:

    // 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));

Alternatively the handler can use a cache for storing
frequently accessed XML documents. This is not only a matter
of reading the initial input document from the cache, as
the translet may load other XML input documents as runtime.
(If the xsl:document() function was used in the stylesheet.)

    // 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
    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();
        dom.setDocumentURI(uri);
        parser.setDocumentHandler(dom.getBuilder());

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

        // Parse the input document and build DOM
        parser.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
        dtd.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

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