
package com.ejie.ad74a.util.pid;

import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.DOMSource;

/**
 * Permite efectuar transformaciones de una fuente xml. <br>
 * <br>
 * El producto de una transformaci�n se denomina resultado. Una transformaci�n
 * puede utilizar o no instrucciones xsl.
 */

public final class XmlTransformer {

	private Transformer transformer;

	private Source source;

	/** Construye un objeto de la clase. */

	public XmlTransformer() {

		transformer = null;
		source = null;
	}

	/**
	 * Crea un transformador sin instrucciones xsl.
	 * 
	 * @throws Exception si se produce alg�n error.
	 */

	public void create() throws Exception {

		TransformerFactory fry;

		fry = TransformerFactory.newInstance();

		try {
			transformer = fry.newTransformer();
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		}

	}

	/**
	 * Crea un transformador con instrucciones xsl.
	 * 
	 * @param pathname Ruta de acceso y nombre del fichero xsl con las
	 *                 instrucciones.
	 * @throws Exception si se produce alg�n error.
	 */

	public void createUsingXslFile(final String pathname) throws Exception {

		TransformerFactory fry;
		StreamSource xsl;

		fry = TransformerFactory.newInstance();
		xsl = new StreamSource(new File(pathname));

		try {
			transformer = fry.newTransformer(xsl);
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		}

	}

	/**
	 * Crea un transformador con instrucciones xsl.
	 * 
	 * @param pathname Ruta de acceso y nombre del fichero xsl con las
	 *                 instrucciones.
	 * @throws Exception, IOException si se produce alg�n error.
	 */

	public void createUsingXslResourceFile(final String pathname) throws Exception, IOException {

		TransformerFactory fry;
		StreamSource xsl;
		InputStream inputStream = null;

		try {
			fry = TransformerFactory.newInstance();
			inputStream = ClassLoader.getSystemResourceAsStream(pathname);
			xsl = new StreamSource(inputStream);
			transformer = fry.newTransformer(xsl);
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		} finally {
			if (inputStream != null) {
				inputStream.close();
			}
		}

	}

	/**
	 * Crea un transformador con instrucciones xsl.
	 * 
	 * @param text Texto xsl con las instrucciones.
	 * @throws Exception si se produce alg�n error.
	 */

	public void createUsingXslStringText(final String text) throws Exception {

		TransformerFactory fry;
		StreamSource xsl;

		fry = TransformerFactory.newInstance();
		xsl = new StreamSource(new StringReader(text));

		try {
			transformer = fry.newTransformer(xsl);
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		}

	}

	/**
	 * Crea un transformador con instrucciones xsl.
	 * 
	 * @param text Texto xsl, codificado en UTF-8, con las instrucciones.
	 * @throws Exception si se produce alg�n error.
	 */

	public void createUsingXslUtf8Text(final byte[] text) throws Exception {

		TransformerFactory fry;
		StreamSource xsl;

		fry = TransformerFactory.newInstance();
		xsl = new StreamSource(new ByteArrayInputStream(text));

		try {
			transformer = fry.newTransformer(xsl);
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		}

	}

	/**
	 * Crea un transformador con instrucciones xsl.
	 * 
	 * @param doc Documento xsl con las instrucciones.
	 * @throws Exception si se produce alg�n error.
	 */

	/*
	 * NO FUNCIONA public void createUsingXslDocument(XmlDocument doc) throws
	 * Exception {
	 * 
	 * TransformerFactory fry; DOMSource xsl;
	 * 
	 * fry = TransformerFactory.newInstance(); xsl = new
	 * DOMSource(doc.getDomDocument()); transformer = fry.newTransformer(xsl); }
	 */

	/**
	 * Establece la fuente de la transformaci�n.
	 * 
	 * @param pathname Ruta de acceso y nombre del fichero xml con la fuente.
	 */

	public void setSourceFromXmlFile(final String pathname) {

		source = new StreamSource(new File(pathname));
	}

	/**
	 * Establece la fuente de la transformaci�n.
	 * 
	 * @param text Texto xml con la fuente.
	 */

	public void setSourceFromXmlStringText(String text) {

		source = new StreamSource(new StringReader(text));
	}

	/**
	 * Establece la fuente de la transformaci�n.
	 * 
	 * @param text Texto xml, codificado en UTF-8, con la fuente.
	 */

	public void setSourceFromXmlUtf8Text(byte[] text) {

		source = new StreamSource(new ByteArrayInputStream(text));
	}

	/**
	 * Establece la fuente de la transformaci�n.
	 * 
	 * @param doc Documento xml con la fuente.
	 */

	public void setSourceFromXmlDocument(XmlDocument doc) {

		source = new DOMSource(doc.getDomDocument());
	}

	/**
	 * Establece la fuente de la transformaci�n.
	 * 
	 * @param elem Elemento xml con la fuente.
	 */

	public void setSourceFromXmlElement(XmlElement elem) {

		source = new DOMSource(elem.getDomElement());
	}

	/**
	 * Efect�a la transformaci�n.
	 * 
	 * @return Texto con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public String transformToStringText() throws Exception {

		StreamResult res;
		StringWriter resWriter;

		resWriter = new StringWriter();
		res = new StreamResult(resWriter);

		try {
			transformer.transform(source, res);
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		}

		return resWriter.toString();

	}

	/**
	 * Efect�a la transformaci�n.
	 * 
	 * @return Texto, codificado en UTF-8, con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public byte[] transformToUtf8Text() throws Exception {

		StreamResult res;
		ByteArrayOutputStream resStream;

		resStream = new ByteArrayOutputStream();
		res = new StreamResult(resStream);

		try {
			transformer.transform(source, res);
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		}

		return resStream.toByteArray();

	}

	/**
	 * Efect�a la transformaci�n.
	 * 
	 * @param pathname Ruta de acceso y nombre del fichero en el que se almacena el
	 *                 resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public void transformToFile(String pathname) throws Exception {

		StreamResult res;

		res = new StreamResult(new File(pathname));

		try {
			transformer.transform(source, res);
		} catch (Exception exc) {
			throw new Exception("" + XmlErrorCodes.EC_TRANSFORM_EXCEPTION, exc);
		}

	}

	/**
	 * Permite especificar si en el resultado de una transformaci�n se omite la
	 * declaraci�n Xml.
	 * 
	 * @param omit Especifica si omitir la declaraci�n xml.
	 */

	public void setOmitXmlDeclarationInOutput(boolean omit) {

		String text;

		if (omit) {
			text = "yes";
		} else {
			text = "no";
		}
		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, text);

	}

	/** Permite especificar que el resultado de una transformaci�n es xml. */

	public void setXmlOutputMethod() {

		transformer.setOutputProperty(OutputKeys.METHOD, "xml");
	}

	/** Permite especificar que el resultado de una transformaci�n es html. */

	public void setHtmlOutputMethod() {

		transformer.setOutputProperty(OutputKeys.METHOD, "html");
	}

	/**
	 * Hace que xml de salida este indentado (pretty print)
	 * 
	 * @param indentAmount numero de caracteres de que consta una indentacion
	 */
	public void setIndentation(int indentAmount) {
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(indentAmount));
	}

	/**
	 * Efect�a la transformaci�n de una fuente xml sin utilizar instrucciones xsl.
	 * 
	 * @param xmlDoc     Documento xml con la fuente.
	 * @param omitXmlHdr Especifica si omitir la cabecera xml en el resultado.
	 * @return Texto xml con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static String transformXmlDocumentToXmlStringText(XmlDocument xmlDoc, boolean omitXmlHdr) throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.create();
		transformer.setSourceFromXmlDocument(xmlDoc);
		transformer.setOmitXmlDeclarationInOutput(omitXmlHdr);

		return transformer.transformToStringText();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml sin utilizar instrucciones xsl.
	 * 
	 * @param xmlDoc     Documento xml con la fuente.
	 * @param omitXmlHdr Especifica si omitir la cabecera xml en el resultado.
	 * @return Texto xml, codificado en UTF-8, con el resultado de la
	 *         transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static byte[] transformXmlDocumentToXmlUtf8Text(XmlDocument xmlDoc, boolean omitXmlHdr) throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.create();
		transformer.setSourceFromXmlDocument(xmlDoc);
		transformer.setOmitXmlDeclarationInOutput(omitXmlHdr);

		return transformer.transformToUtf8Text();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml sin utilizar instrucciones xsl.
	 * 
	 * @param xmlDoc       Documento xml con la fuente.
	 * @param filePathName Ruta de acceso y nombre del fichero en el que se almacena
	 *                     el resultado xml de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static void transformXmlDocumentToXmlFile(XmlDocument xmlDoc, String filePathName) throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.create();
		transformer.setSourceFromXmlDocument(xmlDoc);

		transformer.transformToFile(filePathName);

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml sin utilizar instrucciones xsl.
	 * 
	 * @param xmlElem    Elemento xml con la fuente.
	 * @param omitXmlHdr Especifica si omitir la cabecera xml.
	 * @return Texto xml con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static String transformXmlElementToXmlStringText(XmlElement xmlElem, boolean omitXmlHdr) throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.create();
		transformer.setSourceFromXmlElement(xmlElem);
		transformer.setOmitXmlDeclarationInOutput(omitXmlHdr);

		return transformer.transformToStringText();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml sin utilizar instrucciones xsl.
	 * 
	 * @param xmlElem    Elemento xml con la fuente.
	 * @param omitXmlHdr Especifica si omitir la cabecera xml.
	 * @return Texto xml, codificado en UTF-8, con el resultado de la
	 *         transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static byte[] transformXmlElementToXmlUtf8Text(XmlElement xmlElem, boolean omitXmlHdr) throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.create();
		transformer.setSourceFromXmlElement(xmlElem);
		transformer.setOmitXmlDeclarationInOutput(omitXmlHdr);

		return transformer.transformToUtf8Text();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml utilizando instrucciones xsl.
	 * 
	 * @param xmlDoc          Documento xml con la fuente.
	 * @param xslFilePathName Ruta de acceso y nombre del fichero xsl con las
	 *                        instrucciones.
	 * @return Texto html con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static String transformXmlDocumentToHtmlStringTextUsingXslFile(XmlDocument xmlDoc, String xslFilePathName)
			throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslFile(xslFilePathName);
		transformer.setSourceFromXmlDocument(xmlDoc);
		transformer.setHtmlOutputMethod();

		return transformer.transformToStringText();

	}

	public static byte[] transformXmlDocumentToHtmlUtf8TextUsingXslFile(XmlDocument xmlDoc, String xslFilePathName)
			throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslFile(xslFilePathName);
		transformer.setSourceFromXmlDocument(xmlDoc);
		transformer.setHtmlOutputMethod();

		return transformer.transformToUtf8Text();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml utilizando instrucciones xsl.
	 * 
	 * @param xmlDoc          Documento xml con la fuente.
	 * @param xslFilePathName Ruta de acceso y nombre del fichero xsl con las
	 *                        instrucciones.
	 * @return Texto html con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static String transformXmlUtf8ToHtmlStringTextUsingXslFile(byte[] xmlDoc, String xslFilePathName)
			throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslFile(xslFilePathName);
		transformer.setSourceFromXmlUtf8Text(xmlDoc);
		transformer.setHtmlOutputMethod();

		return transformer.transformToStringText();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml, en UTF-8, utilizando
	 * instrucciones xsl.
	 * 
	 * @param xmlDoc Documento xml con la fuente.
	 * @param xslDoc Contenido del documento xsl con las instrucciones.
	 * @return Texto html con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */
	public static String transformXmlUtf8ToHtmlStringTextUsingXslText(byte[] xmlDoc, String xslDoc) throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslStringText(xslDoc);
		transformer.setSourceFromXmlUtf8Text(xmlDoc);
		transformer.setHtmlOutputMethod();

		return transformer.transformToStringText();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml, en ISO-8859-1, utilizando
	 * instrucciones xsl.
	 * 
	 * @param xmlDoc Documento xml con la fuente.
	 * @param xslDoc Contenido del documento xsl con las instrucciones.
	 * @return Texto html con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */
	public static String transformXmlStringToHtmlStringTextUsingXslText(String xmlDoc, String xslDoc) throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslStringText(xslDoc);
		transformer.setSourceFromXmlStringText(xmlDoc);
		transformer.setHtmlOutputMethod();

		return transformer.transformToStringText();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml utilizando instrucciones xsl.
	 * 
	 * @param xmlDoc          Documento xml con la fuente.
	 * @param xslFilePathName Ruta de acceso y nombre del fichero xsl con las
	 *                        instrucciones.
	 * @return Texto html con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static String transformXmlUtf8ToHtmlStringTextUsingXslResourceFile(byte[] xmlDoc, String xslFilePathName)
			throws Exception, IOException {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslResourceFile(xslFilePathName);
		transformer.setSourceFromXmlUtf8Text(xmlDoc);
		transformer.setHtmlOutputMethod();

		return transformer.transformToStringText();

	}

	public static byte[] transformXmlStringToHtmlUtf8TextUsingXslFile(String xmlDoc, String xslFilePathName)
			throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslFile(xslFilePathName);
		transformer.setSourceFromXmlStringText(xmlDoc);
		transformer.setHtmlOutputMethod();

		return transformer.transformToUtf8Text();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml utilizando instrucciones xsl.
	 * 
	 * @param xmlFilePathName Ruta de acceso y nombre del fichero xml con la fuente.
	 * @param xslFilePathName Ruta de acceso y nombre del fichero xsl con las
	 *                        instrucciones.
	 * @return Texto html con el resultado de la transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static String transformXmlFileToHtmlStringTextUsingXslFile(String xmlFilePathName, String xslFilePathName)
			throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslFile(xslFilePathName);
		transformer.setSourceFromXmlFile(xmlFilePathName);
		transformer.setHtmlOutputMethod();

		return transformer.transformToStringText();

	}

	/**
	 * Efect�a la transformaci�n de una fuente xml utilizando instrucciones xsl.
	 * 
	 * @param xmlFilePathName Ruta de acceso y nombre del fichero xml con la fuente.
	 * @param xslFilePathName Ruta de acceso y nombre del fichero xsl con las
	 *                        instrucciones.
	 * @return Texto html, codificado en UTF-8, con el resultado de la
	 *         transformaci�n.
	 * @throws Exception si se produce alg�n error.
	 */

	public static byte[] transformXmlFileToHtmlUtf8TextUsingXslFile(String xmlFilePathName, String xslFilePathName)
			throws Exception {

		XmlTransformer transformer;

		transformer = new XmlTransformer();

		transformer.createUsingXslFile(xslFilePathName);
		transformer.setSourceFromXmlFile(xmlFilePathName);
		transformer.setHtmlOutputMethod();

		return transformer.transformToUtf8Text();

	}

} // class XmlTransformer
