package com.ejie.ab04b.pdf;

// Imported JAXP-API classes
import java.io.File;
import java.io.Reader;
import java.io.Serializable;

import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamSource;

import org.apache.fop.apps.InputHandler;
import org.apache.fop.messaging.MessageHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;

/**
 * XSLTInputHandler basically takes an xmlfile and transforms it with an
 * xsltfile and the resulting xsl:fo document is input for Fop.
 **/

public class XSLTInputHandler extends InputHandler implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Reader xml;
	private File xsltfile;

	/**
	 * Instantiates a new XSLT input handler.
	 * 
	 *  xml
	 *            the xml
	 *  xsltfile
	 *            the xsltfile
	 *
	 * @param xml the xml
	 * @param xsltfile the xsltfile
	 */
	public XSLTInputHandler(Reader xml, File xsltfile) {
		this.xml = xml;
		this.xsltfile = xsltfile;
	}

	/**
	 * overwrites the method of the super class to return the xmlfile.
	 * 
	 *  the input source
	 *
	 * @return the input source
	 */
	public InputSource getInputSource() {
		return new InputSource(xml);
	}

	/**
	 * overwrites this method of the super class and returns an XMLFilter
	 * instead of a simple XMLReader which allows chaining of transformations.
	 * 
	 *  the parser
	 *
	 * @return the parser
	 */
	public XMLReader getParser() {
		return this.getXMLFilter(xml, xsltfile);
	}

	/**
	 * Creates from the transformer an instance of an XMLFilter which then can
	 * be used in a chain with the XMLReader passed to Driver. This way during
	 * the conversion of the xml file + xslt stylesheet the resulting data is
	 * fed into Fop. This should help to avoid memory problems
	 * 
	 *  driver
	 *            the driver
	 *  XMLFilter an XMLFilter which can be chained together with other
	 *         XMLReaders or XMLFilters
	 *
	 * @param driver the driver
	 */
	public void run(org.apache.fop.apps.Driver driver) {

	}

	/**
	 * Gets the XML filter.
	 * 
	 *  xml
	 *            the xml
	 *  xsltfile
	 *            the xsltfile
	 *  the XML filter
	 *
	 * @param xml the xml
	 * @param xsltfile the xsltfile
	 * @return the XML filter
	 */
	public static XMLFilter getXMLFilter(Reader xml, File xsltfile) {
		try {
			// Instantiate a TransformerFactory.
			TransformerFactory tFactory = TransformerFactory.newInstance();

			// Determine whether the TransformerFactory supports The use uf
			// SAXSource
			// and SAXResult
			if (tFactory.getFeature(SAXSource.FEATURE)
					&& tFactory.getFeature(SAXResult.FEATURE)) {
				// Cast the TransformerFactory to SAXTransformerFactory.
				SAXTransformerFactory saxTFactory = ((SAXTransformerFactory) tFactory);
				// Create an XMLFilter for each stylesheet.
				XMLFilter xmlfilter = saxTFactory
						.newXMLFilter(new StreamSource(xsltfile));

				// Create an XMLReader.
				XMLReader parser = createParser();
				if (parser == null) {
					MessageHandler
							.errorln("ERROR: Unable to create SAX parser");
					// System.exit(1);
				}
				// xmlFilter1 uses the XMLReader as its reader.
				xmlfilter.setParent(parser);
				return xmlfilter;
			} else {
				MessageHandler
						.errorln("Your parser doesn't support the features SAXSource and SAXResult."
								+ "\nMake sure you are using a xsl parser which supports TrAX");
				// System.exit(1);
				return null;
			}
		} catch (Exception ex) {
			// ex.printStackTrace();
			MessageHandler.errorln(ex.toString());
			return null;
		}
	}
}