This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 7f04aacfae5 [CAMEL-18916] camel-xslt-saxon: allow logger injection (#10488) 7f04aacfae5 is described below commit 7f04aacfae5d94c6c96f04a5e6a08cc09a99e9ca Author: Adriano Machado <60320+ammach...@users.noreply.github.com> AuthorDate: Fri Jul 7 10:57:49 2023 -0400 [CAMEL-18916] camel-xslt-saxon: allow logger injection (#10488) Co-authored-by: Adriano Machado <admac...@redhat.com> --- .../org/apache/camel/catalog/components/xj.json | 5 +- .../camel/catalog/components/xslt-saxon.json | 5 +- .../org/apache/camel/catalog/components/xslt.json | 3 +- .../apache/camel/catalog/schemas/camel-spring.xsd | 2 +- .../camel/component/xj/XJEndpointUriFactory.java | 3 +- .../org/apache/camel/component/xj/xj.json | 5 +- .../xslt/saxon/XsltSaxonEndpointUriFactory.java | 3 +- .../camel/component/xslt/saxon/xslt-saxon.json | 5 +- .../component/xslt/saxon/XsltSaxonBuilder.java | 77 +++++++++++++++++++++- .../component/xslt/saxon/XsltSaxonComponent.java | 6 +- .../component/xslt/saxon/XsltSaxonEndpoint.java | 6 +- .../xslt/SaxonXsltXsltMessageLoggerTest.java | 62 +++++++++++++++++ .../component/xslt/TestXsltMessageLogger.java | 31 +++++++++ .../xslt/camelXsltContextWithMessageConsumer.xml | 41 ++++++++++++ .../camel/component/xslt/message_transform.xsl | 31 +++++++++ .../component/xslt/XsltEndpointConfigurer.java | 6 ++ .../component/xslt/XsltEndpointUriFactory.java | 3 +- .../org/apache/camel/component/xslt/xslt.json | 3 +- .../apache/camel/component/xslt/XsltBuilder.java | 32 +++++++-- .../apache/camel/component/xslt/XsltEndpoint.java | 17 +++++ .../camel/component/xslt/XsltMessageLogger.java | 34 ++++++++++ .../endpoint/dsl/XJEndpointBuilderFactory.java | 38 +++++++++-- .../endpoint/dsl/XsltEndpointBuilderFactory.java | 39 +++++++++-- .../dsl/XsltSaxonEndpointBuilderFactory.java | 39 +++++++++-- 24 files changed, 456 insertions(+), 40 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xj.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xj.json index 3d0a014999d..7586645a290 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xj.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xj.json @@ -27,7 +27,7 @@ "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...] "saxonConfiguration": { "index": 3, "kind": "property", "displayName": "Saxon Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "net.sf.saxon.Configuration", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Saxon configuration" }, "saxonConfigurationProperties": { "index": 4, "kind": "property", "displayName": "Saxon Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "To set custom Saxon configuration properties" }, - "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 separat [...] + "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 use commas to se [...] "secureProcessing": { "index": 6, "kind": "property", "displayName": "Secure Processing", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Feature for XML secure processing (see javax.xml.XMLConstants). This is enabled by default. However, when using Saxon Professional you may need to turn this off to allow Saxon to be able to use Java [...] "transformerFactoryClass": { "index": 7, "kind": "property", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 8, "kind": "property", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, @@ -56,6 +56,7 @@ "transformerFactory": { "index": 15, "kind": "parameter", "displayName": "Transformer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.TransformerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory" }, "transformerFactoryClass": { "index": 16, "kind": "parameter", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 17, "kind": "parameter", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, - "uriResolver": { "index": 18, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" } + "uriResolver": { "index": 18, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" }, + "xsltMessageLogger": { "index": 19, "kind": "parameter", "displayName": "Xslt Message Logger", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltMessageLogger", "deprecated": false, "autowired": false, "secret": false, "description": "A consumer to messages generated during XSLT transformations." } } } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt-saxon.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt-saxon.json index 9787cf9e388..ff9a9acaa03 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt-saxon.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt-saxon.json @@ -27,7 +27,7 @@ "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...] "saxonConfiguration": { "index": 3, "kind": "property", "displayName": "Saxon Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "net.sf.saxon.Configuration", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Saxon configuration" }, "saxonConfigurationProperties": { "index": 4, "kind": "property", "displayName": "Saxon Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "To set custom Saxon configuration properties" }, - "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 separat [...] + "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 use commas to se [...] "secureProcessing": { "index": 6, "kind": "property", "displayName": "Secure Processing", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Feature for XML secure processing (see javax.xml.XMLConstants). This is enabled by default. However, when using Saxon Professional you may need to turn this off to allow Saxon to be able to use Java [...] "transformerFactoryClass": { "index": 7, "kind": "property", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 8, "kind": "property", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, @@ -55,6 +55,7 @@ "transformerFactory": { "index": 14, "kind": "parameter", "displayName": "Transformer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.TransformerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory" }, "transformerFactoryClass": { "index": 15, "kind": "parameter", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 16, "kind": "parameter", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, - "uriResolver": { "index": 17, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" } + "uriResolver": { "index": 17, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" }, + "xsltMessageLogger": { "index": 18, "kind": "parameter", "displayName": "Xslt Message Logger", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltMessageLogger", "deprecated": false, "autowired": false, "secret": false, "description": "A consumer to messages generated during XSLT transformations." } } } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt.json index a82a03561a7..222c79fb51a 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/xslt.json @@ -47,6 +47,7 @@ "transformerFactory": { "index": 10, "kind": "parameter", "displayName": "Transformer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.TransformerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory" }, "transformerFactoryClass": { "index": 11, "kind": "parameter", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 12, "kind": "parameter", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, - "uriResolver": { "index": 13, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" } + "uriResolver": { "index": 13, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" }, + "xsltMessageLogger": { "index": 14, "kind": "parameter", "displayName": "Xslt Message Logger", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltMessageLogger", "deprecated": false, "autowired": false, "secret": false, "description": "A consumer to messages generated during XSLT transformations." } } } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd index 52d3831c7a7..84de91928ef 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd @@ -439,7 +439,7 @@ Enriches a message with data from a secondary resource <xs:annotation> <xs:documentation xml:lang="en"> <![CDATA[ -Camel error handling. +Error handler settings ]]> </xs:documentation> </xs:annotation> diff --git a/components/camel-xj/src/generated/java/org/apache/camel/component/xj/XJEndpointUriFactory.java b/components/camel-xj/src/generated/java/org/apache/camel/component/xj/XJEndpointUriFactory.java index 87e4f569006..4c009eabe4c 100644 --- a/components/camel-xj/src/generated/java/org/apache/camel/component/xj/XJEndpointUriFactory.java +++ b/components/camel-xj/src/generated/java/org/apache/camel/component/xj/XJEndpointUriFactory.java @@ -21,7 +21,7 @@ public class XJEndpointUriFactory extends org.apache.camel.support.component.End private static final Set<String> SECRET_PROPERTY_NAMES; private static final Set<String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(19); + Set<String> props = new HashSet<>(20); props.add("allowStAX"); props.add("contentCache"); props.add("deleteOutputFile"); @@ -41,6 +41,7 @@ public class XJEndpointUriFactory extends org.apache.camel.support.component.End props.add("transformerFactoryClass"); props.add("transformerFactoryConfigurationStrategy"); props.add("uriResolver"); + props.add("xsltMessageLogger"); PROPERTY_NAMES = Collections.unmodifiableSet(props); SECRET_PROPERTY_NAMES = Collections.emptySet(); MULTI_VALUE_PREFIXES = Collections.emptySet(); diff --git a/components/camel-xj/src/generated/resources/org/apache/camel/component/xj/xj.json b/components/camel-xj/src/generated/resources/org/apache/camel/component/xj/xj.json index 3d0a014999d..7586645a290 100644 --- a/components/camel-xj/src/generated/resources/org/apache/camel/component/xj/xj.json +++ b/components/camel-xj/src/generated/resources/org/apache/camel/component/xj/xj.json @@ -27,7 +27,7 @@ "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...] "saxonConfiguration": { "index": 3, "kind": "property", "displayName": "Saxon Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "net.sf.saxon.Configuration", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Saxon configuration" }, "saxonConfigurationProperties": { "index": 4, "kind": "property", "displayName": "Saxon Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "To set custom Saxon configuration properties" }, - "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 separat [...] + "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 use commas to se [...] "secureProcessing": { "index": 6, "kind": "property", "displayName": "Secure Processing", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Feature for XML secure processing (see javax.xml.XMLConstants). This is enabled by default. However, when using Saxon Professional you may need to turn this off to allow Saxon to be able to use Java [...] "transformerFactoryClass": { "index": 7, "kind": "property", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 8, "kind": "property", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, @@ -56,6 +56,7 @@ "transformerFactory": { "index": 15, "kind": "parameter", "displayName": "Transformer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.TransformerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory" }, "transformerFactoryClass": { "index": 16, "kind": "parameter", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 17, "kind": "parameter", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, - "uriResolver": { "index": 18, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" } + "uriResolver": { "index": 18, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" }, + "xsltMessageLogger": { "index": 19, "kind": "parameter", "displayName": "Xslt Message Logger", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltMessageLogger", "deprecated": false, "autowired": false, "secret": false, "description": "A consumer to messages generated during XSLT transformations." } } } diff --git a/components/camel-xslt-saxon/src/generated/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpointUriFactory.java b/components/camel-xslt-saxon/src/generated/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpointUriFactory.java index c400ffe264a..fdd68788457 100644 --- a/components/camel-xslt-saxon/src/generated/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpointUriFactory.java +++ b/components/camel-xslt-saxon/src/generated/java/org/apache/camel/component/xslt/saxon/XsltSaxonEndpointUriFactory.java @@ -21,7 +21,7 @@ public class XsltSaxonEndpointUriFactory extends org.apache.camel.support.compon private static final Set<String> SECRET_PROPERTY_NAMES; private static final Set<String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(18); + Set<String> props = new HashSet<>(19); props.add("allowStAX"); props.add("contentCache"); props.add("deleteOutputFile"); @@ -40,6 +40,7 @@ public class XsltSaxonEndpointUriFactory extends org.apache.camel.support.compon props.add("transformerFactoryClass"); props.add("transformerFactoryConfigurationStrategy"); props.add("uriResolver"); + props.add("xsltMessageLogger"); PROPERTY_NAMES = Collections.unmodifiableSet(props); SECRET_PROPERTY_NAMES = Collections.emptySet(); MULTI_VALUE_PREFIXES = Collections.emptySet(); diff --git a/components/camel-xslt-saxon/src/generated/resources/org/apache/camel/component/xslt/saxon/xslt-saxon.json b/components/camel-xslt-saxon/src/generated/resources/org/apache/camel/component/xslt/saxon/xslt-saxon.json index 9787cf9e388..ff9a9acaa03 100644 --- a/components/camel-xslt-saxon/src/generated/resources/org/apache/camel/component/xslt/saxon/xslt-saxon.json +++ b/components/camel-xslt-saxon/src/generated/resources/org/apache/camel/component/xslt/saxon/xslt-saxon.json @@ -27,7 +27,7 @@ "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...] "saxonConfiguration": { "index": 3, "kind": "property", "displayName": "Saxon Configuration", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "net.sf.saxon.Configuration", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom Saxon configuration" }, "saxonConfigurationProperties": { "index": 4, "kind": "property", "displayName": "Saxon Configuration Properties", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.Map<java.lang.String, java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "description": "To set custom Saxon configuration properties" }, - "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 separat [...] + "saxonExtensionFunctions": { "index": 5, "kind": "property", "displayName": "Saxon Extension Functions", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "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 use commas to se [...] "secureProcessing": { "index": 6, "kind": "property", "displayName": "Secure Processing", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Feature for XML secure processing (see javax.xml.XMLConstants). This is enabled by default. However, when using Saxon Professional you may need to turn this off to allow Saxon to be able to use Java [...] "transformerFactoryClass": { "index": 7, "kind": "property", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 8, "kind": "property", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, @@ -55,6 +55,7 @@ "transformerFactory": { "index": 14, "kind": "parameter", "displayName": "Transformer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.TransformerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory" }, "transformerFactoryClass": { "index": 15, "kind": "parameter", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 16, "kind": "parameter", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, - "uriResolver": { "index": 17, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" } + "uriResolver": { "index": 17, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" }, + "xsltMessageLogger": { "index": 18, "kind": "parameter", "displayName": "Xslt Message Logger", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltMessageLogger", "deprecated": false, "autowired": false, "secret": false, "description": "A consumer to messages generated during XSLT transformations." } } } diff --git a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonBuilder.java b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonBuilder.java index b7e96db532c..7a6c5a85ff8 100644 --- a/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonBuilder.java +++ b/components/camel-xslt-saxon/src/main/java/org/apache/camel/component/xslt/saxon/XsltSaxonBuilder.java @@ -16,11 +16,24 @@ */ package org.apache.camel.component.xslt.saxon; +import java.io.Writer; +import java.util.Properties; + import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.stax.StAXSource; -import org.apache.camel.component.xslt.XmlSourceHandlerFactoryImpl; +import net.sf.saxon.jaxp.TemplatesImpl; +import net.sf.saxon.jaxp.TransformerImpl; +import net.sf.saxon.lib.StandardMessageHandler; +import net.sf.saxon.str.UnicodeWriter; +import net.sf.saxon.str.UnicodeWriterToWriter; import org.apache.camel.component.xslt.XsltBuilder; +import org.apache.camel.component.xslt.XsltMessageLogger; +import org.apache.camel.component.xslt.XmlSourceHandlerFactoryImpl; import org.apache.camel.support.builder.xml.StAX2SAXSource; public class XsltSaxonBuilder extends XsltBuilder { @@ -56,4 +69,66 @@ public class XsltSaxonBuilder extends XsltBuilder { protected XmlSourceHandlerFactoryImpl createXmlSourceHandlerFactoryImpl() { return new SaxonXmlSourceHandlerFactoryImpl(); } + + @Override + protected Templates createTemplates(TransformerFactory factory, Source source) throws TransformerConfigurationException { + final Templates templates = super.createTemplates(factory, source); + if (templates instanceof TemplatesImpl && getXsltMessageLogger() != null) { + return new MessageDelegatingTemplates((TemplatesImpl) templates, getXsltMessageLogger()); + } + return templates; + } + + private static class MessageConsumerWriter extends Writer { + + private final XsltMessageLogger xsltMessageLogger; + + public MessageConsumerWriter(XsltMessageLogger xsltMessageLogger) { + this.xsltMessageLogger = xsltMessageLogger; + } + + @Override + public void write(char[] cbuf, int off, int len) { + if (len > 0) { + xsltMessageLogger.accept(String.copyValueOf(cbuf, off, len)); + } + } + + @Override + public void flush() { + } + + @Override + public void close() { + flush(); + } + } + + static class MessageDelegatingTemplates implements Templates { + + private final TemplatesImpl delegated; + + private final XsltMessageLogger xsltMessageLogger; + + MessageDelegatingTemplates(TemplatesImpl templates, XsltMessageLogger xsltMessageLogger) { + this.delegated = templates; + this.xsltMessageLogger = xsltMessageLogger; + } + + @Override + public Transformer newTransformer() throws TransformerConfigurationException { + final TransformerImpl transformer = (TransformerImpl) delegated.newTransformer(); + final StandardMessageHandler standardMessageHandler = new StandardMessageHandler(transformer.getConfiguration()); + final UnicodeWriter writer = new UnicodeWriterToWriter(new MessageConsumerWriter(xsltMessageLogger)); + standardMessageHandler.setUnicodeWriter(writer); + transformer.getUnderlyingXsltTransformer().setMessageHandler(standardMessageHandler); + + return transformer; + } + + @Override + public Properties getOutputProperties() { + return delegated.getOutputProperties(); + } + } } 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 98a634f5b26..e21898cc5ed 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 @@ -48,7 +48,8 @@ public class XsltSaxonComponent extends XsltComponent { /** * 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. + * classpath. The function is looked up in the registry, where you can use commas to separate multiple values to + * lookup. */ public void setSaxonExtensionFunctions(List<Object> extensionFunctions) { this.saxonExtensionFunctions = extensionFunctions; @@ -56,7 +57,8 @@ public class XsltSaxonComponent extends XsltComponent { /** * 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. + * classpath. The function is looked up in the registry, where you can use commas to separate multiple values to + * lookup. */ public void setSaxonExtensionFunctions(String extensionFunctions) { this.saxonExtensionFunctions = EndpointHelper.resolveReferenceListParameter( 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 bd534c915da..5dc002252d1 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 @@ -233,9 +233,13 @@ public class XsltSaxonEndpoint extends XsltEndpoint { xslt.setAllowStAX(allowStAX); xslt.setDeleteOutputFile(isDeleteOutputFile()); + if (getXsltMessageLogger() != null) { + xslt.setXsltMessageLogger(getXsltMessageLogger()); + } + configureOutput(xslt, getOutput().name()); - // any additional transformer parameters then make a copy to avoid side-effects + // any additional transformer parameters then make a copy to avoid side effects if (getParameters() != null) { Map<String, Object> copy = new HashMap<>(getParameters()); xslt.setParameters(copy); diff --git a/components/camel-xslt-saxon/src/test/java/org/apache/camel/component/xslt/SaxonXsltXsltMessageLoggerTest.java b/components/camel-xslt-saxon/src/test/java/org/apache/camel/component/xslt/SaxonXsltXsltMessageLoggerTest.java new file mode 100644 index 00000000000..5f53afc51b7 --- /dev/null +++ b/components/camel-xslt-saxon/src/test/java/org/apache/camel/component/xslt/SaxonXsltXsltMessageLoggerTest.java @@ -0,0 +1,62 @@ +/* + * 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.List; + +import org.apache.camel.Exchange; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.spring.junit5.CamelSpringTestSupport; +import org.junit.jupiter.api.Test; +import org.springframework.context.support.AbstractApplicationContext; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class SaxonXsltXsltMessageLoggerTest extends CamelSpringTestSupport { + + @Override + protected AbstractApplicationContext createApplicationContext() { + return newAppContext("camelXsltContextWithMessageConsumer.xml"); + } + + @Test + public void testSendMessageAndHaveItTransformed() throws Exception { + MockEndpoint endpoint = getMockEndpoint("mock:result"); + endpoint.expectedMessageCount(1); + + template.sendBody("direct:start", + "<mail><subject>Hey</subject><body>Hello world!</body></mail>"); + + MockEndpoint.assertIsSatisfied(context); + + List<Exchange> list = endpoint.getReceivedExchanges(); + Exchange exchange = list.get(0); + String xml = exchange.getIn().getBody(String.class); + + assertNotNull(xml, "The transformed XML should not be null"); + assertTrue(xml.contains("Hey")); + assertTrue(xml.contains("Hello world!")); + + TestXsltMessageLogger testXsltMessageLogger = applicationContext.getBean(TestXsltMessageLogger.class); + assertNotNull(testXsltMessageLogger); + String message = testXsltMessageLogger.getMessage(); + assertEquals("sample message", message); + + } +} diff --git a/components/camel-xslt-saxon/src/test/java/org/apache/camel/component/xslt/TestXsltMessageLogger.java b/components/camel-xslt-saxon/src/test/java/org/apache/camel/component/xslt/TestXsltMessageLogger.java new file mode 100644 index 00000000000..04d820fca6e --- /dev/null +++ b/components/camel-xslt-saxon/src/test/java/org/apache/camel/component/xslt/TestXsltMessageLogger.java @@ -0,0 +1,31 @@ +/* + * 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; + +public class TestXsltMessageLogger implements XsltMessageLogger { + + private final StringBuilder sb = new StringBuilder(); + + @Override + public void accept(String message) { + sb.append(message); + } + + public String getMessage() { + return sb.toString(); + } +} diff --git a/components/camel-xslt-saxon/src/test/resources/org/apache/camel/component/xslt/camelXsltContextWithMessageConsumer.xml b/components/camel-xslt-saxon/src/test/resources/org/apache/camel/component/xslt/camelXsltContextWithMessageConsumer.xml new file mode 100644 index 00000000000..d065c3732ea --- /dev/null +++ b/components/camel-xslt-saxon/src/test/resources/org/apache/camel/component/xslt/camelXsltContextWithMessageConsumer.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + "> + + <!-- START SNIPPET: example --> + <camelContext xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="direct:start"/> + <to uri="xslt-saxon:org/apache/camel/component/xslt/message_transform.xsl?transformerFactory=#factory&xsltMessageLogger=#xsltMessageLogger"/> + <multicast> + <to uri="mock:result"/> + </multicast> + </route> + </camelContext> + <!-- END SNIPPET: example --> + + <bean id="factory" class="net.sf.saxon.TransformerFactoryImpl"/> + <bean id="xsltMessageLogger" class="org.apache.camel.component.xslt.TestXsltMessageLogger"/> +</beans> diff --git a/components/camel-xslt-saxon/src/test/resources/org/apache/camel/component/xslt/message_transform.xsl b/components/camel-xslt-saxon/src/test/resources/org/apache/camel/component/xslt/message_transform.xsl new file mode 100644 index 00000000000..281517d63d8 --- /dev/null +++ b/components/camel-xslt-saxon/src/test/resources/org/apache/camel/component/xslt/message_transform.xsl @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- + + 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. + +--> +<xsl:stylesheet + xmlns:xsl='http://www.w3.org/1999/XSL/Transform' + version='2.0'> + + <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/> + + <xsl:template match="/"> + <xsl:message>sample message</xsl:message> + <xsl:copy-of select="*"/> + </xsl:template> + +</xsl:stylesheet> diff --git a/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointConfigurer.java b/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointConfigurer.java index 46be7be207d..0b868858f3e 100644 --- a/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointConfigurer.java +++ b/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointConfigurer.java @@ -46,6 +46,8 @@ public class XsltEndpointConfigurer extends PropertyConfigurerSupport implements case "transformerFactoryConfigurationStrategy": target.setTransformerFactoryConfigurationStrategy(property(camelContext, org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy.class, value)); return true; case "uriresolver": case "uriResolver": target.setUriResolver(property(camelContext, javax.xml.transform.URIResolver.class, value)); return true; + case "xsltmessagelogger": + case "xsltMessageLogger": target.setXsltMessageLogger(property(camelContext, org.apache.camel.component.xslt.XsltMessageLogger.class, value)); return true; default: return false; } } @@ -78,6 +80,8 @@ public class XsltEndpointConfigurer extends PropertyConfigurerSupport implements case "transformerFactoryConfigurationStrategy": return org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy.class; case "uriresolver": case "uriResolver": return javax.xml.transform.URIResolver.class; + case "xsltmessagelogger": + case "xsltMessageLogger": return org.apache.camel.component.xslt.XsltMessageLogger.class; default: return null; } } @@ -111,6 +115,8 @@ public class XsltEndpointConfigurer extends PropertyConfigurerSupport implements case "transformerFactoryConfigurationStrategy": return target.getTransformerFactoryConfigurationStrategy(); case "uriresolver": case "uriResolver": return target.getUriResolver(); + case "xsltmessagelogger": + case "xsltMessageLogger": return target.getXsltMessageLogger(); default: return null; } } diff --git a/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointUriFactory.java b/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointUriFactory.java index 05f6f203d4e..3e8506e877b 100644 --- a/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointUriFactory.java +++ b/components/camel-xslt/src/generated/java/org/apache/camel/component/xslt/XsltEndpointUriFactory.java @@ -21,7 +21,7 @@ public class XsltEndpointUriFactory extends org.apache.camel.support.component.E private static final Set<String> SECRET_PROPERTY_NAMES; private static final Set<String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(14); + Set<String> props = new HashSet<>(15); props.add("contentCache"); props.add("deleteOutputFile"); props.add("entityResolver"); @@ -36,6 +36,7 @@ public class XsltEndpointUriFactory extends org.apache.camel.support.component.E props.add("transformerFactoryClass"); props.add("transformerFactoryConfigurationStrategy"); props.add("uriResolver"); + props.add("xsltMessageLogger"); PROPERTY_NAMES = Collections.unmodifiableSet(props); SECRET_PROPERTY_NAMES = Collections.emptySet(); MULTI_VALUE_PREFIXES = Collections.emptySet(); diff --git a/components/camel-xslt/src/generated/resources/org/apache/camel/component/xslt/xslt.json b/components/camel-xslt/src/generated/resources/org/apache/camel/component/xslt/xslt.json index a82a03561a7..222c79fb51a 100644 --- a/components/camel-xslt/src/generated/resources/org/apache/camel/component/xslt/xslt.json +++ b/components/camel-xslt/src/generated/resources/org/apache/camel/component/xslt/xslt.json @@ -47,6 +47,7 @@ "transformerFactory": { "index": 10, "kind": "parameter", "displayName": "Transformer Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.TransformerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory" }, "transformerFactoryClass": { "index": 11, "kind": "parameter", "displayName": "Transformer Factory Class", "group": "advanced", "label": "advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom XSLT transformer factory, specified as a FQN class name" }, "transformerFactoryConfigurationStrategy": { "index": 12, "kind": "parameter", "displayName": "Transformer Factory Configuration Strategy", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.TransformerFactoryConfigurationStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "A configuration strategy to apply on freshly created instances of TransformerFactory." }, - "uriResolver": { "index": 13, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" } + "uriResolver": { "index": 13, "kind": "parameter", "displayName": "Uri Resolver", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "javax.xml.transform.URIResolver", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom javax.xml.transform.URIResolver" }, + "xsltMessageLogger": { "index": 14, "kind": "parameter", "displayName": "Xslt Message Logger", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.camel.component.xslt.XsltMessageLogger", "deprecated": false, "autowired": false, "secret": false, "description": "A consumer to messages generated during XSLT transformations." } } } diff --git a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltBuilder.java b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltBuilder.java index 234951ba71e..9bbf8036427 100644 --- a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltBuilder.java +++ b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltBuilder.java @@ -56,14 +56,13 @@ import static org.apache.camel.util.ObjectHelper.notNull; * Creates a <a href="http://camel.apache.org/processor.html">Processor</a> which performs an XSLT transformation of the * IN message body. * <p/> - * Will by default output the result as a String. You can chose which kind of output you want using the + * Will by default output the result as a String. You can choose which kind of output you want using the * <tt>outputXXX</tt> methods. */ public class XsltBuilder implements Processor { protected static final Logger LOG = LoggerFactory.getLogger(XsltBuilder.class); private Map<String, Object> parameters = new HashMap<>(); - private XMLConverterHelper converter = new XMLConverterHelper(); private Templates template; private volatile BlockingQueue<Transformer> transformers; private volatile SourceHandlerFactory sourceHandlerFactory; @@ -73,7 +72,9 @@ public class XsltBuilder implements Processor { private boolean deleteOutputFile; private ErrorListener errorListener; private EntityResolver entityResolver; + private XsltMessageLogger xsltMessageLogger; + private final XMLConverterHelper converter = new XMLConverterHelper(); private final Object sourceHandlerFactoryLock = new Object(); public XsltBuilder() { @@ -93,7 +94,7 @@ public class XsltBuilder implements Processor { notNull(getTemplate(), "template"); if (isDeleteOutputFile()) { - // add on completion so we can delete the file when the Exchange is done + // add on completion, so we can delete the file when the Exchange is done String fileName = ExchangeHelper.getMandatoryHeader(exchange, XsltConstants.XSLT_FILE_NAME, String.class); exchange.getExchangeExtension().addOnCompletion(new XsltBuilderOnCompletion(fileName)); } @@ -260,6 +261,11 @@ public class XsltBuilder implements Processor { return this; } + public XsltBuilder xsltMessageLogger(XsltMessageLogger xsltMessageLogger) { + setXsltMessageLogger(xsltMessageLogger); + return this; + } + // Properties // ------------------------------------------------------------------------- @@ -320,6 +326,10 @@ public class XsltBuilder implements Processor { this.resultHandlerFactory = resultHandlerFactory; } + protected Templates createTemplates(TransformerFactory factory, Source source) throws TransformerConfigurationException { + return factory.newTemplates(source); + } + /** * Sets the XSLT transformer from a Source * @@ -338,10 +348,10 @@ public class XsltBuilder implements Processor { factory.setURIResolver(getUriResolver()); } - // Check that the call to newTemplates() returns a valid template instance. - // In case of an xslt parse error, it will return null and we should stop the + // Check that the call to createTemplates() returns a valid template instance. + // In case of a xslt parse error, it will return null, and we should stop the // deployment and raise an exception as the route will not be setup properly. - Templates templates = factory.newTemplates(source); + Templates templates = createTemplates(factory, source); if (templates != null) { setTemplate(templates); } else { @@ -409,6 +419,14 @@ public class XsltBuilder implements Processor { this.converter.setTransformerFactory(transformerFactory); } + public XsltMessageLogger getXsltMessageLogger() { + return xsltMessageLogger; + } + + public void setXsltMessageLogger(XsltMessageLogger xsltMessageLogger) { + this.xsltMessageLogger = xsltMessageLogger; + } + private void releaseTransformer(Transformer transformer) { if (transformers != null) { transformer.reset(); @@ -450,7 +468,7 @@ public class XsltBuilder implements Processor { } transformer.setURIResolver(uriResolver); if (errorListener == null) { - // set our error listener so we can capture errors and report them back on the exchange + // set our error listener, so we can capture errors and report them back on the exchange transformer.setErrorListener(new DefaultTransformErrorHandler(exchange)); } else { // use custom error listener diff --git a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltEndpoint.java b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltEndpoint.java index 993bfb4d991..8ebaf38954d 100644 --- a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltEndpoint.java +++ b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltEndpoint.java @@ -89,6 +89,8 @@ public class XsltEndpoint extends ProcessorEndpoint { private EntityResolver entityResolver; @UriParam(label = "advanced") private TransformerFactoryConfigurationStrategy transformerFactoryConfigurationStrategy; + @UriParam(label = "advanced") + private XsltMessageLogger xsltMessageLogger; public XsltEndpoint(String endpointUri, Component component) { super(endpointUri, component); @@ -311,6 +313,17 @@ public class XsltEndpoint extends ProcessorEndpoint { this.transformerFactoryConfigurationStrategy = transformerFactoryConfigurationStrategy; } + public XsltMessageLogger getXsltMessageLogger() { + return xsltMessageLogger; + } + + /** + * A consumer to messages generated during XSLT transformations. + */ + public void setXsltMessageLogger(XsltMessageLogger xsltMessageLogger) { + this.xsltMessageLogger = xsltMessageLogger; + } + /** * Loads the resource. * @@ -403,6 +416,10 @@ public class XsltEndpoint extends ProcessorEndpoint { xslt.setResultHandlerFactory(resultHandlerFactory); } + if (xsltMessageLogger != null) { + xslt.setXsltMessageLogger(xsltMessageLogger); + } + // any additional transformer parameters then make a copy to avoid side-effects if (parameters != null) { Map<String, Object> copy = new HashMap<>(parameters); diff --git a/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltMessageLogger.java b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltMessageLogger.java new file mode 100644 index 00000000000..fd46091a6be --- /dev/null +++ b/components/camel-xslt/src/main/java/org/apache/camel/component/xslt/XsltMessageLogger.java @@ -0,0 +1,34 @@ +/* + * 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; + +/** + * Interface for handling {@code xsl:message} and {@code xsl:assert} output from XSLT transformations. Note that the + * same message handler may be called to process messages emanating from multiple threads. The message consumer must + * therefore be thread-safe; and the order in which messages are passed to the message handler is not always + * predictable. + */ +@FunctionalInterface +public interface XsltMessageLogger { + + /** + * Consumes a message generated by a XSLT transformation. + * + * @param message the message generated by the XSLT transformation. + */ + void accept(String message); +} diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XJEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XJEndpointBuilderFactory.java index 735b2a954a6..11ee8aa5e87 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XJEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XJEndpointBuilderFactory.java @@ -16,14 +16,11 @@ */ package org.apache.camel.builder.endpoint.dsl; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.stream.*; import javax.annotation.processing.Generated; -import org.apache.camel.builder.EndpointConsumerBuilder; + import org.apache.camel.builder.EndpointProducerBuilder; import org.apache.camel.builder.endpoint.AbstractEndpointBuilder; +import org.apache.camel.component.xslt.XsltMessageLogger; /** * Transform JSON and XML message using a XSLT. @@ -430,6 +427,37 @@ public interface XJEndpointBuilderFactory { doSetProperty("errorListener", errorListener); return this; } + /** + * A consumer to messages generated during XSLT transformations. + * + * The option is a: + * <code>org.apache.camel.component.xslt.MessageConsumer</code> type. + * + * Group: advanced + * + * @param xsltMessageLogger the value to set + * @return the dsl builder + */ + default AdvancedXJEndpointBuilder messageConsumer( + XsltMessageLogger xsltMessageLogger) { + doSetProperty("xsltMessageLogger", xsltMessageLogger); + return this; + } + /** + * A consumer to messages generated during XSLT transformations. + * + * The option will be converted to a + * <code>org.apache.camel.component.xslt.MessageConsumer</code> type. + * + * Group: advanced + * + * @param messageConsumer the value to set + * @return the dsl builder + */ + default AdvancedXJEndpointBuilder messageConsumer(String messageConsumer) { + doSetProperty("messageConsumer", messageConsumer); + return this; + } /** * Allows you to use a custom * org.apache.camel.builder.xml.ResultHandlerFactory which is capable of diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltEndpointBuilderFactory.java index 5acb85b3886..6ceb7460d2f 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltEndpointBuilderFactory.java @@ -16,14 +16,11 @@ */ package org.apache.camel.builder.endpoint.dsl; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.stream.*; import javax.annotation.processing.Generated; -import org.apache.camel.builder.EndpointConsumerBuilder; + import org.apache.camel.builder.EndpointProducerBuilder; import org.apache.camel.builder.endpoint.AbstractEndpointBuilder; +import org.apache.camel.component.xslt.XsltMessageLogger; /** * Transforms XML payload using an XSLT template. @@ -361,6 +358,38 @@ public interface XsltEndpointBuilderFactory { doSetProperty("errorListener", errorListener); return this; } + /** + * A consumer to messages generated during XSLT transformations. + * + * The option is a: + * <code>org.apache.camel.component.xslt.MessageConsumer</code> type. + * + * Group: advanced + * + * @param xsltMessageLogger the value to set + * @return the dsl builder + */ + default AdvancedXsltEndpointBuilder messageConsumer( + XsltMessageLogger xsltMessageLogger) { + doSetProperty("xsltMessageLogger", xsltMessageLogger); + return this; + } + /** + * A consumer to messages generated during XSLT transformations. + * + * The option will be converted to a + * <code>org.apache.camel.component.xslt.MessageConsumer</code> type. + * + * Group: advanced + * + * @param messageConsumer the value to set + * @return the dsl builder + */ + default AdvancedXsltEndpointBuilder messageConsumer( + String messageConsumer) { + doSetProperty("messageConsumer", messageConsumer); + return this; + } /** * Allows you to use a custom * org.apache.camel.builder.xml.ResultHandlerFactory which is capable of diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java index 093a5db5b98..e7f50f6225f 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/XsltSaxonEndpointBuilderFactory.java @@ -16,14 +16,11 @@ */ package org.apache.camel.builder.endpoint.dsl; -import java.util.*; -import java.util.concurrent.*; -import java.util.function.*; -import java.util.stream.*; import javax.annotation.processing.Generated; -import org.apache.camel.builder.EndpointConsumerBuilder; + import org.apache.camel.builder.EndpointProducerBuilder; import org.apache.camel.builder.endpoint.AbstractEndpointBuilder; +import org.apache.camel.component.xslt.XsltMessageLogger; /** * Transform XML payloads using an XSLT template using Saxon. @@ -402,6 +399,38 @@ public interface XsltSaxonEndpointBuilderFactory { doSetProperty("errorListener", errorListener); return this; } + /** + * A consumer to messages generated during XSLT transformations. + * + * The option is a: + * <code>org.apache.camel.component.xslt.MessageConsumer</code> type. + * + * Group: advanced + * + * @param xsltMessageLogger the value to set + * @return the dsl builder + */ + default AdvancedXsltSaxonEndpointBuilder messageConsumer( + XsltMessageLogger xsltMessageLogger) { + doSetProperty("xsltMessageLogger", xsltMessageLogger); + return this; + } + /** + * A consumer to messages generated during XSLT transformations. + * + * The option will be converted to a + * <code>org.apache.camel.component.xslt.MessageConsumer</code> type. + * + * Group: advanced + * + * @param messageConsumer the value to set + * @return the dsl builder + */ + default AdvancedXsltSaxonEndpointBuilder messageConsumer( + String messageConsumer) { + doSetProperty("messageConsumer", messageConsumer); + return this; + } /** * Allows you to use a custom * org.apache.camel.builder.xml.ResultHandlerFactory which is capable of