============================================================
         README FILE FOR THE SUN XSLT COMPILER API
                  Preview Version 5 
                    February, 2001
============================================================
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
============================================================

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
