import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
 
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.XMLFilter;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.transform.Transformer;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerConfigurationException;

import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXResult;

import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.EntityResolver;

import java.io.*;

public class FilterChain
{
    public static void main (String argv [])
    {
  
	try {
	    // Read the arguments
	    File stylesheet = new File("test.xsl");
	    File datafile    = new File("test.xml");

	    // Setup reusable templates
	    TransformerFactory tFactory =
		TransformerFactory.newInstance();
	    Templates template = 
		tFactory.newTemplates(new StreamSource(stylesheet));

	    // Set up to read the input file
	    SAXParserFactory spf = SAXParserFactory.newInstance();
	    spf.setNamespaceAware( true );
	    spf.setValidating( false );
	    SAXParser parser = spf.newSAXParser();
	    XMLReader reader = parser.getXMLReader();
	    reader.setEntityResolver(new DummyEntityResolver());
    
	    // Set up the output stream
	    StreamResult result = new StreamResult(System.out);

      
	    // Set up the input stream
	    BufferedInputStream bis = 
		new BufferedInputStream(new FileInputStream(datafile));

	    // Create the filters
	    SAXTransformerFactory stf =
		(SAXTransformerFactory) tFactory;
	    XMLFilter filter = stf.newXMLFilter(template);

	    filter.setParent(reader);

	    // Set up the transformer to process the SAX events 
	    // generated by the last filter in the chain
	    Transformer transformer = stf.newTransformer();

	    // transformer.setOutputProperty("omit-xml-declaration", "yes");
	    SAXSource transformSource = 
		new SAXSource(filter, new InputSource(bis));
	    transformer.transform(transformSource, result);
	}
	catch (TransformerConfigurationException tce) {
	    // Error generated by the parser
	    System.out.println ("\n** Transformer Factory error");
	    System.out.println("   " + tce.getMessage() );
      
	    // Use the contained exception, if any
	    Throwable x = tce;
	    if (tce.getException() != null)
		x = tce.getException();
	    x.printStackTrace();
	}
	catch (TransformerException te) {
	    // Error generated by the parser
	    System.out.println ("\n** Transformation error");
	    System.out.println("   " + te.getMessage() );
      
	    // Use the contained exception, if any
	    Throwable x = te;
	    if (te.getException() != null)
		x = te.getException();
	    x.printStackTrace();
	}
	catch (SAXException sxe) {
	    // Error generated by this application
	    // (or a parser-initialization error)
	    Exception  x = sxe;
	    if (sxe.getException() != null)
		x = sxe.getException();
	    x.printStackTrace();
	}
	catch (ParserConfigurationException pce) {
	    // Parser with specified options can't be built
	    pce.printStackTrace();
	}
	catch (IOException ioe) {
	    // I/O error
	    ioe.printStackTrace();
	}

    } // main

};

class DummyEntityResolver implements EntityResolver 
{ 
    public InputSource resolveEntity (String publicId, String systemId) 
    {
	try {
	    return new InputSource(new StringReader("")); 
	} catch (Exception e) {
	    System.out.println("Caught exception in DummyEntityResolver");
	}
	return null;
    } 
}; 
