This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch lang4
in repository https://gitbox.apache.org/repos/asf/camel.git

commit edc439af1f818aabd2775073a88d6a6b3846a51c
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Feb 3 11:14:50 2024 +0100

    CAMEL-20378: Languages should be thread-safe and be configured only via 
properties array, all in the same way.
---
 .../camel/component/hl7/Hl7TerserLanguage.java     |  14 +--
 .../org/apache/camel/language/jq/JqLanguage.java   |  17 ----
 .../java/org/apache/camel/jsonpath/JsonPath.java   |  11 ++-
 .../JsonPathAnnotationExpressionFactory.java       |  16 ++-
 .../org/apache/camel/jsonpath/JsonPathEngine.java  |  33 ++-----
 .../apache/camel/jsonpath/JsonPathExpression.java  |  42 ++------
 .../apache/camel/jsonpath/JsonPathLanguage.java    |  47 +++------
 .../camel/jsonpath/JsonPathLanguageTest.java       |  14 +--
 .../component/xquery/XQueryEndpointConfigurer.java |   6 ++
 .../component/xquery/XQueryEndpointUriFactory.java |   3 +-
 .../org/apache/camel/component/xquery/xquery.json  |  55 +++++------
 .../org/apache/camel/component/xquery/XQuery.java  |  11 ++-
 .../xquery/XQueryAnnotationExpressionFactory.java  |  16 ++-
 .../camel/component/xquery/XQueryBuilder.java      | 107 +++++----------------
 .../camel/component/xquery/XQueryEndpoint.java     |  19 +++-
 .../camel/language/xquery/XQueryLanguage.java      |  48 +--------
 .../language/JsonPathExpressionReifier.java        |  18 ++--
 .../reifier/language/XQueryExpressionReifier.java  |   6 +-
 18 files changed, 171 insertions(+), 312 deletions(-)

diff --git 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
index bf8048169c3..0732c2e308a 100644
--- 
a/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
+++ 
b/components/camel-hl7/src/main/java/org/apache/camel/component/hl7/Hl7TerserLanguage.java
@@ -22,10 +22,8 @@ import ca.uhn.hl7v2.util.Terser;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
-import org.apache.camel.Predicate;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.support.ExpressionAdapter;
-import org.apache.camel.support.ExpressionToPredicateAdapter;
 import org.apache.camel.support.SingleInputTypedLanguageSupport;
 import org.apache.camel.support.builder.ExpressionBuilder;
 import org.apache.camel.util.ObjectHelper;
@@ -65,17 +63,7 @@ public class Hl7TerserLanguage extends 
SingleInputTypedLanguageSupport {
     }
 
     @Override
-    public Predicate createPredicate(String expression) {
-        return 
ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
-    }
-
-    @Override
-    public Expression createExpression(String expression) {
-        return terser(expression);
-    }
-
-    @Override
-    protected Expression createExpression(Expression source, String 
expression, Object[] properties) {
+    public Expression createExpression(Expression source, String expression, 
Object[] properties) {
         return terser(source, expression);
     }
 }
diff --git 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
index 027b3684195..9be23525b60 100644
--- 
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
+++ 
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
@@ -19,10 +19,8 @@ package org.apache.camel.language.jq;
 import net.thisptr.jackson.jq.Scope;
 import net.thisptr.jackson.jq.module.loaders.BuiltinModuleLoader;
 import org.apache.camel.Expression;
-import org.apache.camel.Predicate;
 import org.apache.camel.StaticService;
 import org.apache.camel.spi.annotations.Language;
-import org.apache.camel.support.ExpressionToPredicateAdapter;
 import org.apache.camel.support.SingleInputTypedLanguageSupport;
 import org.apache.camel.util.ObjectHelper;
 
@@ -57,21 +55,6 @@ public class JqLanguage extends 
SingleInputTypedLanguageSupport implements Stati
         // noop
     }
 
-    @Override
-    public Predicate createPredicate(String expression) {
-        return 
ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
-    }
-
-    @Override
-    public Expression createExpression(String expression) {
-        return createExpression(expression, null);
-    }
-
-    @Override
-    public Predicate createPredicate(String expression, Object[] properties) {
-        return 
ExpressionToPredicateAdapter.toPredicate(createExpression(expression, 
properties));
-    }
-
     @Override
     public Expression createExpression(Expression source, String expression, 
Object[] properties) {
         JqExpression answer = new JqExpression(Scope.newChildScope(rootScope), 
expression);
diff --git 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java
 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java
index 118f3995d9b..b7e24366d95 100644
--- 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java
+++ 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPath.java
@@ -58,14 +58,17 @@ public @interface JsonPath {
     Class<?> resultType() default Object.class;
 
     /**
-     * @return The name of the header we want to apply the expression to. If 
this is empty then the expression will be
-     *         applied to the value of the exchange property or the body 
instead.
+     * The name of the variable we want to apply the expression to.
+     */
+    String variableName() default "";
+
+    /**
+     * The name of the header we want to apply the expression to.
      */
     String headerName() default "";
 
     /**
-     * @return The name of the property we want to apply the expression to. If 
this is empty then the expression will be
-     *         applied to the body instead.
+     * The name of the exchange property we want to apply the expression to.
      */
     String propertyName() default "";
 }
diff --git 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java
 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java
index 39c8ef43df5..312ea82994a 100644
--- 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java
+++ 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathAnnotationExpressionFactory.java
@@ -21,6 +21,7 @@ import java.lang.annotation.Annotation;
 import com.jayway.jsonpath.Option;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
+import org.apache.camel.support.builder.ExpressionBuilder;
 import org.apache.camel.support.language.DefaultAnnotationExpressionFactory;
 import org.apache.camel.support.language.LanguageAnnotation;
 import org.apache.camel.util.ObjectHelper;
@@ -48,12 +49,23 @@ public class JsonPathAnnotationExpressionFactory extends 
DefaultAnnotationExpres
 
             
answer.setSuppressExceptions(jsonPathAnnotation.suppressExceptions());
             answer.setAllowSimple(jsonPathAnnotation.allowSimple());
+
+            String variableName = null;
+            String headerName = null;
+            String propertyName = null;
+            if (ObjectHelper.isNotEmpty(jsonPathAnnotation.variableName())) {
+                variableName = jsonPathAnnotation.variableName();
+            }
             if (ObjectHelper.isNotEmpty(jsonPathAnnotation.headerName())) {
-                answer.setHeaderName(jsonPathAnnotation.headerName());
+                headerName = jsonPathAnnotation.headerName();
             }
             if (ObjectHelper.isNotEmpty(jsonPathAnnotation.propertyName())) {
-                answer.setPropertyName(jsonPathAnnotation.propertyName());
+                propertyName = jsonPathAnnotation.propertyName();
             }
+            if (variableName != null || headerName != null || propertyName != 
null) {
+                
answer.setSource(ExpressionBuilder.singleInputExpression(variableName, 
headerName, propertyName));
+            }
+
             Option[] options = jsonPathAnnotation.options();
             answer.setOptions(options);
         }
diff --git 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
index 13739a2d621..afbdc83b699 100644
--- 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
+++ 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathEngine.java
@@ -56,24 +56,22 @@ public class JsonPathEngine {
     private static final Pattern SIMPLE_PATTERN = 
Pattern.compile("\\$\\{[^\\}]+\\}", Pattern.MULTILINE);
     private final String expression;
     private final boolean writeAsString;
-    private final String headerName;
-    private final String propertyName;
     private final Configuration configuration;
     private final boolean hasSimple;
+    private final Expression source;
     private JsonPathAdapter adapter;
     private volatile boolean initJsonAdapter;
 
     @Deprecated
     public JsonPathEngine(String expression) {
-        this(expression, false, false, true, null, null, null, null);
+        this(expression, null, false, false, true, null, null);
     }
 
-    public JsonPathEngine(String expression, boolean writeAsString, boolean 
suppressExceptions, boolean allowSimple,
-                          String headerName, String propertyName, Option[] 
options, CamelContext context) {
+    public JsonPathEngine(String expression, Expression source, boolean 
writeAsString, boolean suppressExceptions,
+                          boolean allowSimple, Option[] options, CamelContext 
context) {
         this.expression = expression;
+        this.source = source;
         this.writeAsString = writeAsString;
-        this.headerName = headerName;
-        this.propertyName = propertyName;
 
         Configuration.ConfigurationBuilder builder = Configuration.builder();
         if (options != null) {
@@ -174,18 +172,7 @@ public class JsonPathEngine {
     }
 
     private Object getPayload(Exchange exchange) {
-        Object payload = null;
-        if (headerName == null && propertyName == null) {
-            payload = exchange.getIn().getBody();
-        } else {
-            if (headerName != null) {
-                payload = exchange.getIn().getHeader(headerName);
-            }
-            if (payload == null && propertyName != null) {
-                payload = exchange.getProperty(propertyName);
-            }
-        }
-        return payload;
+        return source != null ? source.evaluate(exchange, Object.class) : 
exchange.getMessage().getBody();
     }
 
     private Object doRead(String path, Exchange exchange) throws IOException, 
CamelExchangeException {
@@ -239,15 +226,15 @@ public class JsonPathEngine {
         }
 
         // okay it was not then lets throw a failure
-        if (headerName != null) {
-            throw new CamelExchangeException("Cannot read message header " + 
headerName + " as supported JSON value", exchange);
+        if (source != null) {
+            throw new CamelExchangeException("Cannot read " + source + " as 
supported JSON value", exchange);
         } else {
             throw new CamelExchangeException("Cannot read message body as 
supported JSON value", exchange);
         }
     }
 
     private Object readWithInputStream(String path, Exchange exchange) throws 
IOException {
-        Object json = headerName != null ? 
exchange.getIn().getHeader(headerName) : exchange.getIn().getBody();
+        Object json = getPayload(exchange);
         LOG.trace("JSonPath: {} is read as InputStream: {}", path, json);
 
         InputStream is = 
exchange.getContext().getTypeConverter().tryConvertTo(InputStream.class, 
exchange, json);
@@ -273,7 +260,7 @@ public class JsonPathEngine {
     }
 
     private Object readWithAdapter(String path, Exchange exchange) {
-        Object json = headerName != null ? 
exchange.getIn().getHeader(headerName) : exchange.getIn().getBody();
+        Object json = getPayload(exchange);
         LOG.trace("JSonPath: {} is read with adapter: {}", path, json);
 
         doInitAdapter(exchange);
diff --git 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
index f0c27d7cd4a..e6bbfd0a473 100644
--- 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
+++ 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathExpression.java
@@ -22,6 +22,7 @@ import java.util.List;
 import com.jayway.jsonpath.Option;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
 import org.apache.camel.ExpressionEvaluationException;
 import org.apache.camel.ExpressionIllegalSyntaxException;
 import org.apache.camel.jsonpath.easypredicate.EasyPredicateParser;
@@ -43,9 +44,7 @@ public class JsonPathExpression extends ExpressionAdapter {
     private boolean allowEasyPredicate = true;
     private boolean writeAsString;
     private boolean unpackArray;
-    private String variableName;
-    private String headerName;
-    private String propertyName;
+    private Expression source;
     private Option[] options;
 
     public JsonPathExpression(String expression) {
@@ -130,39 +129,12 @@ public class JsonPathExpression extends ExpressionAdapter 
{
         this.unpackArray = unpackArray;
     }
 
-    public String getVariableName() {
-        return variableName;
+    public Expression getSource() {
+        return source;
     }
 
-    /**
-     * Name of variable to use as input, instead of the message body
-     */
-    public void setVariableName(String variableName) {
-        this.variableName = variableName;
-    }
-
-    public String getHeaderName() {
-        return headerName;
-    }
-
-    /**
-     * Name of header to use as input, instead of the message body
-     */
-    public void setHeaderName(String headerName) {
-        this.headerName = headerName;
-    }
-
-    public String getPropertyName() {
-        return propertyName;
-    }
-
-    /**
-     * Name of property to use as input, instead of the message body.
-     * <p>
-     * It has a lower precedent than the name of header if both are set.
-     */
-    public void setPropertyName(String propertyName) {
-        this.propertyName = propertyName;
+    public void setSource(Expression source) {
+        this.source = source;
     }
 
     public Option[] getOptions() {
@@ -217,7 +189,7 @@ public class JsonPathExpression extends ExpressionAdapter {
         LOG.debug("Initializing {} using: {}", predicate ? "predicate" : 
"expression", exp);
         try {
             engine = new JsonPathEngine(
-                    exp, writeAsString, suppressExceptions, allowSimple, 
headerName, propertyName, options, context);
+                    exp, source, writeAsString, suppressExceptions, 
allowSimple, options, context);
         } catch (Exception e) {
             throw new ExpressionIllegalSyntaxException(exp, e);
         }
diff --git 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
index 5819b8f8485..c370359cb3a 100644
--- 
a/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
+++ 
b/components/camel-jsonpath/src/main/java/org/apache/camel/jsonpath/JsonPathLanguage.java
@@ -27,7 +27,7 @@ import org.apache.camel.Predicate;
 import org.apache.camel.jsonpath.easypredicate.EasyPredicateParser;
 import org.apache.camel.spi.PropertyConfigurer;
 import org.apache.camel.spi.annotations.Language;
-import org.apache.camel.support.ExpressionToPredicateAdapter;
+import org.apache.camel.support.ExpressionAdapter;
 import org.apache.camel.support.SingleInputTypedLanguageSupport;
 import org.apache.camel.support.component.PropertyConfigurerSupport;
 
@@ -90,36 +90,27 @@ public class JsonPathLanguage extends 
SingleInputTypedLanguageSupport implements
     }
 
     @Override
-    public Predicate createPredicate(String expression) {
-        return 
ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
+    public Predicate createPredicate(Expression source, String expression, 
Object[] properties) {
+        return doCreateJsonPathExpression(source, expression, properties, 
true);
     }
 
     @Override
-    public Expression createExpression(String expression) {
-        return createExpression(expression, null);
+    public Expression createExpression(Expression source, String expression, 
Object[] properties) {
+        return doCreateJsonPathExpression(source, expression, properties, 
false);
     }
 
-    @Override
-    public Predicate createPredicate(String expression, Object[] properties) {
-        return 
ExpressionToPredicateAdapter.toPredicate(doCreateJsonPathExpression(expression, 
properties, true));
-    }
-
-    @Override
-    public Expression createExpression(String expression, Object[] properties) 
{
-        return doCreateJsonPathExpression(expression, properties, false);
-    }
-
-    protected Expression doCreateJsonPathExpression(String expression, 
Object[] properties, boolean predicate) {
+    protected ExpressionAdapter doCreateJsonPathExpression(
+            Expression source, String expression, Object[] properties, boolean 
predicate) {
         JsonPathExpression answer = new JsonPathExpression(expression);
+        answer.setSource(source);
         answer.setPredicate(predicate);
         answer.setResultType(property(Class.class, properties, 0, 
getResultType()));
-        answer.setSuppressExceptions(property(boolean.class, properties, 1, 
isSuppressExceptions()));
-        answer.setAllowSimple(property(boolean.class, properties, 2, 
isAllowSimple()));
-        answer.setAllowEasyPredicate(property(boolean.class, properties, 3, 
isAllowEasyPredicate()));
-        answer.setWriteAsString(property(boolean.class, properties, 4, 
isWriteAsString()));
-        answer.setUnpackArray(property(boolean.class, properties, 5, 
isUnpackArray()));
-        answer.setHeaderName(property(String.class, properties, 6, 
getHeaderName()));
-        Object option = property(Object.class, properties, 7, null);
+        answer.setSuppressExceptions(property(boolean.class, properties, 4, 
isSuppressExceptions()));
+        answer.setAllowSimple(property(boolean.class, properties, 5, 
isAllowSimple()));
+        answer.setAllowEasyPredicate(property(boolean.class, properties, 6, 
isAllowEasyPredicate()));
+        answer.setWriteAsString(property(boolean.class, properties, 7, 
isWriteAsString()));
+        answer.setUnpackArray(property(boolean.class, properties, 8, 
isUnpackArray()));
+        Object option = property(Object.class, properties, 9, null);
         if (option != null) {
             List<Option> list = new ArrayList<>();
             if (option instanceof String str) {
@@ -133,8 +124,6 @@ public class JsonPathLanguage extends 
SingleInputTypedLanguageSupport implements
         } else if (options != null) {
             answer.setOptions(options);
         }
-        answer.setPropertyName(property(String.class, properties, 8, 
getPropertyName()));
-        answer.setVariableName(property(String.class, properties, 9, 
getVariableName()));
         if (getCamelContext() != null) {
             answer.init(getCamelContext());
         }
@@ -178,14 +167,6 @@ public class JsonPathLanguage extends 
SingleInputTypedLanguageSupport implements
             case "allowEasyPredicate":
                 
setAllowEasyPredicate(PropertyConfigurerSupport.property(camelContext, 
boolean.class, value));
                 return true;
-            case "headername":
-            case "headerName":
-                setHeaderName(PropertyConfigurerSupport.property(camelContext, 
String.class, value));
-                return true;
-            case "propertyname":
-            case "propertyName":
-                
setPropertyName(PropertyConfigurerSupport.property(camelContext, String.class, 
value));
-                return true;
             case "writeasstring":
             case "writeAsString":
                 
setWriteAsString(PropertyConfigurerSupport.property(camelContext, 
boolean.class, value));
diff --git 
a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathLanguageTest.java
 
b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathLanguageTest.java
index 7ae9fea32d0..16c4665abf1 100644
--- 
a/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathLanguageTest.java
+++ 
b/components/camel-jsonpath/src/test/java/org/apache/camel/jsonpath/JsonPathLanguageTest.java
@@ -131,7 +131,7 @@ public class JsonPathLanguageTest extends CamelTestSupport {
         JsonPathLanguage lan = (JsonPathLanguage) 
context.resolveLanguage("jsonpath");
 
         Expression exp = lan.createExpression("$.foo",
-                new Object[] { null, null, null, null, null, null, null, 
Option.SUPPRESS_EXCEPTIONS });
+                new Object[] { null, null, null, null, null, null, null, null, 
null, Option.SUPPRESS_EXCEPTIONS });
         String nofoo = exp.evaluate(exchange, String.class);
 
         assertNull(nofoo);
@@ -144,9 +144,9 @@ public class JsonPathLanguageTest extends CamelTestSupport {
 
         JsonPathLanguage language = (JsonPathLanguage) 
context.resolveLanguage("jsonpath");
 
-        JsonPathExpression expression = (JsonPathExpression) 
language.createExpression("$.store.book",
-                new Object[] { String.class, null, null, null, null, true });
-        String json = (String) expression.evaluate(exchange);
+        Expression expression = language.createExpression("$.store.book",
+                new Object[] { String.class, null, null, null, null, null, 
null, null, true });
+        String json = expression.evaluate(exchange, String.class);
 
         // check that a single json object is returned, not an array
         assertTrue(json.startsWith("{") && json.endsWith("}"));
@@ -159,9 +159,9 @@ public class JsonPathLanguageTest extends CamelTestSupport {
 
         JsonPathLanguage language = (JsonPathLanguage) 
context.resolveLanguage("jsonpath");
 
-        JsonPathExpression expression = (JsonPathExpression) 
language.createExpression("$.store.book",
-                new Object[] { String.class, null, null, null, false });
-        String json = (String) expression.evaluate(exchange);
+        Expression expression = language.createExpression("$.store.book",
+                new Object[] { String.class, null, null, null, null, null, 
false });
+        String json = expression.evaluate(exchange, String.class);
 
         // check that an array is returned, not a single object
         assertTrue(json.startsWith("[") && json.endsWith("]"));
diff --git 
a/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointConfigurer.java
 
b/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointConfigurer.java
index 4280bb380d8..0dfe66d086a 100644
--- 
a/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointConfigurer.java
+++ 
b/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointConfigurer.java
@@ -81,6 +81,8 @@ public class XQueryEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "timeUnit": target.setTimeUnit(property(camelContext, 
java.util.concurrent.TimeUnit.class, value)); return true;
         case "usefixeddelay":
         case "useFixedDelay": target.setUseFixedDelay(property(camelContext, 
boolean.class, value)); return true;
+        case "variablename":
+        case "variableName": target.setVariableName(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
     }
@@ -148,6 +150,8 @@ public class XQueryEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "timeUnit": return java.util.concurrent.TimeUnit.class;
         case "usefixeddelay":
         case "useFixedDelay": return boolean.class;
+        case "variablename":
+        case "variableName": return java.lang.String.class;
         default: return null;
         }
     }
@@ -216,6 +220,8 @@ public class XQueryEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "timeUnit": return target.getTimeUnit();
         case "usefixeddelay":
         case "useFixedDelay": return target.isUseFixedDelay();
+        case "variablename":
+        case "variableName": return target.getVariableName();
         default: return null;
         }
     }
diff --git 
a/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointUriFactory.java
 
b/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointUriFactory.java
index 38a3973ed41..88348ef2a12 100644
--- 
a/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointUriFactory.java
+++ 
b/components/camel-saxon/src/generated/java/org/apache/camel/component/xquery/XQueryEndpointUriFactory.java
@@ -21,7 +21,7 @@ public class XQueryEndpointUriFactory extends 
org.apache.camel.support.component
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Set<String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(34);
+        Set<String> props = new HashSet<>(35);
         props.add("allowStAX");
         props.add("backoffErrorThreshold");
         props.add("backoffIdleThreshold");
@@ -56,6 +56,7 @@ public class XQueryEndpointUriFactory extends 
org.apache.camel.support.component
         props.add("stripsAllWhiteSpace");
         props.add("timeUnit");
         props.add("useFixedDelay");
+        props.add("variableName");
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
         SECRET_PROPERTY_NAMES = Collections.emptySet();
         Set<String> prefixes = new HashSet<>(1);
diff --git 
a/components/camel-saxon/src/generated/resources/org/apache/camel/component/xquery/xquery.json
 
b/components/camel-saxon/src/generated/resources/org/apache/camel/component/xquery/xquery.json
index 7f8340f892a..5df5016f9a4 100644
--- 
a/components/camel-saxon/src/generated/resources/org/apache/camel/component/xquery/xquery.json
+++ 
b/components/camel-saxon/src/generated/resources/org/apache/camel/component/xquery/xquery.json
@@ -35,35 +35,36 @@
     "allowStAX": { "index": 1, "kind": "parameter", "displayName": "Allow St 
AX", "group": "common", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "description": "Whether to allow using StAX mode" 
},
     "headerName": { "index": 2, "kind": "parameter", "displayName": "Header 
Name", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "description": "To use a Camel Message header as the input 
source instead of Message body." },
     "namespacePrefixes": { "index": 3, "kind": "parameter", "displayName": 
"Namespace Prefixes", "group": "common", "label": "", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.String>", "deprecated": false, "autowired": false, "secret": false, 
"description": "Allows to control which namespace prefixes to use for a set of 
namespace mappings" },
-    "propertyName": { "index": 4, "kind": "parameter", "displayName": 
"Property Name", "group": "common", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a Camel Exchange property as the 
input source instead of Message body. It has a lower precedent than the name of 
header if both are set." },
+    "propertyName": { "index": 4, "kind": "parameter", "displayName": 
"Property Name", "group": "common", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a Camel Exchange property as the 
input source instead of Message body." },
     "resultsFormat": { "index": 5, "kind": "parameter", "displayName": 
"Results Format", "group": "common", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.camel.component.xquery.ResultFormat", "enum": 
[ "Bytes", "BytesSource", "DOM", "DOMSource", "List", "String", "StringSource" 
], "deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"DOM", "description": "What output result to use" },
     "resultType": { "index": 6, "kind": "parameter", "displayName": "Result 
Type", "group": "common", "label": "", "required": false, "type": "string", 
"javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, 
"autowired": false, "secret": false, "description": "What output result to use 
defined as a class" },
     "stripsAllWhiteSpace": { "index": 7, "kind": "parameter", "displayName": 
"Strips All White Space", "group": "common", "label": "", "required": false, 
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": true, "description": "Whether to strip 
all whitespaces" },
-    "sendEmptyMessageWhenIdle": { "index": 8, "kind": "parameter", 
"displayName": "Send Empty Message When Idle", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If the polling consumer did not poll any files, you can 
enable this option to send an empty message (no body) instead." },
-    "bridgeErrorHandler": { "index": 9, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming  [...]
-    "exceptionHandler": { "index": 10, "kind": "parameter", "displayName": 
"Exception Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By de [...]
-    "exchangePattern": { "index": 11, "kind": "parameter", "displayName": 
"Exchange Pattern", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the exchange pattern when the consumer creates an exchange." },
-    "pollStrategy": { "index": 12, "kind": "parameter", "displayName": "Poll 
Strategy", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.PollingConsumerPollStrategy", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your 
custom implementation to control error handling usually occurred during the po 
[...]
-    "lazyStartProducer": { "index": 13, "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 produ [...]
-    "configuration": { "index": 14, "kind": "parameter", "displayName": 
"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" },
-    "configurationProperties": { "index": 15, "kind": "parameter", 
"displayName": "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" },
-    "moduleURIResolver": { "index": 16, "kind": "parameter", "displayName": 
"Module URIResolver", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "net.sf.saxon.lib.ModuleURIResolver", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use the custom ModuleURIResolver" },
-    "parameters": { "index": 17, "kind": "parameter", "displayName": 
"Parameters", "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": "Additional parameters" },
-    "properties": { "index": 18, "kind": "parameter", "displayName": 
"Properties", "group": "advanced", "label": "advanced", "required": false, 
"type": "object", "javaType": "java.util.Properties", "deprecated": false, 
"autowired": false, "secret": false, "description": "Properties to configure 
the serialization parameters" },
-    "staticQueryContext": { "index": 19, "kind": "parameter", "displayName": 
"Static Query Context", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "net.sf.saxon.query.StaticQueryContext", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use a custom Saxon StaticQueryContext" },
-    "backoffErrorThreshold": { "index": 20, "kind": "parameter", 
"displayName": "Backoff Error Threshold", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
number of subsequent error polls (failed due some error) that should happen 
before the backoffMultipler should kick-in." },
-    "backoffIdleThreshold": { "index": 21, "kind": "parameter", "displayName": 
"Backoff Idle Threshold", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "The number of subsequent 
idle polls that should happen before the backoffMultipler should kick-in." },
-    "backoffMultiplier": { "index": 22, "kind": "parameter", "displayName": 
"Backoff Multiplier", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "To let the scheduled 
polling consumer backoff if there has been a number of subsequent idles\/errors 
in a row. The multiplier is then the number of polls that will be skipped 
before the next actual attempt is h [...]
-    "delay": { "index": 23, "kind": "parameter", "displayName": "Delay", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 500, "description": "Milliseconds before the 
next poll." },
-    "greedy": { "index": 24, "kind": "parameter", "displayName": "Greedy", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If greedy is enabled, 
then the ScheduledPollConsumer will run immediately again, if the previous run 
polled 1 or more messages." },
-    "initialDelay": { "index": 25, "kind": "parameter", "displayName": 
"Initial Delay", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": 1000, "description": 
"Milliseconds before the first poll starts." },
-    "repeatCount": { "index": 26, "kind": "parameter", "displayName": "Repeat 
Count", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 0, "description": "Specifies a maximum limit 
of number of fires. So if you set it to 1, the scheduler will only fire once. 
If you set it to 5, it will only fire five times. A value of zero or negative 
means fire forever." },
-    "runLoggingLevel": { "index": 27, "kind": "parameter", "displayName": "Run 
Logging Level", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.LoggingLevel", "enum": [ "TRACE", "DEBUG", "INFO", "WARN", 
"ERROR", "OFF" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "TRACE", "description": "The consumer logs a start\/complete 
log line when it polls. This option allows you to configure the l [...]
-    "scheduledExecutorService": { "index": 28, "kind": "parameter", 
"displayName": "Scheduled Executor Service", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "object", "javaType": 
"java.util.concurrent.ScheduledExecutorService", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows for configuring a 
custom\/shared thread pool to use for the consumer. By default each consumer 
has its own single threaded thread pool." },
-    "scheduler": { "index": 29, "kind": "parameter", "displayName": 
"Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "object", "javaType": "java.lang.Object", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "none", "description": "To 
use a cron scheduler from either camel-spring or camel-quartz component. Use 
value spring or quartz for built in scheduler" },
-    "schedulerProperties": { "index": 30, "kind": "parameter", "displayName": 
"Scheduler Properties", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"java.util.Map<java.lang.String, java.lang.Object>", "prefix": "scheduler.", 
"multiValue": true, "deprecated": false, "autowired": false, "secret": false, 
"description": "To configure additional properties when using a custom 
scheduler or any of the Quartz, Spring based scheduler." },
-    "startScheduler": { "index": 31, "kind": "parameter", "displayName": 
"Start Scheduler", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Whether the scheduler should be auto started." },
-    "timeUnit": { "index": 32, "kind": "parameter", "displayName": "Time 
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "object", "javaType": "java.util.concurrent.TimeUnit", "enum": [ 
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", 
"DAYS" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and 
delay options." },
-    "useFixedDelay": { "index": 33, "kind": "parameter", "displayName": "Use 
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in 
JDK for details." }
+    "variableName": { "index": 8, "kind": "parameter", "displayName": 
"Variable Name", "group": "common", "label": "", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "description": "To use a variable as the input source 
instead of Message body." },
+    "sendEmptyMessageWhenIdle": { "index": 9, "kind": "parameter", 
"displayName": "Send Empty Message When Idle", "group": "consumer", "label": 
"consumer", "required": false, "type": "boolean", "javaType": "boolean", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
false, "description": "If the polling consumer did not poll any files, you can 
enable this option to send an empty message (no body) instead." },
+    "bridgeErrorHandler": { "index": 10, "kind": "parameter", "displayName": 
"Bridge Error Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions (if possible) occurred 
while the Camel consumer is trying to pickup incoming [...]
+    "exceptionHandler": { "index": 11, "kind": "parameter", "displayName": 
"Exception Handler", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By de [...]
+    "exchangePattern": { "index": 12, "kind": "parameter", "displayName": 
"Exchange Pattern", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut" ], 
"deprecated": false, "autowired": false, "secret": false, "description": "Sets 
the exchange pattern when the consumer creates an exchange." },
+    "pollStrategy": { "index": 13, "kind": "parameter", "displayName": "Poll 
Strategy", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.PollingConsumerPollStrategy", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your 
custom implementation to control error handling usually occurred during the po 
[...]
+    "lazyStartProducer": { "index": 14, "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 produ [...]
+    "configuration": { "index": 15, "kind": "parameter", "displayName": 
"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" },
+    "configurationProperties": { "index": 16, "kind": "parameter", 
"displayName": "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" },
+    "moduleURIResolver": { "index": 17, "kind": "parameter", "displayName": 
"Module URIResolver", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "net.sf.saxon.lib.ModuleURIResolver", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use the custom ModuleURIResolver" },
+    "parameters": { "index": 18, "kind": "parameter", "displayName": 
"Parameters", "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": "Additional parameters" },
+    "properties": { "index": 19, "kind": "parameter", "displayName": 
"Properties", "group": "advanced", "label": "advanced", "required": false, 
"type": "object", "javaType": "java.util.Properties", "deprecated": false, 
"autowired": false, "secret": false, "description": "Properties to configure 
the serialization parameters" },
+    "staticQueryContext": { "index": 20, "kind": "parameter", "displayName": 
"Static Query Context", "group": "advanced", "label": "advanced", "required": 
false, "type": "object", "javaType": "net.sf.saxon.query.StaticQueryContext", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use a custom Saxon StaticQueryContext" },
+    "backoffErrorThreshold": { "index": 21, "kind": "parameter", 
"displayName": "Backoff Error Threshold", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
number of subsequent error polls (failed due some error) that should happen 
before the backoffMultipler should kick-in." },
+    "backoffIdleThreshold": { "index": 22, "kind": "parameter", "displayName": 
"Backoff Idle Threshold", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "The number of subsequent 
idle polls that should happen before the backoffMultipler should kick-in." },
+    "backoffMultiplier": { "index": 23, "kind": "parameter", "displayName": 
"Backoff Multiplier", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "To let the scheduled 
polling consumer backoff if there has been a number of subsequent idles\/errors 
in a row. The multiplier is then the number of polls that will be skipped 
before the next actual attempt is h [...]
+    "delay": { "index": 24, "kind": "parameter", "displayName": "Delay", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 500, "description": "Milliseconds before the 
next poll." },
+    "greedy": { "index": 25, "kind": "parameter", "displayName": "Greedy", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If greedy is enabled, 
then the ScheduledPollConsumer will run immediately again, if the previous run 
polled 1 or more messages." },
+    "initialDelay": { "index": 26, "kind": "parameter", "displayName": 
"Initial Delay", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": 1000, "description": 
"Milliseconds before the first poll starts." },
+    "repeatCount": { "index": 27, "kind": "parameter", "displayName": "Repeat 
Count", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 0, "description": "Specifies a maximum limit 
of number of fires. So if you set it to 1, the scheduler will only fire once. 
If you set it to 5, it will only fire five times. A value of zero or negative 
means fire forever." },
+    "runLoggingLevel": { "index": 28, "kind": "parameter", "displayName": "Run 
Logging Level", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.LoggingLevel", "enum": [ "TRACE", "DEBUG", "INFO", "WARN", 
"ERROR", "OFF" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "TRACE", "description": "The consumer logs a start\/complete 
log line when it polls. This option allows you to configure the l [...]
+    "scheduledExecutorService": { "index": 29, "kind": "parameter", 
"displayName": "Scheduled Executor Service", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "object", "javaType": 
"java.util.concurrent.ScheduledExecutorService", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows for configuring a 
custom\/shared thread pool to use for the consumer. By default each consumer 
has its own single threaded thread pool." },
+    "scheduler": { "index": 30, "kind": "parameter", "displayName": 
"Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "object", "javaType": "java.lang.Object", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "none", "description": "To 
use a cron scheduler from either camel-spring or camel-quartz component. Use 
value spring or quartz for built in scheduler" },
+    "schedulerProperties": { "index": 31, "kind": "parameter", "displayName": 
"Scheduler Properties", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"java.util.Map<java.lang.String, java.lang.Object>", "prefix": "scheduler.", 
"multiValue": true, "deprecated": false, "autowired": false, "secret": false, 
"description": "To configure additional properties when using a custom 
scheduler or any of the Quartz, Spring based scheduler." },
+    "startScheduler": { "index": 32, "kind": "parameter", "displayName": 
"Start Scheduler", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Whether the scheduler should be auto started." },
+    "timeUnit": { "index": 33, "kind": "parameter", "displayName": "Time 
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "object", "javaType": "java.util.concurrent.TimeUnit", "enum": [ 
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", 
"DAYS" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and 
delay options." },
+    "useFixedDelay": { "index": 34, "kind": "parameter", "displayName": "Use 
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in 
JDK for details." }
   }
 }
diff --git 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQuery.java
 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQuery.java
index 6d160dd7298..43631161df5 100644
--- 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQuery.java
+++ 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQuery.java
@@ -49,14 +49,17 @@ public @interface XQuery {
     Class<?> resultType() default Object.class;
 
     /**
-     * @return The name of the header we want to apply the XQuery expression 
to. If this is empty then the Xquery
-     *         expression will be applied to the value of the exchange 
property or the body instead.
+     * The name of the variable we want to apply the expression to.
+     */
+    String variableName() default "";
+
+    /**
+     * The name of the header we want to apply the expression to.
      */
     String headerName() default "";
 
     /**
-     * @return The name of the property we want to apply the XQuery expression 
to. If this is empty then the Xquery
-     *         expression will be applied to the body instead.
+     * The name of the exchange property we want to apply the expression to.
      */
     String propertyName() default "";
 }
diff --git 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryAnnotationExpressionFactory.java
 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryAnnotationExpressionFactory.java
index 12cbd2be1dd..cfe3156ce37 100644
--- 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryAnnotationExpressionFactory.java
+++ 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryAnnotationExpressionFactory.java
@@ -23,6 +23,7 @@ import org.w3c.dom.Node;
 import net.sf.saxon.functions.CollectionFn;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
+import org.apache.camel.support.builder.ExpressionBuilder;
 import org.apache.camel.support.language.DefaultAnnotationExpressionFactory;
 import org.apache.camel.support.language.LanguageAnnotation;
 import org.apache.camel.support.language.NamespacePrefix;
@@ -39,12 +40,23 @@ public class XQueryAnnotationExpressionFactory extends 
DefaultAnnotationExpressi
         if (annotation instanceof XQuery) {
             XQuery xQueryAnnotation = (XQuery) annotation;
             
builder.setStripsAllWhiteSpace(xQueryAnnotation.stripsAllWhiteSpace());
+
+            String variableName = null;
+            String headerName = null;
+            String propertyName = null;
+            if (ObjectHelper.isNotEmpty(xQueryAnnotation.variableName())) {
+                variableName = xQueryAnnotation.variableName();
+            }
             if (ObjectHelper.isNotEmpty(xQueryAnnotation.headerName())) {
-                builder.setHeaderName(xQueryAnnotation.headerName());
+                headerName = xQueryAnnotation.headerName();
             }
             if (ObjectHelper.isNotEmpty(xQueryAnnotation.propertyName())) {
-                builder.setPropertyName(xQueryAnnotation.propertyName());
+                propertyName = xQueryAnnotation.propertyName();
             }
+            if (variableName != null || headerName != null || propertyName != 
null) {
+                
builder.setSource(ExpressionBuilder.singleInputExpression(variableName, 
headerName, propertyName));
+            }
+
             NamespacePrefix[] namespaces = xQueryAnnotation.namespaces();
             if (namespaces != null) {
                 for (NamespacePrefix namespacePrefix : namespaces) {
diff --git 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
index f4d2af3bcfa..ce7acd33e60 100644
--- 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
+++ 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
@@ -65,7 +65,6 @@ import net.sf.saxon.value.StringValue;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
-import org.apache.camel.Message;
 import org.apache.camel.NoTypeConversionAvailableException;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
@@ -100,9 +99,7 @@ public abstract class XQueryBuilder implements Expression, 
Predicate, NamespaceA
     private boolean stripsAllWhiteSpace = true;
     private ModuleURIResolver moduleURIResolver;
     private boolean allowStAX;
-    private String headerName;
-    private String propertyName;
-    private String variableName;
+    private Expression source;
 
     @Override
     public String toString() {
@@ -518,41 +515,6 @@ public abstract class XQueryBuilder implements Expression, 
Predicate, NamespaceA
         this.stripsAllWhiteSpace = stripsAllWhiteSpace;
     }
 
-    public String getHeaderName() {
-        return headerName;
-    }
-
-    /**
-     * Name of header to use as input, instead of the message body
-     */
-    public void setHeaderName(String headerName) {
-        this.headerName = headerName;
-    }
-
-    public String getPropertyName() {
-        return propertyName;
-    }
-
-    /**
-     * Name of property to use as input, instead of the message body.
-     * <p>
-     * It has a lower precedent than the name of header if both are set.
-     */
-    public void setPropertyName(String propertyName) {
-        this.propertyName = propertyName;
-    }
-
-    public String getVariableName() {
-        return variableName;
-    }
-
-    /**
-     * Name of variable to use as input, instead of the message body
-     */
-    public void setVariableName(String variableName) {
-        this.variableName = variableName;
-    }
-
     public boolean isAllowStAX() {
         return allowStAX;
     }
@@ -561,6 +523,14 @@ public abstract class XQueryBuilder implements Expression, 
Predicate, NamespaceA
         this.allowStAX = allowStAX;
     }
 
+    public Expression getSource() {
+        return source;
+    }
+
+    public void setSource(Expression source) {
+        this.source = source;
+    }
+
     // Implementation methods
     // 
-------------------------------------------------------------------------
 
@@ -577,56 +547,26 @@ public abstract class XQueryBuilder implements 
Expression, Predicate, NamespaceA
         Configuration config = getConfiguration();
         DynamicQueryContext dynamicQueryContext = new 
DynamicQueryContext(config);
 
-        Message in = exchange.getIn();
-        Item item;
-        if (ObjectHelper.isNotEmpty(getHeaderName())) {
-            item = in.getHeader(getHeaderName(), Item.class);
-        } else if (ObjectHelper.isNotEmpty(getPropertyName())) {
-            item = exchange.getProperty(getPropertyName(), Item.class);
-        } else if (ObjectHelper.isNotEmpty(getVariableName())) {
-            item = exchange.getVariable(getVariableName(), Item.class);
-        } else {
-            item = in.getBody(Item.class);
-        }
+        Object payload = source != null ? source.evaluate(exchange, 
Object.class) : exchange.getMessage().getBody();
+        Item item = 
exchange.getContext().getTypeConverter().tryConvertTo(Item.class, exchange, 
payload);
         if (item != null) {
             dynamicQueryContext.setContextItem(item);
         } else {
-            Object body;
-            if (ObjectHelper.isNotEmpty(getHeaderName())) {
-                body = in.getHeader(getHeaderName());
-            } else if (ObjectHelper.isNotEmpty(getPropertyName())) {
-                body = exchange.getProperty(getPropertyName());
-            } else if (ObjectHelper.isNotEmpty(getVariableName())) {
-                body = exchange.getVariable(getVariableName());
-            } else {
-                body = in.getBody();
-            }
-
             // the underlying input stream, which we need to close to avoid 
locking files or other resources
             InputStream is = null;
             try {
                 Source source;
                 // only convert to input stream if really needed
-                if (isInputStreamNeeded(exchange)) {
-                    if (ObjectHelper.isNotEmpty(getHeaderName())) {
-                        is = exchange.getIn().getHeader(getHeaderName(), 
InputStream.class);
-                    } else if (ObjectHelper.isNotEmpty(getPropertyName())) {
-                        is = exchange.getProperty(getPropertyName(), 
InputStream.class);
-                    } else if (ObjectHelper.isNotEmpty(getVariableName())) {
-                        is = exchange.getVariable(getVariableName(), 
InputStream.class);
-                    } else {
-                        is = exchange.getIn().getBody(InputStream.class);
-                    }
+                if (isInputStreamNeeded(payload)) {
+                    is = 
exchange.getContext().getTypeConverter().convertTo(InputStream.class, exchange, 
payload);
                     source = getSource(exchange, is);
                 } else {
-                    source = getSource(exchange, body);
+                    source = getSource(exchange, payload);
                 }
-
                 if (source == null) {
                     // indicate it was not possible to convert to a Source type
-                    throw new NoTypeConversionAvailableException(body, 
Source.class);
+                    throw new NoTypeConversionAvailableException(payload, 
Source.class);
                 }
-
                 TreeInfo doc = config.buildDocumentTree(source);
                 dynamicQueryContext.setContextItem(doc.getRootNode());
             } finally {
@@ -646,23 +586,20 @@ public abstract class XQueryBuilder implements 
Expression, Predicate, NamespaceA
      * <p/>
      * Depending on the content in the message body, we may not need to 
convert to {@link InputStream}.
      *
-     * @param  exchange the current exchange
-     * @return          <tt>true</tt> to convert to {@link InputStream} 
beforehand converting to {@link Source}
-     *                  afterwards.
+     * @return <tt>true</tt> to convert to {@link InputStream} beforehand 
converting to {@link Source} afterwards.
      */
-    protected boolean isInputStreamNeeded(Exchange exchange) {
-        Object body = exchange.getIn().getBody();
-        if (body == null) {
+    protected boolean isInputStreamNeeded(Object payload) {
+        if (payload == null) {
             return false;
         }
 
-        if (body instanceof Source) {
+        if (payload instanceof Source) {
             return false;
-        } else if (body instanceof String) {
+        } else if (payload instanceof String) {
             return false;
-        } else if (body instanceof byte[]) {
+        } else if (payload instanceof byte[]) {
             return false;
-        } else if (body instanceof Node) {
+        } else if (payload instanceof Node) {
             return false;
         }
 
diff --git 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
index 90c18106b1b..fb5daf6edbd 100644
--- 
a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
+++ 
b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryEndpoint.java
@@ -32,6 +32,7 @@ import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.support.ProcessorEndpoint;
 import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.support.builder.ExpressionBuilder;
 import org.apache.camel.support.service.ServiceHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -73,6 +74,8 @@ public class XQueryEndpoint extends ProcessorEndpoint {
     @UriParam
     private boolean allowStAX;
     @UriParam
+    private String variableName;
+    @UriParam
     private String headerName;
     @UriParam
     private String propertyName;
@@ -213,6 +216,17 @@ public class XQueryEndpoint extends ProcessorEndpoint {
         this.allowStAX = allowStAX;
     }
 
+    public String getVariableName() {
+        return variableName;
+    }
+
+    /**
+     * To use a variable as the input source instead of Message body.
+     */
+    public void setVariableName(String variableName) {
+        this.variableName = variableName;
+    }
+
     public String getHeaderName() {
         return headerName;
     }
@@ -230,8 +244,6 @@ public class XQueryEndpoint extends ProcessorEndpoint {
 
     /**
      * To use a Camel Exchange property as the input source instead of Message 
body.
-     * <p>
-     * It has a lower precedent than the name of header if both are set.
      */
     public void setPropertyName(String propertyName) {
         this.propertyName = propertyName;
@@ -269,9 +281,8 @@ public class XQueryEndpoint extends ProcessorEndpoint {
         this.xquery.setResultType(getResultType());
         this.xquery.setStripsAllWhiteSpace(isStripsAllWhiteSpace());
         this.xquery.setAllowStAX(isAllowStAX());
-        this.xquery.setHeaderName(getHeaderName());
-        this.xquery.setPropertyName(getPropertyName());
         this.xquery.setModuleURIResolver(getModuleURIResolver());
+        
this.xquery.setSource(ExpressionBuilder.singleInputExpression(getVariableName(),
 getHeaderName(), getPropertyName()));
         this.xquery.init(getCamelContext());
 
         setProcessor(xquery);
diff --git 
a/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
 
b/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
index 219b29111fc..6fd03362817 100644
--- 
a/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
+++ 
b/components/camel-saxon/src/main/java/org/apache/camel/language/xquery/XQueryLanguage.java
@@ -19,7 +19,6 @@ package org.apache.camel.language.xquery;
 import net.sf.saxon.Configuration;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
-import org.apache.camel.Predicate;
 import org.apache.camel.component.xquery.XQueryBuilder;
 import org.apache.camel.spi.PropertyConfigurer;
 import org.apache.camel.spi.annotations.Language;
@@ -43,46 +42,21 @@ public class XQueryLanguage extends 
SingleInputTypedLanguageSupport implements P
     }
 
     @Override
-    public Predicate createPredicate(String expression) {
-        return (Predicate) createExpression(expression, null);
-    }
-
-    @Override
-    public Expression createExpression(String expression) {
-        return createExpression(expression, null);
-    }
-
-    @Override
-    public Predicate createPredicate(String expression, Object[] properties) {
-        return (Predicate) createExpression(expression, properties);
-    }
-
-    @Override
-    public Expression createExpression(String expression, Object[] properties) 
{
+    public Expression createExpression(Expression source, String expression, 
Object[] properties) {
         expression = loadResource(expression);
 
         XQueryBuilder builder = XQueryBuilder.xquery(expression);
-        configureBuilder(builder, properties);
+        configureBuilder(builder, properties, source);
         return builder;
     }
 
-    protected void configureBuilder(XQueryBuilder builder, Object[] 
properties) {
+    protected void configureBuilder(XQueryBuilder builder, Object[] 
properties, Expression source) {
+        builder.setSource(source);
+
         Class<?> clazz = property(Class.class, properties, 0, getResultType());
         if (clazz != null) {
             builder.setResultType(clazz);
         }
-        String str = property(String.class, properties, 1, getHeaderName());
-        if (str != null) {
-            builder.setHeaderName(str);
-        }
-        str = property(String.class, properties, 2, getPropertyName());
-        if (str != null) {
-            builder.setPropertyName(str);
-        }
-        str = property(String.class, properties, 3, getVariableName());
-        if (str != null) {
-            builder.setVariableName(str);
-        }
         if (configuration != null) {
             builder.setConfiguration(configuration);
         }
@@ -98,18 +72,6 @@ public class XQueryLanguage extends 
SingleInputTypedLanguageSupport implements P
             case "resultType":
                 setResultType(PropertyConfigurerSupport.property(camelContext, 
Class.class, value));
                 return true;
-            case "headername":
-            case "headerName":
-                setHeaderName(PropertyConfigurerSupport.property(camelContext, 
String.class, value));
-                return true;
-            case "propertyname":
-            case "propertyName":
-                
setPropertyName(PropertyConfigurerSupport.property(camelContext, String.class, 
value));
-                return true;
-            case "variablename":
-            case "variableName":
-                
setVariableName(PropertyConfigurerSupport.property(camelContext, String.class, 
value));
-                return true;
             case "configuration":
             case "Configuration":
                 
setConfiguration(PropertyConfigurerSupport.property(camelContext, 
Configuration.class, value));
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
index 270c7364273..3ee13662e94 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
@@ -30,15 +30,15 @@ public class JsonPathExpressionReifier extends 
SingleInputTypedExpressionReifier
     protected Object[] createProperties() {
         Object[] properties = new Object[10];
         properties[0] = definition.getResultType();
-        properties[1] = parseBoolean(definition.getSuppressExceptions());
-        properties[2] = parseBoolean(definition.getAllowSimple());
-        properties[3] = parseBoolean(definition.getAllowEasyPredicate());
-        properties[4] = parseBoolean(definition.getWriteAsString());
-        properties[5] = parseBoolean(definition.getUnpackArray());
-        properties[6] = parseString(definition.getHeaderName());
-        properties[7] = parseString(definition.getOption());
-        properties[8] = parseString(definition.getPropertyName());
-        properties[9] = parseString(definition.getVariableName());
+        properties[1] = parseString(definition.getVariableName());
+        properties[2] = parseString(definition.getHeaderName());
+        properties[3] = parseString(definition.getPropertyName());
+        properties[4] = parseBoolean(definition.getSuppressExceptions());
+        properties[5] = parseBoolean(definition.getAllowSimple());
+        properties[6] = parseBoolean(definition.getAllowEasyPredicate());
+        properties[7] = parseBoolean(definition.getWriteAsString());
+        properties[8] = parseBoolean(definition.getUnpackArray());
+        properties[9] = parseString(definition.getOption());
         return properties;
     }
 
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
index 48726d3e5d0..0ee0dbf4ab8 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/language/XQueryExpressionReifier.java
@@ -61,9 +61,9 @@ public class XQueryExpressionReifier extends 
ExpressionReifier<XQueryExpression>
     protected Object[] createProperties() {
         Object[] properties = new Object[4];
         properties[0] = definition.getResultType();
-        properties[1] = parseString(definition.getHeaderName());
-        properties[2] = parseString(definition.getPropertyName());
-        properties[3] = parseString(definition.getVariableName());
+        properties[1] = parseString(definition.getVariableName());
+        properties[2] = parseString(definition.getHeaderName());
+        properties[3] = parseString(definition.getPropertyName());
         return properties;
     }
 

Reply via email to