//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.common.xml;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.epf.common.CommonPlugin;

/**
 * A wrapper over the XSLT processor bundled with the JRE.
 * 
 * @author Kelvin Low
 * @since 1.0
 */
public class XSLTProcessor {

	// If true, cache the compiled the XSL transformer with the compiled XSL
	// templates.
	private static boolean cacheXSL;

	// Caches the XSL transformers.
	private static Map<String, Transformer> transformerCache;

	static {
		String cacheXSLProperty = CommonPlugin.getDefault().getString(
				"cacheXSL"); //$NON-NLS-1$
		if (cacheXSLProperty != null && !cacheXSLProperty.startsWith("[")) { //$NON-NLS-1$
			cacheXSL = Boolean.getBoolean(cacheXSLProperty);
		} else {
			cacheXSL = true;
		}
		if (cacheXSL) {
			transformerCache = new HashMap<String, Transformer>();
		}
		
		// Increase the entity expansion line limit to handle a larger number of XML entities. 
		System.setProperty("entityExpansionLimit", "1000000");
	}

	/**
	 * Default private constructor to prevent this class from being
	 * instantiated.
	 */
	private XSLTProcessor() {
	}

	/**
	 * Executes the XSL transformation given the XSL source, XML source, target
	 * output and encoding.
	 * 
	 * @param xslSource
	 *            The XSL source.
	 * @param xmlSource
	 *            The XML source.
	 * @param output
	 *            The output target.
	 * @param params
	 *            The parameters for the XSL transformation.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(Source xslSource, Source xmlSource,
			Writer output, Properties params, String encoding) throws Exception {
		if (xslSource != null && xmlSource != null) {
			Transformer transformer = null;
			String xslFile = xslSource.getSystemId();
			if (cacheXSL && xslFile != null) {
				synchronized (transformerCache) {
					transformer = (Transformer) transformerCache.get(xslFile);
					if (transformer == null) {
						TransformerFactory factory = TransformerFactory
								.newInstance();
						transformer = factory.newTransformer(xslSource);
						transformerCache.put(xslFile, transformer);
					}
				}
			} else {
				TransformerFactory factory = TransformerFactory.newInstance();
				transformer = factory.newTransformer(xslSource);
			}
			if (params != null && params.size() > 0) {
				for (Iterator i = params.keySet().iterator(); i.hasNext();) {
					String paramName = (String) i.next();
					String paramValue = params.getProperty(paramName);
					transformer.setParameter(paramName, paramValue);
				}
			}
			if (encoding != null && encoding.length() > 0) {
				transformer.setOutputProperty("encoding", encoding); //$NON-NLS-1$
			} else {
				transformer.setOutputProperty("encoding", "utf-8"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			transformer.transform(xmlSource, new StreamResult(output));
		}
	}

	/**
	 * Executes the XSL transformation given the XSL source, XML source, target
	 * output and encoding.
	 * 
	 * @param xslSource
	 *            The XSL source.
	 * @param xmlSource
	 *            The XML source.
	 * @param output
	 *            The output target.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(Source xslSource, Source xmlSource,
			Writer output, String encoding) throws Exception {
		transform(xslSource, xmlSource, output, null, encoding);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML source,
	 * target output and encoding.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML source.
	 * @param output
	 *            The output target.
	 * @param params
	 *            The parameters for the XSL transformation.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(String xslUri, Source xmlSource,
			Writer output, Properties params, String encoding) throws Exception {
		InputStream xslInput = getXslInputStream(xslUri);
		if (xslInput != null) {
			StreamSource xslSource = new StreamSource(xslInput);
			xslSource.setSystemId(new File(xslUri));
			transform(xslSource, xmlSource, output, params, encoding);
			try {
				xslInput.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML source,
	 * target output and encoding.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML source.
	 * @param output
	 *            The output target.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(String xslUri, Source xmlSource,
			Writer output, String encoding) throws Exception {
		transform(xslUri, xmlSource, output, null, encoding);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string,
	 * target output and encoding.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param output
	 *            The output target.
	 * @param params
	 *            The parameters for the XSL transformation.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(String xslUri, String xmlStr, Writer output,
			Properties params, String encoding) throws Exception {
		InputStream xslInput = getXslInputStream(xslUri);
		if (xslInput != null) {
			StreamSource xslSource = new StreamSource(xslInput);
			xslSource.setSystemId(new File(xslUri));

			byte[] xml = xmlStr.getBytes("utf-8"); //$NON-NLS-1$
			ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml);
			StreamSource xmlSource = new StreamSource(xmlInput);

			transform(xslSource, xmlSource, output, params, encoding);

			try {
				xslInput.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string,
	 * target output and encoding.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param output
	 *            The output target.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(String xslUri, String xmlStr, Writer output,
			String encoding) throws Exception {
		transform(xslUri, xmlStr, output, null, encoding);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string,
	 * target output and encoding.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param file
	 *            The output file.
	 * @param params
	 *            The parameters for the XSL transformation.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(String xslUri, String xmlStr, File file,
			Properties params, String encoding) throws Exception {
		FileWriter output = new FileWriter(file);
		if (output != null) {
			transform(xslUri, xmlStr, output, params, encoding);
			try {
				output.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string,
	 * target output and encoding.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param file
	 *            The output file.
	 * @param encoding
	 *            The target encoding.
	 */
	public static void transform(String xslUri, String xmlStr, File file,
			String encoding) throws Exception {
		transform(xslUri, xmlStr, file, null, encoding);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML source
	 * and target output.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML source.
	 * @param params
	 *            The parameters for the XSL transformation.
	 * @param output
	 *            The output target.
	 */
	public static void transform(String xslUri, Source xmlSource,
			Properties params, Writer output) throws Exception {
		transform(xslUri, xmlSource, output, params, null);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML source
	 * and target output.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML source.
	 * @param output
	 *            The output target.
	 */
	public static void transform(String xslUri, Source xmlSource, Writer output)
			throws Exception {
		transform(xslUri, xmlSource, output, null, null);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string
	 * and target output.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param params
	 *            The parameters for the XSL transformation.
	 * @param output
	 *            The output target.
	 */
	public static void transform(String xslUri, String xmlStr,
			Properties params, Writer output) throws Exception {
		transform(xslUri, xmlStr, output, params, null);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string
	 * and target output.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param output
	 *            The output target.
	 */
	public static void transform(String xslUri, String xmlStr, Writer output)
			throws Exception {
		transform(xslUri, xmlStr, output, null, null);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string
	 * and target output file.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param params
	 *            The parameters for the XSL transformation.
	 * @param output
	 *            The output target.
	 */
	public static void transform(String xslUri, String xmlStr,
			Properties params, File file) throws Exception {
		transform(xslUri, xmlStr, file, params, null);
	}

	/**
	 * Executes the XSL transformation given the XSL stylesheet URI, XML string
	 * and target output file.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 * @param xmlStr
	 *            The XML string.
	 * @param output
	 *            The output target.
	 */
	public static void transform(String xslUri, String xmlStr, File file)
			throws Exception {
		transform(xslUri, xmlStr, file, null, null);
	}

	/**
	 * Returns the XSL input stream given the XSL stylesheet URI.
	 * 
	 * @param xslURI
	 *            The XSL stylesheet URI.
	 */
	private static InputStream getXslInputStream(String xslUri) {
		InputStream xslInput = null;
		try {
			xslInput = new FileInputStream(xslUri);
		} catch (Exception e) {
			if (xslInput == null) {
				xslInput = XSLTProcessor.class.getClassLoader()
						.getResourceAsStream(xslUri);
			}
		}
		return xslInput;
	}

}
