/**
 * Copyright (c) 2014-2017 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.activitibpmn.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.bind.DatatypeConverter;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import com.ebmwebsourcing.easycommons.xml.DocumentBuilders;

public class XslUtils {

    private XslUtils() {
        // Utility class
    }

    /**
     * Create a XML source from a XSLT style-sheet template and XSL parameters
     * 
     * @param templates
     *            The XSLT style-sheet template to use
     * @param xslParameters
     *            The XSL parameters
     * @param logger
     *            A logger
     * @return The XML source generated
     * @throws TransformerException
     *             An error occurs during trnaformation
     */
    public static Source createXmlPayload(final Templates templates, final Map<QName, String> xslParameters,
            final Logger logger) throws TransformerException {

        // TODO: For performance reasons, check that it is not needed to introduce a pool of transformers to avoid to
        // create a transformer on each request
        final Transformer outputTransformer = templates.newTransformer();

        // We prepare the parameters to set to the XSL transformer:
        if (xslParameters != null) {
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("XSL Parameters:");
                for (final Entry<QName, String> variable : xslParameters.entrySet()) {
                    logger.fine("\t- " + variable.getKey().toString() + " => " + variable.getValue());
                }
            }
            for (final Entry<QName, String> variable : xslParameters.entrySet()) {
                outputTransformer.setParameter(variable.getKey().toString(), variable.getValue());
            }
        }

        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final Result result = new StreamResult(baos);
        // TODO: Improve the empty document to avoid to create it each time
        outputTransformer.transform(new DOMSource(DocumentBuilders.newDocument()), result);

        return new StreamSource(new ByteArrayInputStream(baos.toByteArray()));
    }

    /**
     * Convert a BPMN variable value to a XSL parameter value
     * 
     * @param bpmnVariableValue
     *            A BPMN variable value
     * @return The XSL parameter value
     */
    public static String convertBpmnVariableValueToXslParam(final Object bpmnVariableValue) {

        final String xslParamValue;
        if (bpmnVariableValue != null) {
            if (bpmnVariableValue instanceof Date) {
                final Calendar calendar = Calendar.getInstance();
                calendar.setTime((Date) bpmnVariableValue);
                xslParamValue = DatatypeConverter.printDateTime(calendar);
            } else {
                xslParamValue = bpmnVariableValue.toString();
            }
        } else {
            xslParamValue = "";
        }

        return xslParamValue;
    }

}

@@ -837,83 +837,8 @@
 s;%0A%0A
-import java.io.ByteArrayInputStream;%0Aimport java.io.ByteArrayOutputStream;%0A
 impo
@@ -1452,54 +1452,227 @@
 ons.
-xml.DocumentBuilders;%0A%0Apublic class XslUtils %7B
+stream.EasyByteArrayOutputStream;%0Aimport com.ebmwebsourcing.easycommons.xml.DocumentBuilders;%0A%0Apublic class XslUtils %7B%0A%0A    private static final DOMSource EMPTY_DOMSOURCE = new DOMSource(DocumentBuilders.newDocument());
 %0A%0A  
@@ -3212,16 +3212,20 @@
   final 
+Easy
 ByteArra
@@ -3238,16 +3238,17 @@
 tStream 
+e
 baos = n
@@ -3246,24 +3246,28 @@
 ebaos = new 
+Easy
 ByteArrayOut
@@ -3326,16 +3326,17 @@
 mResult(
+e
 baos);%0A 
@@ -3346,168 +3346,184 @@
     
-// TODO: Improve the empty document to avoid to create it each time%0A        outputTransformer.transform(new DOMSource(DocumentBuilders.newDocument()), result);%0A
+outputTransformer.transform(EMPTY_DOMSOURCE, result);%0A        if (logger.isLoggable(Level.FINE)) %7B%0A            logger.fine(%22XML output payload: %22 + ebaos.toString());%0A        %7D
 %0A   
@@ -3551,20 +3551,24 @@
 mSource(
-new 
+ebaos.to
 ByteArra
@@ -3584,26 +3584,8 @@
 eam(
-baos.toByteArray()
 ));%0A

Improve generation of XML output payload