This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch camel-3.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-3.x by this push: new 9c5339b82bb CAMEL-19079: camel-language - Should init expression. Add resultType as configuration option. 9c5339b82bb is described below commit 9c5339b82bb2c067f02de40c3f582e83a4dba4f7 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Sat Feb 25 18:26:04 2023 +0100 CAMEL-19079: camel-language - Should init expression. Add resultType as configuration option. --- .../apache/camel/catalog/components/language.json | 1 + .../language/LanguageEndpointConfigurer.java | 6 ++++ .../language/LanguageEndpointUriFactory.java | 3 +- .../apache/camel/component/language/language.json | 1 + .../camel/component/language/LanguageEndpoint.java | 32 +++++++++++++---- .../camel/component/language/LanguageProducer.java | 14 +++++++- .../XQueryLanguageProducerTemplateTest.java | 41 ++++++++++++++++++++++ .../dsl/LanguageEndpointBuilderFactory.java | 14 ++++++++ 8 files changed, 103 insertions(+), 9 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/language.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/language.json index da622e8e69d..5bce1dc1155 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/language.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/language.json @@ -35,6 +35,7 @@ "binary": { "kind": "parameter", "displayName": "Binary", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the script is binary content or text content. By default the script is read as text content (eg java.lang.String)" }, "cacheScript": { "kind": "parameter", "displayName": "Cache Script", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to cache the compiled script and reuse Notice reusing the script can cause side effects from processing one Camel org.apache.camel.Exchange to the next org.apache.camel.Exchange." }, "contentCache": { "kind": "parameter", "displayName": "Content Cache", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to use resource content cache or not" }, + "resultType": { "kind": "parameter", "displayName": "Result Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, "script": { "kind": "parameter", "displayName": "Script", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the script to execute" }, "transform": { "kind": "parameter", "displayName": "Transform", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether or not the result of the script should be used as message body. This options is default true." }, "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "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 other [...] diff --git a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java index ead8210e747..7260366f861 100644 --- a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java +++ b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointConfigurer.java @@ -30,6 +30,8 @@ public class LanguageEndpointConfigurer extends PropertyConfigurerSupport implem case "contentCache": target.setContentCache(property(camelContext, boolean.class, value)); return true; case "lazystartproducer": case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true; + case "resulttype": + case "resultType": target.setResultType(property(camelContext, java.lang.String.class, value)); return true; case "script": target.setScript(property(camelContext, java.lang.String.class, value)); return true; case "transform": target.setTransform(property(camelContext, boolean.class, value)); return true; default: return false; @@ -48,6 +50,8 @@ public class LanguageEndpointConfigurer extends PropertyConfigurerSupport implem case "contentCache": return boolean.class; case "lazystartproducer": case "lazyStartProducer": return boolean.class; + case "resulttype": + case "resultType": return java.lang.String.class; case "script": return java.lang.String.class; case "transform": return boolean.class; default: return null; @@ -67,6 +71,8 @@ public class LanguageEndpointConfigurer extends PropertyConfigurerSupport implem case "contentCache": return target.isContentCache(); case "lazystartproducer": case "lazyStartProducer": return target.isLazyStartProducer(); + case "resulttype": + case "resultType": return target.getResultType(); case "script": return target.getScript(); case "transform": return target.isTransform(); default: return null; diff --git a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java index 7a4c12385ee..f49a39fdec2 100644 --- a/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java +++ b/components/camel-language/src/generated/java/org/apache/camel/component/language/LanguageEndpointUriFactory.java @@ -21,7 +21,7 @@ public class LanguageEndpointUriFactory extends org.apache.camel.support.compone private static final Set<String> SECRET_PROPERTY_NAMES; private static final Set<String> MULTI_VALUE_PREFIXES; static { - Set<String> props = new HashSet<>(9); + Set<String> props = new HashSet<>(10); props.add("allowContextMapAll"); props.add("binary"); props.add("cacheScript"); @@ -29,6 +29,7 @@ public class LanguageEndpointUriFactory extends org.apache.camel.support.compone props.add("languageName"); props.add("lazyStartProducer"); props.add("resourceUri"); + props.add("resultType"); props.add("script"); props.add("transform"); PROPERTY_NAMES = Collections.unmodifiableSet(props); diff --git a/components/camel-language/src/generated/resources/org/apache/camel/component/language/language.json b/components/camel-language/src/generated/resources/org/apache/camel/component/language/language.json index da622e8e69d..5bce1dc1155 100644 --- a/components/camel-language/src/generated/resources/org/apache/camel/component/language/language.json +++ b/components/camel-language/src/generated/resources/org/apache/camel/component/language/language.json @@ -35,6 +35,7 @@ "binary": { "kind": "parameter", "displayName": "Binary", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the script is binary content or text content. By default the script is read as text content (eg java.lang.String)" }, "cacheScript": { "kind": "parameter", "displayName": "Cache Script", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to cache the compiled script and reuse Notice reusing the script can cause side effects from processing one Camel org.apache.camel.Exchange to the next org.apache.camel.Exchange." }, "contentCache": { "kind": "parameter", "displayName": "Content Cache", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Sets whether to use resource content cache or not" }, + "resultType": { "kind": "parameter", "displayName": "Result Type", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the class of the result type (type from output)" }, "script": { "kind": "parameter", "displayName": "Script", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Sets the script to execute" }, "transform": { "kind": "parameter", "displayName": "Transform", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether or not the result of the script should be used as message body. This options is default true." }, "lazyStartProducer": { "kind": "parameter", "displayName": "Lazy Start Producer", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "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 other [...] diff --git a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java index e46f308c20e..3e0d71b8e75 100644 --- a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java +++ b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageEndpoint.java @@ -18,8 +18,8 @@ package org.apache.camel.component.language; import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import org.apache.camel.Category; import org.apache.camel.Component; @@ -37,6 +37,7 @@ import org.apache.camel.spi.UriPath; import org.apache.camel.support.CamelContextHelper; import org.apache.camel.support.EndpointHelper; import org.apache.camel.support.ResourceHelper; +import org.apache.camel.support.TypedLanguageSupport; import org.apache.camel.util.IOHelper; /** @@ -58,7 +59,7 @@ public class LanguageEndpoint extends ResourceEndpoint { private String languageName; // resourceUri is optional in the language endpoint @UriPath(description = "Path to the resource, or a reference to lookup a bean in the Registry to use as the resource") - @Metadata(required = false) + @Metadata private String resourceUri; @UriParam private String script; @@ -70,6 +71,8 @@ public class LanguageEndpoint extends ResourceEndpoint { private boolean cacheScript; @UriParam(defaultValue = "true", description = "Sets whether to use resource content cache or not") private boolean contentCache; + @UriParam + private String resultType; public LanguageEndpoint() { // enable cache by default @@ -90,6 +93,10 @@ public class LanguageEndpoint extends ResourceEndpoint { if (language == null && languageName != null) { language = getCamelContext().resolveLanguage(languageName); } + if (language instanceof TypedLanguageSupport && resultType != null) { + Class<?> clazz = getCamelContext().getClassResolver().resolveMandatoryClass(resultType); + ((TypedLanguageSupport) language).setResultType(clazz); + } if (cacheScript && expression == null && script != null) { boolean external = script.startsWith("file:") || script.startsWith("http:"); if (!external) { @@ -98,6 +105,9 @@ public class LanguageEndpoint extends ResourceEndpoint { expression = language.createExpression(script); } } + if (expression != null) { + expression.init(getCamelContext()); + } } @Override @@ -105,6 +115,7 @@ public class LanguageEndpoint extends ResourceEndpoint { if (cacheScript && expression == null && script != null) { script = resolveScript(script); expression = language.createExpression(script); + expression.init(getCamelContext()); } return new LanguageProducer(this); @@ -141,11 +152,7 @@ public class LanguageEndpoint extends ResourceEndpoint { @Override protected String createEndpointUri() { String s = script; - try { - s = URLEncoder.encode(s, "UTF-8"); - } catch (UnsupportedEncodingException e) { - // ignore - } + s = URLEncoder.encode(s, StandardCharsets.UTF_8); return languageName + ":" + s; } @@ -254,6 +261,17 @@ public class LanguageEndpoint extends ResourceEndpoint { this.cacheScript = cacheScript; } + public String getResultType() { + return resultType; + } + + /** + * Sets the class of the result type (type from output) + */ + public void setResultType(String resultType) { + this.resultType = resultType; + } + @Override public void clearContentCache() { super.clearContentCache(); diff --git a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java index ae825ad4779..966d0f78a7a 100644 --- a/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java +++ b/components/camel-language/src/main/java/org/apache/camel/component/language/LanguageProducer.java @@ -36,6 +36,8 @@ public class LanguageProducer extends DefaultProducer { private static final Logger LOG = LoggerFactory.getLogger(LanguageProducer.class); + private Class<?> resultType = Object.class; + public LanguageProducer(LanguageEndpoint endpoint) { super(endpoint); } @@ -52,6 +54,7 @@ public class LanguageProducer extends DefaultProducer { // the script may be a file: so resolve it before using script = getEndpoint().resolveScript(script); exp = getEndpoint().getLanguage().createExpression(script); + exp.init(getEndpoint().getCamelContext()); } } // if not fallback to use expression from endpoint @@ -95,6 +98,7 @@ public class LanguageProducer extends DefaultProducer { if (script != null) { // create the expression from the script exp = getEndpoint().getLanguage().createExpression(script); + exp.init(getEndpoint().getCamelContext()); // expression was resolved from resource getEndpoint().setContentResolvedFromResource(true); // if we cache then set this as expression on endpoint so we don't re-create it again @@ -107,7 +111,7 @@ public class LanguageProducer extends DefaultProducer { Object result; if (exp != null) { try { - result = exp.evaluate(exchange, Object.class); + result = exp.evaluate(exchange, resultType); LOG.debug("Evaluated expression as: {} with: {}", result, exchange); } finally { if (!getEndpoint().isCacheScript()) { @@ -131,4 +135,12 @@ public class LanguageProducer extends DefaultProducer { public LanguageEndpoint getEndpoint() { return (LanguageEndpoint) super.getEndpoint(); } + + @Override + protected void doBuild() throws Exception { + if (getEndpoint().getResultType() != null) { + resultType = getEndpoint().getCamelContext() + .getClassResolver().resolveMandatoryClass(getEndpoint().getResultType()); + } + } } diff --git a/components/camel-saxon/src/test/java/org/apache/camel/language/XQueryLanguageProducerTemplateTest.java b/components/camel-saxon/src/test/java/org/apache/camel/language/XQueryLanguageProducerTemplateTest.java new file mode 100644 index 00000000000..f998dea06bb --- /dev/null +++ b/components/camel-saxon/src/test/java/org/apache/camel/language/XQueryLanguageProducerTemplateTest.java @@ -0,0 +1,41 @@ +/* + * 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.language; + +import org.apache.camel.CamelContext; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.impl.DefaultCamelContext; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class XQueryLanguageProducerTemplateTest { + + @Test + public void testXQueryLanguage() { + CamelContext context = new DefaultCamelContext(); + context.start(); + + ProducerTemplate producer = context.createProducerTemplate(); + String result = producer.requestBody( + "language:xquery:upper-case(/message/text())?resultType=String", + "<message>Hello from XQuery</message>", + String.class); + Assertions.assertEquals("HELLO FROM XQUERY", result); + + context.stop(); + } +} diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LanguageEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LanguageEndpointBuilderFactory.java index af2b5ed1dda..1efd0c6a072 100644 --- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LanguageEndpointBuilderFactory.java +++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/LanguageEndpointBuilderFactory.java @@ -181,6 +181,20 @@ public interface LanguageEndpointBuilderFactory { doSetProperty("contentCache", contentCache); return this; } + /** + * Sets the class of the result type (type from output). + * + * The option is a: <code>java.lang.String</code> type. + * + * Group: producer + * + * @param resultType the value to set + * @return the dsl builder + */ + default LanguageEndpointBuilder resultType(String resultType) { + doSetProperty("resultType", resultType); + return this; + } /** * Sets the script to execute. *