org.restlet.resource.TransformRepresentation Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.servicemix.bundles.restlet
Show all versions of org.apache.servicemix.bundles.restlet
This OSGi bundle wraps org.restlet, and com.noelios.restlet ${pkgVersion} jar files.
The newest version!
/**
* Copyright 2005-2008 Noelios Technologies.
*
* The contents of this file are subject to the terms of the following open
* source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 (the "Licenses"). You can
* select the license that you prefer but you may not use this file except in
* compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.gnu.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.gnu.org/licenses/lgpl-2.1.html
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.sun.com/cddl/cddl.html
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royaltee free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/
package org.restlet.resource;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
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.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.restlet.Context;
import org.restlet.data.Reference;
import org.restlet.data.Response;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
/**
* Representation able to apply an XSLT transformation. The internal JAXP
* transformer is created when the getTransformer() method is first called. So,
* if you need to specify a custom URI resolver, you need to do it before
* actually using the representation for a transformation.
*
* This representation should be viewed as a wrapper representation that applies
* a transform sheet on a source representation when it is read or written out.
* Therefore, it isn't intended to be reused on different sources. For this use
* case, you should instead use the {@link org.restlet.Transformer} filter.
*
* @author Jerome Louvel
*/
public class TransformRepresentation extends OutputRepresentation {
/**
* Abstract SAX XML Reader.
*
* @author Warren Janssens
*/
private static abstract class AbstractXmlReader implements XMLReader {
/** The features map. */
private final HashMap features;
/** The properties map. */
private final HashMap properties;
/** The entity resolver. */
private EntityResolver entityResolver;
/** The DTD handler. */
private DTDHandler handler;
/** The content handler. */
private ContentHandler contentHandler;
/** The error handler. */
private ErrorHandler errorHandler;
/**
* Default constructor.
*/
public AbstractXmlReader() {
this.features = new HashMap();
this.properties = new HashMap();
}
/**
* Return the content handler.
*
* @return The content handler.
* @see XMLReader#getContentHandler()
*/
public ContentHandler getContentHandler() {
return contentHandler;
}
/**
* Return the DTD handler.
*
* @return The DTD handler.
* @see XMLReader#getDTDHandler()
*/
public DTDHandler getDTDHandler() {
return handler;
}
/**
* Return the entity resolver.
*
* @return The entity resolver.
* @see XMLReader#getEntityResolver()
*/
public EntityResolver getEntityResolver() {
return entityResolver;
}
/**
* Return the error handler.
*
* @return The error handler.
* @see XMLReader#getErrorHandler()
*/
public ErrorHandler getErrorHandler() {
return errorHandler;
}
/**
* Returns the feature by name.
*
* @param name
* The feature name.
* @return The feature.
* @see XMLReader#getFeature(String)
*/
public boolean getFeature(String name)
throws SAXNotRecognizedException, SAXNotSupportedException {
final Boolean result = features.get(name);
return result == null ? false : result.booleanValue();
}
/**
* Returns the property by name.
*
* @param name
* The property name.
* @return The property.
* @see XMLReader#getProperty(String)
*/
public Object getProperty(String name)
throws SAXNotRecognizedException, SAXNotSupportedException {
return properties.get(name);
}
/**
* Sets the content handler.
*
* @param contentHandler
* The content handler.
* @see XMLReader#setContentHandler(ContentHandler)
*/
public void setContentHandler(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
}
/**
* Sets the DTD handler.
*
* @param handler
* The DTD handler.
* @see XMLReader#setDTDHandler(DTDHandler)
*/
public void setDTDHandler(DTDHandler handler) {
this.handler = handler;
}
/**
* Sets the entity resolver.
*
* @param entityResolver
* The entity resolver.
* @see XMLReader#setEntityResolver(EntityResolver)
*/
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
/**
* Sets the error handler.
*
* @param errorHandler
* The error handler.
* @see XMLReader#setErrorHandler(ErrorHandler)
*/
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
/**
* Sets a feature.
*
* @param name
* The feature name.
* @param value
* The feature value.
* @see XMLReader#setFeature(String, boolean)
*/
public void setFeature(String name, boolean value)
throws SAXNotRecognizedException, SAXNotSupportedException {
this.features.put(name, value);
}
/**
* Sets a property.
*
* @param name
* The property name.
* @param value
* The property value.
* @see XMLReader#setProperty(String, Object)
*/
public void setProperty(String name, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException {
this.properties.put(name, value);
}
}
/**
* URI resolver based on a Restlet Context instance.
*
* @author Jerome Louvel
*/
private final static class ContextResolver implements URIResolver {
/** The Restlet context. */
private final Context context;
/**
* Constructor.
*
* @param context
* The Restlet context.
*/
public ContextResolver(Context context) {
this.context = context;
}
/**
* Resolves a target reference into a Source document.
*
* @see javax.xml.transform.URIResolver#resolve(java.lang.String,
* java.lang.String)
*/
public Source resolve(String href, String base)
throws TransformerException {
Source result = null;
if (this.context != null) {
Reference targetRef = null;
if ((base != null) && !base.equals("")) {
// Potentially a relative reference
final Reference baseRef = new Reference(base);
targetRef = new Reference(baseRef, href);
} else {
// No base, assume "href" is an absolute URI
targetRef = new Reference(href);
}
final String targetUri = targetRef.getTargetRef().toString();
final Response response = this.context.getClientDispatcher()
.get(targetUri);
if (response.getStatus().isSuccess()
&& response.isEntityAvailable()) {
try {
result = new StreamSource(response.getEntity()
.getStream());
result.setSystemId(targetUri);
} catch (IOException e) {
this.context.getLogger().log(Level.WARNING,
"I/O error while getting the response stream",
e);
}
}
}
return result;
}
}
/** The JAXP transformer output properties. */
private volatile Map outputProperties;
/** The JAXP transformer parameters. */
private volatile Map parameters;
/** The source representation to transform. */
private volatile Representation sourceRepresentation;
/** The template to be used and reused. */
private volatile Templates templates;
/** The XSLT transform sheet to apply to message entities. */
private volatile Representation transformSheet;
/** The URI resolver. */
private volatile URIResolver uriResolver;
/**
* Constructor. Note that a default URI resolver will be created based on
* the given context.
*
* @param context
* The parent context.
* @param source
* The source representation to transform.
* @param transformSheet
* The XSLT transform sheet to apply.
*/
public TransformRepresentation(Context context, Representation source,
Representation transformSheet) {
this((context == null) ? null : new ContextResolver(context), source,
transformSheet);
}
/**
* Default constructor.
*
* @param source
* The source representation to transform.
* @param transformSheet
* The XSLT transform sheet to apply.
*/
public TransformRepresentation(Representation source,
Representation transformSheet) {
this((URIResolver) null, source, transformSheet);
}
/**
* Constructor. Note that a default URI resolver will be created based on
* the given context.
*
* @param uriResolver
* The JAXP URI resolver.
* @param source
* The source representation to transform.
* @param transformSheet
* The XSLT transform sheet to apply.
*/
public TransformRepresentation(URIResolver uriResolver,
Representation source, Representation transformSheet) {
this(uriResolver, source, transformSheet, null);
}
/**
* Constructor.
*
* @param uriResolver
* The optional JAXP URI resolver.
* @param source
* The source representation to transform.
* @param templates
* The precompiled JAXP template.
*/
private TransformRepresentation(URIResolver uriResolver,
Representation source, Representation transformSheet,
Templates templates) {
super(null);
this.sourceRepresentation = source;
this.templates = templates;
this.transformSheet = transformSheet;
this.uriResolver = uriResolver;
this.parameters = new HashMap();
this.outputProperties = new HashMap();
}
/**
* Constructor.
*
* @param uriResolver
* The optional JAXP URI resolver.
* @param source
* The source representation to transform.
* @param templates
* The precompiled JAXP template.
*/
public TransformRepresentation(URIResolver uriResolver,
Representation source, Templates templates) {
this(uriResolver, source, null, templates);
}
/**
* Returns the modifiable map of JAXP transformer output properties.
*
* @return The JAXP transformer output properties.
*/
public Map getOutputProperties() {
return this.outputProperties;
}
/**
* Returns the modiable map of JAXP transformer parameters.
*
* @return The JAXP transformer parameters.
*/
public Map getParameters() {
return this.parameters;
}
/**
* Returns the SAX source associated to the source representation.
*
* @return The SAX source associated to the source representation.
* @throws IOException
*/
public SAXSource getSaxSource() throws IOException {
SAXSource result = null;
if (getSourceRepresentation() instanceof XmlRepresentation) {
result = ((XmlRepresentation) getSourceRepresentation())
.getSaxSource();
} else if (getSourceRepresentation() instanceof TransformRepresentation) {
XMLReader reader = new AbstractXmlReader() {
public void parse(InputSource input) throws IOException,
SAXException {
try {
TransformRepresentation source = (TransformRepresentation) getSourceRepresentation();
source.getTransformer().transform(
source.getSaxSource(),
new SAXResult(getContentHandler()));
} catch (TransformerException te) {
throw new IOException("Transformer exception. "
+ te.getMessage());
}
}
public void parse(String systemId) throws IOException,
SAXException {
throw new IllegalStateException("Not implemented");
}
};
result = new SAXSource(reader, null);
} else {
// Prepare the source and result documents
result = new SAXSource(new InputSource(getSourceRepresentation()
.getStream()));
}
if (getSourceRepresentation().getIdentifier() != null) {
result.setSystemId(getSourceRepresentation().getIdentifier()
.getTargetRef().toString());
}
return result;
}
/**
* Returns the default SAX transformer factory.
*
* @return The default SAX transformer factory.
*/
private SAXTransformerFactory getSaxTransformerFactory() {
final SAXTransformerFactory result = (SAXTransformerFactory) TransformerFactory
.newInstance();
return result;
}
/**
* Returns the source representation to transform.
*
* @return The source representation to transform.
*/
public Representation getSourceRepresentation() {
return this.sourceRepresentation;
}
/**
* Returns the templates to be used and reused. If no one exists, it creates
* a new one based on the transformSheet representation and on the URI
* resolver.
*
* @return The templates to be used and reused.
*/
public Templates getTemplates() throws IOException {
if (this.templates == null) {
try {
// Prepare the XSLT transformer documents
final StreamSource transformSource = new StreamSource(
getTransformSheet().getStream());
if (getTransformSheet().getIdentifier() != null) {
transformSource.setSystemId(getTransformSheet()
.getIdentifier().getTargetRef().toString());
}
// Create the transformer factory
final TransformerFactory transformerFactory = TransformerFactory
.newInstance();
// Set the URI resolver
if (getUriResolver() != null) {
transformerFactory.setURIResolver(getUriResolver());
}
// Create a new transformer
this.templates = transformerFactory
.newTemplates(transformSource);
} catch (TransformerConfigurationException tce) {
throw new IOException("Transformer configuration exception. "
+ tce.getMessage());
}
}
return this.templates;
}
/**
* Returns a new transformer to be used. Creation is based on the
* {@link #getTemplates()}.newTransformer() method.
*
* @return The new transformer to be used.
*/
public Transformer getTransformer() throws IOException {
Transformer result = null;
try {
final Templates templates = getTemplates();
if (templates != null) {
result = templates.newTransformer();
if (this.uriResolver != null) {
result.setURIResolver(getUriResolver());
}
// Set the parameters
for (final String name : getParameters().keySet()) {
result.setParameter(name, getParameters().get(name));
}
// Set the output properties
for (final String name : getOutputProperties().keySet()) {
result.setOutputProperty(name, getOutputProperties().get(
name));
}
}
} catch (TransformerConfigurationException tce) {
throw new IOException("Transformer configuration exception. "
+ tce.getMessage());
} catch (TransformerFactoryConfigurationError tfce) {
throw new IOException(
"Transformer factory configuration exception. "
+ tfce.getMessage());
}
return result;
}
/**
* Returns the SAX transformer handler associated to the transform sheet.
*
* @return The SAX transformer handler.
* @throws IOException
*/
public TransformerHandler getTransformerHandler() throws IOException {
TransformerHandler result = null;
final Templates templates = getTemplates();
if (templates != null) {
try {
result = getSaxTransformerFactory().newTransformerHandler(
templates);
} catch (TransformerConfigurationException tce) {
throw new IOException("Transformer configuration exception. "
+ tce.getMessage());
}
}
return result;
}
/**
* Returns the XSLT transform sheet to apply to the source representation.
*
* @return The XSLT transform sheet to apply.
*/
public Representation getTransformSheet() {
return this.transformSheet;
}
/**
* Returns the URI resolver.
*
* @return The URI resolver.
*/
public URIResolver getUriResolver() {
return this.uriResolver;
}
/**
* Returns the URI resolver.
*
* @return The URI resolver.
* @deprecated Use the getUriResolver method instead.
*/
@Deprecated
public URIResolver getURIResolver() {
return this.uriResolver;
}
/**
* Returns the SAX XML filter applying the transform sheet to its input.
*
* @return The SAX XML filter.
* @throws IOException
*/
public XMLFilter getXmlFilter() throws IOException {
XMLFilter result = null;
final Templates templates = getTemplates();
if (templates != null) {
try {
result = getSaxTransformerFactory().newXMLFilter(templates);
} catch (TransformerConfigurationException tce) {
throw new IOException("Transformer configuration exception. "
+ tce.getMessage());
}
}
return result;
}
/**
* Releases the source and transform sheet representations, the transformer
* and the URI resolver.
*/
@Override
public void release() {
if (this.sourceRepresentation != null) {
this.sourceRepresentation.release();
this.sourceRepresentation = null;
}
if (this.templates != null) {
this.templates = null;
}
if (this.transformSheet != null) {
this.transformSheet.release();
this.transformSheet = null;
}
if (this.uriResolver != null) {
this.uriResolver = null;
}
super.release();
}
/**
* Sets the modifiable map of JAXP transformer output properties.
*
* @param outputProperties
* The JAXP transformer output properties.
*/
public void setOutputProperties(Map outputProperties) {
this.outputProperties = outputProperties;
}
/**
* Sets the JAXP transformer parameters.
*
* @param parameters
* The JAXP transformer parameters.
*/
public void setParameters(Map parameters) {
this.parameters = parameters;
}
/**
* Sets the source representation to transform.
*
* @param source
* The source representation to transform.
*/
public void setSourceRepresentation(Representation source) {
this.sourceRepresentation = source;
}
/**
* Sets the templates to be used and reused.
*
* @param templates
* The templates to be used and reused.
*/
public void setTemplates(Templates templates) {
this.templates = templates;
}
/**
* Sets the XSLT transform sheet to apply to message entities.
*
* @param transformSheet
* The XSLT transform sheet to apply to message entities.
*/
public void setTransformSheet(Representation transformSheet) {
this.transformSheet = transformSheet;
}
/**
* Sets the URI resolver.
*
* @param uriResolver
* The URI resolver.
*/
public void setUriResolver(URIResolver uriResolver) {
this.uriResolver = uriResolver;
}
@Override
public void write(OutputStream outputStream) throws IOException {
try {
// Generates the result of the transformation
getTransformer().transform(getSaxSource(),
new StreamResult(outputStream));
} catch (TransformerException te) {
throw new IOException("Transformer exception. " + te.getMessage());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy