
/**
 *  Replicate the SimpleTransform sample, explicitly using the SAX model to handle the
 *  stylesheet, the XML input, and the transformation.
 */

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Templates;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import javax.xml.transform.sax.TransformerHandler;

import org.xml.sax.SAXException;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
import org.xml.sax.XMLReader;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.XMLReaderFactory;

import org.apache.xalan.serialize.SerializerFactory;
import org.apache.xalan.serialize.Serializer;
import org.apache.xalan.templates.OutputProperties;

import java.io.FileOutputStream;
import java.io.IOException;


class ProxyContentHandler implements ContentHandler {
  private ContentHandler contentHandler;

  ProxyContentHandler (ContentHandler contentHandler) {
     this.contentHandler = contentHandler;
     }

  public void characters (char[] ch, int start, int length) throws SAXException {
     contentHandler.characters (ch, start, length);
     }
  public void endDocument () throws SAXException {
     contentHandler.endDocument();
     }
  public void endElement (String namespaceURI, String localName, String qName) throws SAXException {
     contentHandler.endElement(namespaceURI, localName, qName);
     }
  public void endPrefixMapping (String prefix) throws SAXException {
     contentHandler.endPrefixMapping(prefix);
     }
  public void ignorableWhitespace (char[] ch, int start, int length) throws SAXException {
     contentHandler.ignorableWhitespace(ch, start, length);
     }
  public void processingInstruction (String target, String data) throws SAXException {
     contentHandler.processingInstruction(target, data);
     }
  public void setDocumentLocator (Locator locator) {
     contentHandler.setDocumentLocator(locator);
     }
  public void skippedEntity (String name) throws SAXException {
     contentHandler.skippedEntity(name);
     }
  public void startDocument () throws SAXException {
     contentHandler.startDocument();
     }
  public void startElement (String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
  System.out.println ("IN: "+localName);
     contentHandler.startElement(namespaceURI, localName, qName, atts);
     }
  public void startPrefixMapping (String prefix, String uri) throws SAXException {
     contentHandler.startPrefixMapping(prefix, uri);
     }
  }


public class SAX2SAX
{
  public static void main(String[] args)
	throws TransformerException, TransformerConfigurationException,
         SAXException, IOException
	{

    // Instantiate a TransformerFactory.
  	TransformerFactory tFactory = TransformerFactory.newInstance();
    // Determine whether the TransformerFactory supports The use of SAXSource
    // and SAXResult
    if (tFactory.getFeature(SAXSource.FEATURE) && tFactory.getFeature(SAXResult.FEATURE))
    {
      // Cast the TransformerFactory.
      SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory);
      // Create a ContentHandler to handle parsing of the stylesheet.
      TemplatesHandler templatesHandler = saxTFactory.newTemplatesHandler();

      // Create an XMLReader and set its ContentHandler.
      XMLReader reader = XMLReaderFactory.createXMLReader();
      reader.setContentHandler(templatesHandler);

      // Parse the stylesheet.
      reader.parse("birds.xsl");

      //Get the Templates object from the ContentHandler.
      Templates templates = templatesHandler.getTemplates();
      // Create a ContentHandler to handle parsing of the XML source.
      TransformerHandler handler
        = saxTFactory.newTransformerHandler(templates);
      // Reset the XMLReader's ContentHandler.
      reader.setContentHandler (new ProxyContentHandler (handler));

      // Set the ContentHandler to also function as a LexicalHandler, which
      // includes "lexical" events (e.g., comments and CDATA).
      reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler);

   	  FileOutputStream fos = new FileOutputStream("birds.out");

      Serializer serializer = SerializerFactory.getSerializer
                              (OutputProperties.getDefaultMethodProperties("xml"));
      serializer.setOutputStream(/*fos*/System.out);


      // Set the result handling to be a serialization to the file output stream.
      Result result = new SAXResult(serializer.asContentHandler());
      handler.setResult(result);

      // Parse the XML input document.
      reader.parse("birds.xml");

      System.out.println("************* The result is in birds.out *************");
    }
    else
      System.out.println("The TransformerFactory does not support SAX input and SAX output");
  }
}