package com.sixsq.slipstream.util;
/*
* +=================================================================+
* SlipStream Server (WAR)
* =====
* Copyright (C) 2013 SixSq Sarl (sixsq.com)
* =====
* 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.
* -=================================================================-
*/
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import com.sixsq.slipstream.exceptions.SlipStreamInternalException;
/**
* Simple utilities to allow static pages/templates to be loaded from the
* classpath.
*/
public class XslUtils {
// Must set the resolver for the factory, so that imported stylesheets are
// looked up relative to this class!
private static TransformerFactory factory;
private static boolean reloadStylesheets = true;
static {
createFactory();
}
private static void createFactory()
throws TransformerFactoryConfigurationError {
factory = TransformerFactory.newInstance();
factory.setURIResolver(new XslResolver(XslUtils.class));
}
private XslUtils() {
}
/**
* Looks up the named stylesheet and returns a tranformer for it. The
* stylesheet is read as a resource and should appear in the CLASSPATH at
* the same location as this class.
*
* @param xslName
* name of the stylesheet to compile
*
* @return Transformer configured with the given stylesheet
*
*/
public static Transformer getTransformer(String xslName) {
Transformer transformer = null;
InputStream is = XslUtils.class.getResourceAsStream(xslName);
if (is != null) {
try {
Source xsltSource = new StreamSource(is);
transformer = getFactory().newTransformer(xsltSource);
} catch (TransformerConfigurationException e) {
throw new SlipStreamInternalException(
"error compiling stylesheet: " + xslName, e);
} finally {
try {
is.close();
} catch (IOException ioe) {
throw new SlipStreamInternalException(
"error closing stylesheet: " + xslName, ioe);
}
}
} else {
throw new SlipStreamInternalException("stylesheet " + xslName
+ " not found");
}
return transformer;
}
private static TransformerFactory getFactory() {
if (reloadStylesheets) {
createFactory();
}
return factory;
}
private static class XslResolver implements URIResolver {
private final Class<?> baseClass;
public XslResolver(Class<?> baseClass) {
this.baseClass = baseClass;
}
public Source resolve(String href, String base) {
InputStream is = baseClass.getResourceAsStream(href);
if (is != null) {
return new StreamSource(is);
} else {
return null;
}
}
}
public static String transform(Source source,
String stylesheet, Map<String, Object> parameters) {
CharArrayWriter writer = new CharArrayWriter();
Result result = new StreamResult(writer);
Transformer transformer = XslUtils.getTransformer(stylesheet);
for (Entry<String, Object> parameter : parameters.entrySet()) {
String value = (parameter.getValue() == null ? "" : parameter
.getValue().toString());
transformer.setParameter(parameter.getKey(), value);
}
try {
transformer.transform(source, result);
return writer.toString();
} catch (TransformerException e) {
throw new SlipStreamInternalException(e);
} finally {
writer.close();
}
}
}