This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch saxon in repository https://gitbox.apache.org/repos/asf/camel.git
commit 42246cb35a2afaf0b901c0fcb2559cf8ca609532 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Nov 14 11:28:32 2019 +0100 CAMEL-14167: camel-xslt - Split up into camel-saxon-xslt --- components/camel-xslt-saxon/pom.xml | 6 ++ .../src/main/docs/xslt-saxon-component.adoc | 6 +- .../xslt/saxon/XsltSaxonAggregationStrategy.java | 4 +- .../component/xslt/saxon/XsltSaxonComponent.java | 7 +- .../component/xslt/saxon/XsltSaxonEndpoint.java | 41 ++++++------ .../component/xslt/saxon/XsltSaxonHelper.java | 74 +++++----------------- .../component/xslt/XsltAggregationStrategy.java | 9 ++- .../dsl/XsltSaxonEndpointBuilderFactory.java | 9 +-- .../XsltSaxonComponentConfiguration.java | 6 +- 9 files changed, 70 insertions(+), 92 deletions(-) diff --git a/components/camel-xslt-saxon/pom.xml b/components/camel-xslt-saxon/pom.xml index 5ad9aa5..8e3b123 100644 --- a/components/camel-xslt-saxon/pom.xml +++ b/components/camel-xslt-saxon/pom.xml @@ -33,6 +33,12 @@ <name>Camel :: XSLT Saxon</name> <description>Camel XSLT Saxon component</description> + <properties> + <camel.osgi.import.additional> + net.sf.saxon.*;version="[9.9.0,10)" + </camel.osgi.import.additional> + </properties> + <dependencies> <dependency> diff --git a/components/camel-xslt-saxon/src/main/docs/xslt-saxon-component.adoc b/components/camel-xslt-saxon/src/main/docs/xslt-saxon-component.adoc index f0fafff..6114496 100644 --- a/components/camel-xslt-saxon/src/main/docs/xslt-saxon-component.adoc +++ b/components/camel-xslt-saxon/src/main/docs/xslt-saxon-component.adoc @@ -47,7 +47,7 @@ The XSLT Saxon component supports 9 options, which are listed below. |=== | Name | Description | Default | Type | *saxonExtensionFunctions* (advanced) | 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. | | String -| *saxonConfiguration* (advanced) | To use a custom Saxon configuration | | Object +| *saxonConfiguration* (advanced) | To use a custom Saxon configuration | | Configuration | *saxonConfiguration Properties* (advanced) | To set custom Saxon configuration properties | | Map | *uriResolverFactory* (advanced) | To use a custom UriResolver which depends on a dynamic endpoint resource URI. Should not be used together with the option 'uriResolver'. | | XsltUriResolverFactory | *uriResolver* (advanced) | To use a custom UriResolver. Should not be used together with the option 'uriResolverFactory'. | | URIResolver @@ -85,7 +85,7 @@ with the following path and query parameters: |=== | Name | Description | Default | Type | *allowStAX* (producer) | Whether to allow using StAX as the javax.xml.transform.Source. You can enable this if the XSLT library supports StAX such as the Saxon library (camel-saxon). The Xalan library (default in JVM) does not support StAXSource. | true | boolean -| *saxonConfiguration* (advanced) | To use a custom Saxon configuration | | Object +| *saxonConfiguration* (advanced) | To use a custom Saxon configuration | | Configuration | *saxonExtensionFunctions* (advanced) | 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. | | String | *contentCache* (producer) | 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. | true | boolean | *deleteOutputFile* (producer) | If you have output=file then this option dictates whether or not the output file should be deleted when the Exchange is done processing. For example suppose the output file is a temporary file, then it can be a good idea to delete it after use. | false | boolean @@ -132,7 +132,7 @@ The component supports 10 options, which are listed below. | *camel.component.xslt-saxon.content-cache* | 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. | true | Boolean | *camel.component.xslt-saxon.enabled* | Whether to enable auto configuration of the xslt-saxon component. This is enabled by default. | | Boolean | *camel.component.xslt-saxon.lazy-start-producer* | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed [...] -| *camel.component.xslt-saxon.saxon-configuration* | To use a custom Saxon configuration. The option is a java.lang.Object type. | | String +| *camel.component.xslt-saxon.saxon-configuration* | To use a custom Saxon configuration. The option is a net.sf.saxon.Configuration type. | | String | *camel.component.xslt-saxon.saxon-configuration-properties* | To set custom Saxon configuration properties | | Map | *camel.component.xslt-saxon.saxon-extension-functions* | 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. | | String | *camel.component.xslt-saxon.uri-resolver* | To use a custom UriResolver. Should not be used together with the option 'uriResolverFactory'. The option is a javax.xml.transform.URIResolver type. | | String diff --git a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java index e05637c..ecefe2e 100644 --- a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java +++ b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonAggregationStrategy.java @@ -16,6 +16,8 @@ */ package org.apache.camel.component.xslt.saxon; +import net.sf.saxon.TransformerFactoryImpl; + import org.apache.camel.component.xslt.XsltAggregationStrategy; import org.apache.camel.component.xslt.XsltBuilder; @@ -23,7 +25,7 @@ public class XsltSaxonAggregationStrategy extends XsltAggregationStrategy { public XsltSaxonAggregationStrategy(String xslFileLocation) { super(xslFileLocation); - setTransformerFactoryClass(XsltSaxonEndpoint.SAXON_TRANSFORMER_FACTORY_CLASS_NAME); + setTransformerFactory(new TransformerFactoryImpl()); } @Override diff --git a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonComponent.java b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonComponent.java index 4bb0a47..bbd4b0ba 100644 --- a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonComponent.java +++ b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonComponent.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import net.sf.saxon.Configuration; import org.apache.camel.Endpoint; import org.apache.camel.component.xslt.XsltComponent; import org.apache.camel.spi.Metadata; @@ -33,7 +34,7 @@ import org.apache.camel.support.EndpointHelper; public class XsltSaxonComponent extends XsltComponent { @Metadata(label = "advanced") - private Object saxonConfiguration; + private Configuration saxonConfiguration; @Metadata(label = "advanced") private Map<String, Object> saxonConfigurationProperties = new HashMap<>(); @Metadata(label = "advanced", javaType = "java.lang.String") @@ -65,14 +66,14 @@ public class XsltSaxonComponent extends XsltComponent { ); } - public Object getSaxonConfiguration() { + public Configuration getSaxonConfiguration() { return saxonConfiguration; } /** * To use a custom Saxon configuration */ - public void setSaxonConfiguration(Object saxonConfiguration) { + public void setSaxonConfiguration(Configuration saxonConfiguration) { this.saxonConfiguration = saxonConfiguration; } diff --git a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpoint.java b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpoint.java index ee7ab45..b04e6ed 100644 --- a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpoint.java +++ b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpoint.java @@ -21,6 +21,8 @@ import java.util.List; import java.util.Map; import javax.xml.transform.TransformerFactory; +import net.sf.saxon.Configuration; +import net.sf.saxon.TransformerFactoryImpl; import org.apache.camel.CamelContext; import org.apache.camel.Component; import org.apache.camel.api.management.ManagedAttribute; @@ -34,15 +36,13 @@ import org.apache.camel.spi.UriParam; import org.apache.camel.support.EndpointHelper; /** - * Transforms the message using a XSLT template. + * Transforms the message using a XSLT template using Saxon. */ @ManagedResource(description = "Managed XsltSaxonEndpoint") @UriEndpoint(firstVersion = "3.0.0", scheme = "xslt-saxon", title = "XSLT Saxon", syntax = "xslt-saxon:resourceUri", producerOnly = true, label = "core,transformation") public class XsltSaxonEndpoint extends XsltEndpoint { - public static final String SAXON_TRANSFORMER_FACTORY_CLASS_NAME = "net.sf.saxon.TransformerFactoryImpl"; - @UriParam(label = "advanced") - private Object saxonConfiguration; + private Configuration saxonConfiguration; @Metadata(label = "advanced") private Map<String, Object> saxonConfigurationProperties = new HashMap<>(); @UriParam(label = "advanced", javaType = "java.lang.String") @@ -80,14 +80,14 @@ public class XsltSaxonEndpoint extends XsltEndpoint { ); } - public Object getSaxonConfiguration() { + public Configuration getSaxonConfiguration() { return saxonConfiguration; } /** * To use a custom Saxon configuration */ - public void setSaxonConfiguration(Object saxonConfiguration) { + public void setSaxonConfiguration(Configuration saxonConfiguration) { this.saxonConfiguration = saxonConfiguration; } @@ -132,21 +132,24 @@ public class XsltSaxonEndpoint extends XsltEndpoint { final XsltSaxonBuilder xslt = injector.newInstance(XsltSaxonBuilder.class); - String fc = getTransformerFactoryClass(); - if (fc == null) { - fc = SAXON_TRANSFORMER_FACTORY_CLASS_NAME; - } - TransformerFactory factory = getTransformerFactory(); if (factory == null) { - // provide the class loader of this component to work in OSGi environments - Class<TransformerFactory> factoryClass = resolver.resolveMandatoryClass(fc, TransformerFactory.class, XsltSaxonComponent.class.getClassLoader()); - log.debug("Using TransformerFactoryClass {}", factoryClass); - factory = injector.newInstance(factoryClass); - - XsltSaxonHelper.registerSaxonConfiguration(ctx, factoryClass, factory, saxonConfiguration); - XsltSaxonHelper.registerSaxonConfigurationProperties(ctx, factoryClass, factory, saxonConfigurationProperties); - XsltSaxonHelper.registerSaxonExtensionFunctions(ctx, factoryClass, factory, saxonExtensionFunctions); + if (getTransformerFactoryClass() == null) { + // create new saxon factory + factory = new TransformerFactoryImpl(); + } else { + // provide the class loader of this component to work in OSGi environments + Class<TransformerFactory> factoryClass = resolver.resolveMandatoryClass(getTransformerFactoryClass(), TransformerFactory.class, XsltSaxonComponent.class.getClassLoader()); + log.debug("Using TransformerFactoryClass {}", factoryClass); + factory = injector.newInstance(factoryClass); + } + } + + if (factory instanceof TransformerFactoryImpl) { + TransformerFactoryImpl tf = (TransformerFactoryImpl) factory; + XsltSaxonHelper.registerSaxonConfiguration(tf, saxonConfiguration); + XsltSaxonHelper.registerSaxonConfigurationProperties(tf, saxonConfigurationProperties); + XsltSaxonHelper.registerSaxonExtensionFunctions(tf, saxonExtensionFunctions); } if (factory != null) { diff --git a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonHelper.java b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonHelper.java index 0a6944d..88d7edd 100644 --- a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonHelper.java +++ b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonHelper.java @@ -16,89 +16,47 @@ */ package org.apache.camel.component.xslt.saxon; -import java.lang.reflect.Method; import java.util.List; import java.util.Map; - import javax.xml.XMLConstants; -import javax.xml.transform.TransformerFactory; -import org.apache.camel.CamelContext; +import net.sf.saxon.Configuration; +import net.sf.saxon.TransformerFactoryImpl; +import net.sf.saxon.lib.ExtensionFunctionDefinition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; final class XsltSaxonHelper { private static final Logger LOG = LoggerFactory.getLogger(XsltSaxonHelper.class); - // TODO: Avoid dynamic class-loading - - private static final String SAXON_CONFIGURATION_CLASS_NAME = "net.sf.saxon.Configuration"; - private static final String SAXON_EXTENDED_FUNCTION_DEFINITION_CLASS_NAME = "net.sf.saxon.lib.ExtensionFunctionDefinition"; - private XsltSaxonHelper() { } - public static void registerSaxonConfiguration( - CamelContext camelContext, Class<?> factoryClass, TransformerFactory factory, Object saxonConfiguration) throws Exception { - + public static void registerSaxonConfiguration(TransformerFactoryImpl factory, Configuration saxonConfiguration) throws Exception { if (saxonConfiguration != null) { - Class<?> configurationClass = camelContext.getClassResolver().resolveClass(SAXON_CONFIGURATION_CLASS_NAME); - if (configurationClass != null) { - Method method = factoryClass.getMethod("setConfiguration", configurationClass); - if (method != null) { - method.invoke(factory, configurationClass.cast(saxonConfiguration)); - } - } + factory.setConfiguration(saxonConfiguration); } } - public static void registerSaxonConfigurationProperties( - CamelContext camelContext, Class<?> factoryClass, TransformerFactory factory, Map<String, Object> saxonConfigurationProperties) throws Exception { - + public static void registerSaxonConfigurationProperties(TransformerFactoryImpl factory, + Map<String, Object> saxonConfigurationProperties) throws Exception { if (saxonConfigurationProperties != null && !saxonConfigurationProperties.isEmpty()) { - Method method = factoryClass.getMethod("getConfiguration"); - if (method != null) { - Object configuration = method.invoke(factory); - if (configuration != null) { - method = configuration.getClass().getMethod("setConfigurationProperty", String.class, Object.class); - for (Map.Entry<String, Object> entry : saxonConfigurationProperties.entrySet()) { - method.invoke(configuration, entry.getKey(), entry.getValue()); - } - } + for (Map.Entry<String, Object> entry : saxonConfigurationProperties.entrySet()) { + factory.getConfiguration().setConfigurationProperty(entry.getKey(), entry.getValue()); } } } - public static void registerSaxonExtensionFunctions( - CamelContext camelContext, Class<?> factoryClass, TransformerFactory factory, List<Object> saxonExtensionFunctions) throws Exception { - + public static void registerSaxonExtensionFunctions(TransformerFactoryImpl factory, List<Object> saxonExtensionFunctions) throws Exception { if (saxonExtensionFunctions != null && !saxonExtensionFunctions.isEmpty()) { - Method method = factoryClass.getMethod("getConfiguration"); - if (method != null) { - Object configuration = method.invoke(factory); - if (configuration != null) { - Class<?> extensionClass = camelContext.getClassResolver().resolveMandatoryClass( - SAXON_EXTENDED_FUNCTION_DEFINITION_CLASS_NAME, XsltSaxonComponent.class.getClassLoader() - ); - - method = configuration.getClass().getMethod("registerExtensionFunction", extensionClass); - if (method != null) { - factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - for (Object extensionFunction : saxonExtensionFunctions) { - if (extensionClass.isInstance(extensionFunction)) { - LOG.debug("Saxon.registerExtensionFunction {}", extensionFunction); - method.invoke(configuration, extensionFunction); - } - } - } else { - LOG.warn("Unable to get reference to method registerExtensionFunction on {}", configuration.getClass().getName()); - } - } else { - LOG.warn("Unable to get Saxon configuration ({}) on {}", SAXON_CONFIGURATION_CLASS_NAME, factory.getClass().getName()); + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + for (Object extensionFunction : saxonExtensionFunctions) { + if (extensionFunction instanceof ExtensionFunctionDefinition) { + LOG.debug("Saxon.registerExtensionFunction {}", extensionFunction); + factory.getConfiguration().registerExtensionFunction((ExtensionFunctionDefinition) extensionFunction); } - } else { - LOG.warn("Unable to get reference to method getConfiguration on {}", factoryClass.getName()); } } } + } diff --git a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java index 8cfbd00..63d2ad3 100644 --- a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java +++ b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltAggregationStrategy.java @@ -70,6 +70,7 @@ public class XsltAggregationStrategy extends ServiceSupport implements Aggregati private String propertyName; private final String xslFile; + private TransformerFactory transformerFactory; private String transformerFactoryClass; private XsltOutput output = XsltOutput.string; @@ -136,6 +137,10 @@ public class XsltAggregationStrategy extends ServiceSupport implements Aggregati this.transformerFactoryClass = transformerFactoryClass; } + public void setTransformerFactory(TransformerFactory transformerFactory) { + this.transformerFactory = transformerFactory; + } + public String getPropertyName() { return propertyName; } @@ -218,11 +223,13 @@ public class XsltAggregationStrategy extends ServiceSupport implements Aggregati // initialize the XsltBuilder this.xslt = createXsltBuilder(); - if (transformerFactoryClass != null) { + if (transformerFactory == null && transformerFactoryClass != null) { Class<?> factoryClass = camelContext.getClassResolver().resolveMandatoryClass(transformerFactoryClass, XsltAggregationStrategy.class.getClassLoader()); TransformerFactory factory = (TransformerFactory) camelContext.getInjector().newInstance(factoryClass); xslt.setTransformerFactory(factory); + } else if (transformerFactory != null) { + xslt.setTransformerFactory(transformerFactory); } if (uriResolver == null) { diff --git a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java index 09807d2..e6e5371 100644 --- a/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java +++ b/core/camel-endpointdsl/src/main/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java @@ -23,7 +23,7 @@ import org.apache.camel.builder.EndpointProducerBuilder; import org.apache.camel.builder.endpoint.AbstractEndpointBuilder; /** - * Transforms the message using a XSLT template. + * Transforms the message using a XSLT template using Saxon. * * Generated by camel-package-maven-plugin - do not edit this file! */ @@ -264,7 +264,7 @@ public interface XsltSaxonEndpointBuilderFactory { /** * To use a custom Saxon configuration. * - * The option is a: <code>java.lang.Object</code> type. + * The option is a: <code>net.sf.saxon.Configuration</code> type. * * Group: advanced */ @@ -276,7 +276,8 @@ public interface XsltSaxonEndpointBuilderFactory { /** * To use a custom Saxon configuration. * - * The option will be converted to a <code>java.lang.Object</code> type. + * The option will be converted to a + * <code>net.sf.saxon.Configuration</code> type. * * Group: advanced */ @@ -535,7 +536,7 @@ public interface XsltSaxonEndpointBuilderFactory { } /** * XSLT Saxon (camel-xslt-saxon) - * Transforms the message using a XSLT template. + * Transforms the message using a XSLT template using Saxon. * * Category: core,transformation * Available as of version: 3.0 diff --git a/platforms/spring-boot/components-starter/camel-xslt-saxon-starter/src/main/java/org/apache/camel/component/xslt/saxon/springboot/XsltSaxonComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-xslt-saxon-starter/src/main/java/org/apache/camel/component/xslt/saxon/springboot/XsltSaxonComponentConfiguration.java index b674ad2..c0238d8 100644 --- a/platforms/spring-boot/components-starter/camel-xslt-saxon-starter/src/main/java/org/apache/camel/component/xslt/saxon/springboot/XsltSaxonComponentConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-xslt-saxon-starter/src/main/java/org/apache/camel/component/xslt/saxon/springboot/XsltSaxonComponentConfiguration.java @@ -22,7 +22,7 @@ import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon; import org.springframework.boot.context.properties.ConfigurationProperties; /** - * Transforms the message using a XSLT template. + * Transforms the message using a XSLT template using Saxon. * * Generated by camel-package-maven-plugin - do not edit this file! */ @@ -45,8 +45,8 @@ public class XsltSaxonComponentConfiguration */ private String saxonExtensionFunctions; /** - * To use a custom Saxon configuration. The option is a java.lang.Object - * type. + * To use a custom Saxon configuration. The option is a + * net.sf.saxon.Configuration type. */ private String saxonConfiguration; /**