/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.camel.component.xslt;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.URIResolver;
import org.apache.camel.Endpoint;
import org.apache.camel.builder.xml.XsltUriResolver;
import org.apache.camel.converter.jaxp.XmlConverter;
import org.apache.camel.impl.UriEndpointComponent;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriParam;
import org.apache.camel.util.EndpointHelper;
import org.apache.camel.util.ResourceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The <a href="http://camel.apache.org/xslt.html">XSLT Component</a> is for performing XSLT transformations of messages
*/
public class XsltComponent extends UriEndpointComponent {
private static final Logger LOG = LoggerFactory.getLogger(XsltComponent.class);
@Metadata(label = "advanced")
private XmlConverter xmlConverter;
@Metadata(label = "advanced", description = "To use a custom UriResolver. Should not be used together with the option 'uriResolverFactory'.")
private URIResolver uriResolver;
@Metadata(label = "advanced", description = "To use a custom UriResolver which depends on a dynamic endpoint resource URI. Should not be used together with the option 'uriResolver'.")
private XsltUriResolverFactory uriResolverFactory;
@Metadata(defaultValue = "true")
@UriParam(label = "advanced")
private Object saxonConfiguration;
@Metadata(label = "advanced")
private Map<String, Object> saxonConfigurationProperties = new HashMap<>();
@UriParam(label = "advanced", javaType = "java.lang.String")
private List<Object> saxonExtensionFunctions;
private boolean contentCache = true;
private boolean saxon;
public XsltComponent() {
super(XsltEndpoint.class);
}
public XmlConverter getXmlConverter() {
return xmlConverter;
}
/**
* To use a custom implementation of {@link org.apache.camel.converter.jaxp.XmlConverter}
*/
public void setXmlConverter(XmlConverter xmlConverter) {
this.xmlConverter = xmlConverter;
}
public XsltUriResolverFactory getUriResolverFactory() {
return uriResolverFactory;
}
/**
* To use a custom javax.xml.transform.URIResolver which depends on a dynamic endpoint resource URI or which is a subclass of {@link XsltUriResolver}.
* Do not use in combination with uriResolver.
* See also {@link #setUriResolver(URIResolver)}.
*/
public void setUriResolverFactory(XsltUriResolverFactory uriResolverFactory) {
this.uriResolverFactory = uriResolverFactory;
}
public URIResolver getUriResolver() {
return uriResolver;
}
/**
* To use a custom javax.xml.transform.URIResolver. Do not use in combination with uriResolverFactory.
* See also {@link #setUriResolverFactory(XsltUriResolverFactory)}.
*/
public void setUriResolver(URIResolver uriResolver) {
this.uriResolver = uriResolver;
}
public boolean isContentCache() {
return contentCache;
}
/**
* Cache for the resource content (the stylesheet file) when it is loaded.
* If set to false Camel will reload the stylesheet file on each message processing. This is good for development.
* A cached stylesheet can be forced to reload at runtime via JMX using the clearCachedStylesheet operation.
*/
public void setContentCache(boolean contentCache) {
this.contentCache = contentCache;
}
public boolean isSaxon() {
return saxon;
}
/**
* Whether to use Saxon as the transformerFactoryClass.
* If enabled then the class net.sf.saxon.TransformerFactoryImpl. You would need to add Saxon to the classpath.
*/
public void setSaxon(boolean saxon) {
this.saxon = saxon;
}
public List<Object> getSaxonExtensionFunctions() {
return saxonExtensionFunctions;
}
/**
* Allows you to use a custom net.sf.saxon.lib.ExtensionFunctionDefinition.
* You would need to add camel-saxon to the classpath.
* The function is looked up in the registry, where you can comma to separate multiple values to lookup.
*/
public void setSaxonExtensionFunctions(List<Object> extensionFunctions) {
this.saxonExtensionFunctions = extensionFunctions;
}
/**
* Allows you to use a custom net.sf.saxon.lib.ExtensionFunctionDefinition.
* You would need to add camel-saxon to the classpath.
* The function is looked up in the registry, where you can comma to separate multiple values to lookup.
*/
public void setSaxonExtensionFunctions(String extensionFunctions) {
this.saxonExtensionFunctions = EndpointHelper.resolveReferenceListParameter(
getCamelContext(),
extensionFunctions,
Object.class
);
}
public Object getSaxonConfiguration() {
return saxonConfiguration;
}
/**
* To use a custom Saxon configuration
*/
public void setSaxonConfiguration(Object saxonConfiguration) {
this.saxonConfiguration = saxonConfiguration;
}
public Map<String, Object> getSaxonConfigurationProperties() {
return saxonConfigurationProperties;
}
/**
* To set custom Saxon configuration properties
*/
public void setSaxonConfigurationProperties(Map<String, Object> configurationProperties) {
this.saxonConfigurationProperties = configurationProperties;
}
@Override
protected Endpoint createEndpoint(String uri, final String remaining, Map<String, Object> parameters) throws Exception {
XsltEndpoint endpoint = new XsltEndpoint(uri, this);
endpoint.setConverter(getXmlConverter());
endpoint.setContentCache(isContentCache());
endpoint.setSaxon(isSaxon());
endpoint.setSaxonConfiguration(saxonConfiguration);
endpoint.setSaxonConfigurationProperties(saxonConfigurationProperties);
endpoint.setSaxonExtensionFunctions(saxonExtensionFunctions);
String resourceUri = remaining;
// if its a http uri, then append additional parameters as they are part of the uri
if (ResourceHelper.isHttpUri(resourceUri)) {
resourceUri = ResourceHelper.appendParameters(resourceUri, parameters);
}
LOG.debug("{} using schema resource: {}", this, resourceUri);
endpoint.setResourceUri(resourceUri);
// lookup custom resolver to use
URIResolver resolver = resolveAndRemoveReferenceParameter(parameters, "uriResolver", URIResolver.class);
if (resolver == null) {
// not in endpoint then use component specific resolver
resolver = getUriResolver();
}
if (resolver == null) {
// lookup custom resolver factory to use
XsltUriResolverFactory resolverFactory = resolveAndRemoveReferenceParameter(parameters, "uriResolverFactory", XsltUriResolverFactory.class);
if (resolverFactory == null) {
// not in endpoint then use component specific resolver factory
resolverFactory = getUriResolverFactory();
}
if (resolverFactory == null) {
// fallback to use the Default URI resolver factory
resolverFactory = new DefaultXsltUriResolverFactory();
}
resolver = resolverFactory.createUriResolver(getCamelContext(), remaining);
}
endpoint.setUriResolver(resolver);
setProperties(endpoint, parameters);
if (!parameters.isEmpty()) {
// additional parameters need to be stored on endpoint as they can be used to configure xslt builder additionally
endpoint.setParameters(parameters);
}
return endpoint;
}
}