| //------------------------------------------------------------------------------ |
| // 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, CachedTransformer> 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, CachedTransformer>(); |
| } |
| |
| // Increase the entity expansion line limit to handle a larger number of |
| // XML entities. |
| System.setProperty("entityExpansionLimit", "1000000"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /** |
| * 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) { |
| CachedTransformer cachedTransformer = null; |
| synchronized (transformerCache) { |
| cachedTransformer = transformerCache.get(xslFile); |
| if (cachedTransformer == null) { |
| TransformerFactory factory = TransformerFactory |
| .newInstance(); |
| transformer = factory.newTransformer(xslSource); |
| transformerCache.put(xslFile, new CachedTransformer( |
| transformer, params)); |
| } else { |
| cachedTransformer.setParams(params); |
| transformer = cachedTransformer.getTransformer(); |
| } |
| } |
| } else { |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| transformer = factory.newTransformer(xslSource); |
| |
| if (params != null && params.size() > 0) { |
| for (Iterator<Object> 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(); |
| xmlInput.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; |
| } |
| |
| } |
| |
| /** |
| * A cached XSL Transformer object. |
| */ |
| class CachedTransformer { |
| |
| private Transformer transformer; |
| private Properties params; |
| |
| public CachedTransformer(Transformer transformer, Properties params) { |
| this.transformer = transformer; |
| setParams(params); |
| } |
| |
| public Transformer getTransformer() { |
| return transformer; |
| } |
| |
| public Properties getParams() { |
| return params; |
| } |
| |
| public void setParams(Properties params) { |
| if (params != this.params) { |
| transformer.clearParameters(); |
| for (Iterator<Object> i = params.keySet().iterator(); i.hasNext();) { |
| String paramName = (String) i.next(); |
| String paramValue = params.getProperty(paramName); |
| transformer.setParameter(paramName, paramValue); |
| } |
| this.params = params; |
| } |
| } |
| |
| } |