io.inkstand.halite.rs.OutputTransformMessageBodyWriter Maven / Gradle / Ivy
package io.inkstand.halite.rs;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.net.URL;
import javax.annotation.PostConstruct;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.xml.bind.JAXBException;
import javax.xml.bind.util.JAXBSource;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
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 io.inkstand.halite.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* {@link MessageBodyWriter} that allows to transform the halite {@link Resource} to any representation using an
* XSL transformation.
*
* @author Gerald Mücke
*
*/
public abstract class OutputTransformMessageBodyWriter extends HaliteMessageBodyWriter {
/**
* SLF4J Logger for this class
*/
private static final Logger LOG = LoggerFactory.getLogger(OutputTransformMessageBodyWriter.class);
private Transformer transformer;
@PostConstruct
public void initializeTransformer() {
try {
final TransformerFactory factory = TransformerFactory.newInstance();
factory.setURIResolver(getURIResolver());
final URL templateUrl = getTemplate();
if (templateUrl == null) {
// identity transformer
this.transformer = factory.newTransformer();
} else {
// template transformer
final StreamSource templateSource = new StreamSource(templateUrl.openStream());
final Templates template = factory.newTemplates(templateSource);
this.transformer = template.newTransformer();
}
} catch (TransformerConfigurationException | TransformerFactoryConfigurationError
| ParserConfigurationException | IOException e) {
throw new TransformerInitializationException(e);
}
}
/**
* Provides the URI resolver that is needed by the transformation to resolve externally referrences resources.
* The default implementation provides a ClasspathUriResolver. Override the method to provide a custom {@link URIResolver}.
* @return
* the {@link URIResolver} to be used in the transformation
* @throws ParserConfigurationException
*/
protected URIResolver getURIResolver() throws ParserConfigurationException {
return new ClasspathURIResolver(getClass(), "/templates/");
}
/**
* Implement the method to provide the URL of the template that should be used for generating the representation
* of the resource. If templates are provided that do not reside in the classpath, the getURIResolver method
* has to be overridden.
* @return
* the URL pointing to the template.
*/
protected abstract URL getTemplate();
@Override
public void writeTo(
final Resource paramT,
final Class> paramClass,
final Type paramType,
final Annotation[] paramArrayOfAnnotation,
final MediaType paramMediaType,
final MultivaluedMap paramMultivaluedMap,
final OutputStream paramOutputStream)
throws IOException, WebApplicationException {
try {
final Source input = new JAXBSource(newJAXBContext(), paramT);
final Result result = new StreamResult(paramOutputStream);
this.transformer.transform(input, result);
} catch (JAXBException | TransformerException e) {
LOG.error("Could not produce result", e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy