com.elsevier.xml.XSLTProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.elsevier.xml.XSLTProcessor.java

Source

/*
 * Copyright (c)2015 Elsevier, Inc.
    
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.elsevier.xml;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;

import javax.xml.transform.stream.StreamSource;

import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.Serializer;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Class that provides xml transforming capabilities  (via xslt) for an object passed as a String.
 * 
 * @author Darin McBeath
 * 
 */
public class XSLTProcessor {

    // Stylesheet cache
    private static volatile HashMap<String, String> stylesheetMap = new HashMap<String, String>();

    // Logger
    private static Log log = LogFactory.getLog(XSLTProcessor.class);

    /**
     * Init the stylesheet cache.
     * 
     * @param stylesheetName name to use for the stylesheet
     * @param stylesheet actual stylesheet
     */
    public static void init(String stylesheetName, String stylesheet) throws IOException {

        if (stylesheetMap.get(stylesheetName) == null) {
            synchronized (XSLTProcessor.class) {
                if (stylesheetMap.get(stylesheetName) == null) {
                    stylesheetMap.put(stylesheetName, stylesheet);
                }
            }
        }

    }

    /**
     * Transform the content using the specified stylesheet.
     * 
     * @param stylesheetName name of the stylesheet (that was set in init)
     * @param content the xml to be transformed
     * @return transformed content
     */
    public static String transform(String stylesheetName, String content) {

        try {

            // Get the stylesheet from the cache
            String stylesheet = stylesheetMap.get(stylesheetName);

            if (stylesheet == null) {
                log.error("Problems finding the stylesheet.  STYLESHEET_NAME: " + stylesheetName);
                return "</error>";
            }

            StreamSource stylesheetSource = new StreamSource(IOUtils.toInputStream(stylesheet, CharEncoding.UTF_8));

            // Create streamsource for the content
            StreamSource contentSource = new StreamSource(IOUtils.toInputStream(content, CharEncoding.UTF_8));

            // Apply transformation
            return transform(contentSource, stylesheetSource);

        } catch (IOException e) {

            log.error("Problems transforming the content.  STYLESHEET_NAME: " + stylesheetName + "  "
                    + e.getMessage(), e);
            return "</error>";

        }

    }

    /**
     * Transform the content with the specified stylesheet
     * @param content the xml to be transformed
     * @param stylesheet the stylesheet to apply to the xml content
     * @return transformed content
     */
    private static String transform(StreamSource content, StreamSource stylesheet) {

        try {

            // Get the processor
            Processor proc = new Processor(false);

            // Get the xslt compiler
            XsltCompiler xsltCompiler = proc.newXsltCompiler();

            // Set the uri resolver (for imported/included stylesheets)
            xsltCompiler.setURIResolver(new S3URIResolver());

            // Compile the stylesheet
            XsltExecutable exp = xsltCompiler.compile(stylesheet);

            // Set up the output for the transformation
            Serializer out = new Serializer();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            out.setOutputStream(baos);
            // Appears ok to always set output property to xml
            out.setOutputProperty(Serializer.Property.METHOD, "xml");
            out.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "yes");
            out.setProcessor(proc);
            XsltTransformer trans = exp.load();
            trans.setDestination(out);

            // Set the content to use for the transformation
            trans.setSource(content);

            // Transform the content
            trans.transform();

            // Return the transformed content
            return new String(baos.toByteArray(), CharEncoding.UTF_8);

        } catch (IOException e) {

            log.error("Problems transforming the content.  " + e.getMessage(), e);
            return "<error/>";

        } catch (SaxonApiException e) {

            log.error("Problems transforming the content.  " + e.getMessage(), e);
            return "<error/>";

        }

    }

    /**
     * Empty the caches for the stylesheets.
     * and S3URIResolver
     */
    public static void clear() {

        XSLTProcessor.emptyCache();
        S3URIResolver.emptyCache();

    }

    /**
     * Empty the stylesheet cache.
     */
    private static void emptyCache() {

        if (stylesheetMap.size() > 0) {
            synchronized (XSLTProcessor.class) {
                if (stylesheetMap.size() > 0) {
                    stylesheetMap.clear();
                }
            }
        }

    }

}