============================================================
         README FILE FOR THE SUN XSLT COMPILER API
                  Preview Version 5 
                    February, 2001
           Copyright (c) Sun Microsystems, 2001
============================================================

The Sun XSLT Compiler (XSLTC) is a Java-based tool for 
compiling XSL stylesheets into extremely lightweight and 
portable Java byte code. The Sun XSLTC Java Runtime environment 
can then process XML files against these compiled stylesheets 
(Translets) to generate any manner of output per the style-
sheet instructions.

CONTENTS OF THIS DOCUMENT:
	1. HOW TO INCLUDE TRANSLETS IN YOUR APPLICATIONS
	2. FULL CODE EXAMPLE 1, (uses a SAX DocumentHandler).
	3. COMPILING AND RUNNING THE EXAMPLE 
	4. FULL CODE EXAMPLE 2, (uses DefaultSAXOutputHandler). 
	5. APPENDIX (TextOut and DefaultSAXOutputHandler)




1. HOW TO INCLUDE TRANSLETS IN YOUR APPLICATIONS
---------------------------------------------------------------------

Translets implement the interface com.sun.xslt.Translet
that you will find in the src directory.

public interface Translet {
    public void transform(DOM document, TransletOutputHandler handler)
	throws TransletException;

    public void transform(DOM document, TransletOutputHandler[] handlers)
	throws TransletException;

    public void transform(DOM document, NodeIterator iterator,
                          TransletOutputHandler handler) throws 
			  TransletException;

    public Object addParameter(String name, Object value);

    public void buildKeys(DOM document, NodeIterator iterator,
                          TransletOutputHandler handler, int root) throws 
			  TransletException;

    public String getOutputEncoding();
}

The Translet takes a DOMImpl object (created from an input XML document),
as input and transforms it. The results of the transformation are 
sent to an  event-based output handler that implements the 
com.sun.xslt.TransletOutputHandler interface :


public interface com.sun.xslt.TransletOutputHandler {
    public void startDocument() throws TransletException;
    public void endDocument() throws TransletException;
    public void characters(char[] characters, int offset, int length)
        throws TransletException;
    public void startElement(String elementName) throws TransletException;
    public void endElement(String elementName) throws TransletException;
    public void attribute(String attributeName, String attributeValue)
        throws TransletException;
    public void comment(String comment) throws TransletException;
    public void processingInstruction(String target, String data)
        throws TransletException;
    public void setType(int type);
    public void setIndent(boolean indent);
    public boolean setEscaping(boolean escape) throws TransletException;
    public void insertCdataElement(String elementName);
}


You create an instance of the class that implements the Translet interface
using Java reflection:

  Class clazz = Class.forName("classname");
  Translet translet = (Translet) clazz.newInstance();

where "classname" is the name of the class generated by XSLTC.
In order to execute a transformation, both a document and a SAX-like
handler (TransletOutputHandler) are needed.
A document instance can be created with the aid of SAX-complaint XML parser.
For example, using Sun's parser you would write,

  import com.sun.xslt.dom.DOMImpl;
  import com.sun.xml.parser.Parser;
  import com.sun.xml.parser.Resolver;

  // Create new instances of DOM and Parser
  DOMImpl dom = new DOMImpl();
  Parser parser = new Parser();

  // Set a SAX handler to build a DOM tree
  parser.setDocumentHandler(dom.getBuilder());

  // Parse the document and build a DOM tree
  InputSource input = new InputSource(
                          new FileReader("xmlfile.xml"));
  parser.parse(input);
  
In this example a document is parsed from a file, but it is also 
possible to parse a document from a URI by writing,

  parser.parse("http://.../xmlfile.xml");

To transform the input XML document, a call is made to the translet's
transform() method. In order to do its work, the transform() method
takes two arguments, (1) the DOMImpl object created from parsing
the input XML document, and (2) an output handler. The output handler
must implement the org.xml.sax.DocumentHandler interface.  You 
have the option of: (1) writing your own class that implements 
DocumentHandler, or (2) using our default class
'com.sun.xslt.runtime.DefaultSAXOutputHandler' instead.  
The source code for our DefaultSAXOutputHandler is included
in this package in the com/sun/xslt/runtime directory. 
This is a change from the previous releases of
our compiler API. If you  wanted to create your own 
output handler in previous releases, you would have write a class that 
implemented the interface TransletOutputHandler. This change was made
so that users could more easily plug in any SAX compliant output
handler. To plug in the SAX compliant output handler,
(whether it is a user written class or our DefaultSAXOutputHandler)
into the transform() method, it must be wrapped in a
TextOutput object first. 

The Translet.transform() method may also take an array of output handlers. 
In this case the transformation will be able to select which handler 
to send output to by using the extension element <translet:output port="n"> 
where 'n' is a 0-based index in the array of output handlers.

Lets take a look at the code needed to carry out both of the options
for passing the SAX output handler to the translet's transform() method:

   (1) You would write your own output handler that implements
       the org.xml.sax.DocumentHandler interface, pass this class
       into our com.sun.xslt.runtime.TextOutput class which itself
       implements the TransletOutputHandler interface.

   (2) You would create an instance of the default SAX output handler,
       com.sun.xslt.runtime.DefaultSAXOutputHandler, pass this
       instance into our com.sun.xslt.runtime.TextOutput class which
       itself implements the TransletOutputHandler interface.


In option (1), we want to use a SAX compliant output handler that we write
ourselves. In this case we create our Handler class, which implements 
org.xml.sax.DocumentHandler:

import org.xml.sax.DocumentHandler;

// user supplied SAX Handler:
class Handler implements DocumentHandler {
    public void startDocument() throws SAXException {}

    public void endDocument() throws SAXException {}

    public void characters(char[] characters, int offset, int length)
        throws SAXException
    {
        System.out.println(new String(characters, offset, length));
    }
    public void startElement(String elementName, AttributeList attrs)
        throws SAXException {}
    public void endElement(String elementName) throws SAXException {}
    public void setDocumentLocator(Locator loc) {}
    public void ignorableWhitespace(char[] characters, int offset, int length)
        throws SAXException {}
    public void processingInstruction(String target, String data)
        throws SAXException {}
}

Now before we pass our handler to the transform() method, we wrap it
in a TextOutput object (which implements the TransletOutputHandler
interface for us).  Then given the instantiated translet class, 
the transform method could be called as:

	import com.sun.xslt.runtime.TextOutput;

	DOMImpl dom;
        ...
        Handler saxHandler;
        TextOutput textOutput;
        try {
            saxHandler = new Handler();
            textOutput = new TextOutput(saxHandler);
            translet.transform(dom, textOutput);
        } catch (TransletException  e){
	    ...
        } catch (IOException  e){
	    ...
        }


By using the TextOutput wrapper class, one can also control the character
encoding. The TextOutput class has an additional constructor that takes
the DocumentHandler and a String that describes the encoding, for example
'textOutput' could have been created as:

	textOutput = new TextOutput(saxHandler, "utf-8");

Finally, option (2) is much like option (1) except you do not have
to write your own DocumentHandler. We provide one by default. To use the
default one, instantiate 'com.sun.xslt.runtime.DefaultSAXOutputHandler'
rather than instantiating your own class (such as Handler above):

	import com.sun.xslt.runtime.DefaultSAXOutputHandler;
	import com.sun.xslt.runtime.TextOutput;

	DefaultSAXOutputHandler defhandlr;
	try {
            defhandlr = new DefaultSAXOutputHandler(System.out, "utf-8");
            translet.transform(dom, new TextOutput(defhandlr));
        } catch (TransletException  e){
	    ...
        } catch (IOException  e){
	    ...
        }

For a quick reference to the TextOutput and DefaultSAXOutputHandler
constructors available, see the Appendix. 

In the following sections, full code examples are shown.
	
Finally, if you want the transformation results in the DOM form:

DOM result = new DOM();
translet.transform(dom, result.getOutputDomBuilder());

If the compiled stylesheet requires the values of global 
parameters to be set, you should call addParameter() before 
calling the transform() method.

 
2. FULL CODE EXAMPLE 1, XsltApp.java, uses a SAX DocumentHandler.
	This example corresponds to option (1) in discussion above.
------------------------------------------------------------------
import java.io.FileReader;
import java.io.IOException;
import com.sun.xslt.dom.DOMImpl;
import com.sun.xslt.runtime.TextOutput;
import com.sun.xslt.Translet;
import com.sun.xslt.TransletException;
import com.sun.xml.parser.Parser;
import org.xml.sax.AttributeList;
import org.xml.sax.DocumentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;


// Create a SAX Output Handler
class Handler implements DocumentHandler {
    public void startDocument() throws SAXException {}

    public void endDocument() throws SAXException {}

    public void characters(char[] characters, int offset, int length)
        throws SAXException
    {
        System.out.println(new String(characters, offset, length));
    }

    public void startElement(String elementName, AttributeList attrs)
        throws SAXException {}

    public void endElement(String elementName) throws SAXException {}

    public void setDocumentLocator(Locator loc) {}

    public void ignorableWhitespace(char[] characters, int offset, int length)
        throws SAXException {}

    public void processingInstruction(String target, String data)
        throws SAXException {}

}

public class XsltApp {
   public static void main(String[] args){
        XsltApp app = new XsltApp();
        app.run(args);
   }

   public void run(String[] args){
        if(args.length != 2){
                usage();
        }
        String inputFileName = args[0];
        String transletName = args[1];

        DOMImpl dom = new DOMImpl();
        Parser parser = new Parser();
        parser.setDocumentHandler(dom.getBuilder());
        InputSource input = null;
        try {
            input = new InputSource(new FileReader(inputFileName));
        } catch( java.io.FileNotFoundException e){
            System.err.println("File " + inputFileName + " not found");
            System.exit(1);
        }

        try {
            parser.parse(input);
        } catch (org.xml.sax.SAXException e){
            System.err.println("Error: " + e);
            System.exit(1);
        } catch (IOException e){
            System.err.println("Error: " + e);
            System.exit(1);
        }

        Class transletPluggable = null;
        try {
            transletPluggable = Class.forName(transletName);
        } catch (java.lang.ClassNotFoundException e){
            System.err.println("Error: " + e);
            System.exit(1);
        }

        Translet translet = null;
        try {
            translet = (Translet)transletPluggable.newInstance();
        } catch (java.lang.Exception e){
            System.err.println("Error instantiating pluggable translet");
            System.exit(1);
        }

        Handler saxHandler;
        TextOutput textOutput;
        try {
            saxHandler = new Handler();
            textOutput = new TextOutput(saxHandler, "utf-8");
            translet.transform(dom, textOutput);
        } catch (TransletException  e){
            System.err.println("Error: " + e);
            System.exit(1);
        } catch (IOException  e){
            System.err.println("Error: " + e);
            System.exit(1);
        }
   }

   public void usage(){
        System.out.println("Usage: \n" +
                "     xsltapp <xml_file> <translet_name>\n\n" +
                "     where <file> is xml source (e.g. play.xml). \n" +
                "     and  <translet_name> is java class (e.g. play1). \n"
        );
        System.exit(1);
   }
}



3. COMPILING AND RUNNING THE EXAMPLE:
---------------------------------------------------------------------

To compile the example above, assuming you unpacked the code
into the directory /tmp:

javac -classpath "/tmp/xsltc/lib/xml.jar:/tmp/xsltc/lib/BCEL.jar:/tmp/xsltc
/lib/xsltcrt.jar" XsltApp.java

To run the example on xml document 'play.xml' and stylesheet 'play1.xsl':

(1) compile the stylesheet:
        xsltc play1.xsl
 
    this will produce the translet 'play1.class'.

(2) run the translet with the XsltApp demo:

java -classpath /tmp/xsltc/lib/xsltcrt.jar:/tmp/xsltc/lib/xml.jar:. XsltApp play
.xml play1


 
4. FULL CODE EXAMPLE 2, DefaultRun.java
	This example corresponds to option (2) in the discussion above.
------------------------------------------------------------------
See the source file for the class 'com.sun.xslt.runtime.DefaultRun',
which is included in the src directory. It uses the 
'DefaultSAXOutputHandler' approach.




5. APPENDIX
------------------------------------------------------------------

TextOutput
----------

package com.sun.xslt.runtime;

public final class TextOutput implements TransletOutputHandler {
	public TextOutput(DocumentHandler handler) throws IOException;
	public TextOutput(DocumentHandler handler, String encoding) throws
		IOException;
}


DefaultSAXOutputHandler
-----------------------
package com.sun.xslt.runtime;

public class DefaultSAXOutputHandler implements DocumentHandler{
	public DefaultSAXOutputHandler(Writer writer) throws IOException;
	public DefaultSAXOutputHandler(OutputStream out, String encoding)
	    throws IOException;
	public DefaultSAXOutputHandler(String filename, String encoding)
            throws IOException;
	...
}



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