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

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

commit 7d07d3ba7ddbede6b8fff54034dcc2197096da0c
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Oct 1 15:27:57 2020 +0200

    CAMEL-15605: Languages should be singleton for better performance.
---
 .../camel/catalog/docs/jsonpath-language.adoc      |  3 +-
 .../apache/camel/language/bean/BeanExpression.java | 16 ----
 .../apache/camel/language/bean/BeanLanguage.java   | 45 +++++++++++
 .../org/apache/camel/jsonpath/jsonpath.json        |  1 +
 .../src/main/docs/jsonpath-language.adoc           |  3 +-
 .../apache/camel/jsonpath/JsonPathExpression.java  | 40 +---------
 .../apache/camel/jsonpath/JsonPathLanguage.java    | 92 ++++++++++++++++++----
 .../camel/jsonpath/JsonPathLanguageTest.java       |  2 +-
 .../main/java/org/apache/camel/spi/Language.java   |  8 +-
 .../org/apache/camel/model/language/jsonpath.json  |  1 +
 .../camel/model/language/JsonPathExpression.java   | 14 ++++
 .../language/JsonPathExpressionReifier.java        | 42 ++++++----
 .../org/apache/camel/support/LanguageSupport.java  | 72 +++++++++++++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  1 +
 .../modules/languages/pages/jsonpath-language.adoc |  3 +-
 15 files changed, 250 insertions(+), 93 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jsonpath-language.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jsonpath-language.adoc
index 806aca9..87ae77d 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jsonpath-language.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jsonpath-language.adoc
@@ -29,7 +29,7 @@ from("queue:books.new")
 
 
 // language options: START
-The JsonPath language supports 7 options, which are listed below.
+The JsonPath language supports 8 options, which are listed below.
 
 
 
@@ -42,6 +42,7 @@ The JsonPath language supports 7 options, which are listed 
below.
 | allowEasyPredicate | true | Boolean | Whether to allow using the easy 
predicate parser to pre-parse predicates.
 | writeAsString | false | Boolean | Whether to write the output of each 
row/element as a JSON String value instead of a Map/POJO value.
 | headerName |  | String | Name of header to use as input, instead of the 
message body
+| option |  | String | To configure additional options on json path. Multiple 
values can be separated by comma.
 | trim | true | Boolean | Whether to trim the value to remove leading and 
trailing whitespaces and line breaks
 |===
 // language options: END
diff --git 
a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
 
b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
index 6fdaafa..9d2038e 100644
--- 
a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
+++ 
b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
@@ -81,34 +81,18 @@ public class BeanExpression implements Expression, 
Predicate, AfterPropertiesCon
         return bean;
     }
 
-    public void setBean(Object bean) {
-        this.bean = bean;
-    }
-
     public String getBeanName() {
         return beanName;
     }
 
-    public void setBeanName(String beanName) {
-        this.beanName = beanName;
-    }
-
     public Class<?> getType() {
         return type;
     }
 
-    public void setType(Class<?> type) {
-        this.type = type;
-    }
-
     public String getMethod() {
         return method;
     }
 
-    public void setMethod(String method) {
-        this.method = method;
-    }
-
     @Override
     public void init(CamelContext context) {
     }
diff --git 
a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
 
b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
index 70d6692..d59e676d 100644
--- 
a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
+++ 
b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanLanguage.java
@@ -38,9 +38,46 @@ import org.apache.camel.util.StringHelper;
 @org.apache.camel.spi.annotations.Language("bean")
 public class BeanLanguage extends LanguageSupport {
 
+    private Object bean;
+    private Class<?> beanType;
+    private String ref;
+    private String method;
+
     public BeanLanguage() {
     }
 
+    public Object getBean() {
+        return bean;
+    }
+
+    public void setBean(Object bean) {
+        this.bean = bean;
+    }
+
+    public Class<?> getBeanType() {
+        return beanType;
+    }
+
+    public void setBeanType(Class<?> beanType) {
+        this.beanType = beanType;
+    }
+
+    public String getRef() {
+        return ref;
+    }
+
+    public void setRef(String ref) {
+        this.ref = ref;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+    }
+
     @Override
     public Predicate createPredicate(String expression) {
         return 
ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
@@ -72,6 +109,14 @@ public class BeanLanguage extends LanguageSupport {
     @Override
     public Expression createExpression(String expression) {
         // favour using the configured options
+        if (bean != null) {
+            return new BeanExpression(bean, method);
+        } else if (beanType != null) {
+            return new BeanExpression(beanType, method);
+        } else if (ref != null) {
+            return new BeanExpression(ref, method);
+        }
+
         String beanName = expression;
         String method = null;
 
diff --git 
a/components/camel-jsonpath/src/generated/resources/org/apache/camel/jsonpath/jsonpath.json
 
b/components/camel-jsonpath/src/generated/resources/org/apache/camel/jsonpath/jsonpath.json
index a97e759..c5fab68 100644
--- 
a/components/camel-jsonpath/src/generated/resources/org/apache/camel/jsonpath/jsonpath.json
+++ 
b/components/camel-jsonpath/src/generated/resources/org/apache/camel/jsonpath/jsonpath.json
@@ -23,6 +23,7 @@
     "allowEasyPredicate": { "kind": "attribute", "displayName": "Allow Easy 
Predicate", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
true, "description": "Whether to allow using the easy predicate parser to 
pre-parse predicates." },
     "writeAsString": { "kind": "attribute", "displayName": "Write As String", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "secret": false, "defaultValue": false, "description": 
"Whether to write the output of each row\/element as a JSON String value 
instead of a Map\/POJO value." },
     "headerName": { "kind": "attribute", "displayName": "Header Name", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Name of header to use as 
input, instead of the message body" },
+    "option": { "kind": "attribute", "displayName": "Option", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ 
"ALWAYS_RETURN_LIST", "AS_PATH_LIST", "DEFAULT_PATH_LEAF_TO_NULL", 
"REQUIRE_PROPERTIES", "SUPPRESS_EXCEPTIONS" ], "deprecated": false, "secret": 
false, "description": "To configure additional options on json path. Multiple 
values can be separated by comma." },
     "trim": { "kind": "attribute", "displayName": "Trim", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
value to remove leading and trailing whitespaces and line breaks" },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" }
   }
diff --git a/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc 
b/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
index 806aca9..87ae77d 100644
--- a/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
+++ b/components/camel-jsonpath/src/main/docs/jsonpath-language.adoc
@@ -29,7 +29,7 @@ from("queue:books.new")
 
 
 // language options: START
-The JsonPath language supports 7 options, which are listed below.
+The JsonPath language supports 8 options, which are listed below.
 
 
 
@@ -42,6 +42,7 @@ The JsonPath language supports 7 options, which are listed 
below.
 | allowEasyPredicate | true | Boolean | Whether to allow using the easy 
predicate parser to pre-parse predicates.
 | writeAsString | false | Boolean | Whether to write the output of each 
row/element as a JSON String value instead of a Map/POJO value.
 | headerName |  | String | Name of header to use as input, instead of the 
message body
+| option |  | String | To configure additional options on json path. Multiple 
values can be separated by comma.
 | trim | true | Boolean | Whether to trim the value to remove leading and 
trailing whitespaces and line breaks
 |===
 // language options: END
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 60954f9..7dfb850 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
@@ -26,13 +26,11 @@ import org.apache.camel.Exchange;
 import org.apache.camel.ExpressionEvaluationException;
 import org.apache.camel.ExpressionIllegalSyntaxException;
 import org.apache.camel.jsonpath.easypredicate.EasyPredicateParser;
-import org.apache.camel.spi.GeneratedPropertyConfigurer;
 import org.apache.camel.support.ExpressionAdapter;
-import org.apache.camel.support.component.PropertyConfigurerSupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class JsonPathExpression extends ExpressionAdapter implements 
AfterPropertiesConfigured, GeneratedPropertyConfigurer {
+public class JsonPathExpression extends ExpressionAdapter implements 
AfterPropertiesConfigured {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(JsonPathExpression.class);
 
@@ -46,47 +44,13 @@ public class JsonPathExpression extends ExpressionAdapter 
implements AfterProper
     private boolean allowEasyPredicate = true;
     private boolean writeAsString;
     private String headerName;
+    private String option;
     private Option[] options;
 
     public JsonPathExpression(String expression) {
         this.expression = expression;
     }
 
-    @Override
-    public boolean configure(CamelContext camelContext, Object target, String 
name, Object value, boolean ignoreCase) {
-        if (target != this) {
-            throw new IllegalStateException("Can only configure our own 
instance !");
-        }
-        switch (ignoreCase ? name.toLowerCase() : name) {
-            case "resulttype":
-            case "resultType":
-                setResultType(PropertyConfigurerSupport.property(camelContext, 
Class.class, value));
-                return true;
-            case "suppressexceptions":
-            case "suppressExceptions":
-                
setSuppressExceptions(PropertyConfigurerSupport.property(camelContext, 
Boolean.class, value));
-                return true;
-            case "allowsimple":
-            case "allowSimple":
-                
setAllowSimple(PropertyConfigurerSupport.property(camelContext, Boolean.class, 
value));
-                return true;
-            case "alloweasypredicate":
-            case "allowEasyPredicate":
-                
setAllowEasyPredicate(PropertyConfigurerSupport.property(camelContext, 
Boolean.class, value));
-                return true;
-            case "writeasstring":
-            case "writeAsString":
-                
setWriteAsString(PropertyConfigurerSupport.property(camelContext, 
Boolean.class, value));
-                return true;
-            case "headername":
-            case "headerName":
-                setHeaderName(PropertyConfigurerSupport.property(camelContext, 
String.class, value));
-                return true;
-            default:
-                return false;
-        }
-    }
-
     public boolean isPredicate() {
         return predicate;
     }
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 0873981..e04bb94 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
@@ -16,6 +16,10 @@
  */
 package org.apache.camel.jsonpath;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 import com.jayway.jsonpath.Option;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
@@ -27,6 +31,10 @@ public class JsonPathLanguage extends LanguageSupport {
 
     private Class<?> resultType;
     private boolean suppressExceptions;
+    private boolean allowSimple = true;
+    private boolean allowEasyPredicate = true;
+    private boolean writeAsString;
+    private String headerName;
     private Option[] options;
 
     public Class<?> getResultType() {
@@ -45,43 +53,95 @@ public class JsonPathLanguage extends LanguageSupport {
         this.suppressExceptions = suppressExceptions;
     }
 
-    public Option[] getOptions() {
-        return options;
+    public boolean isAllowSimple() {
+        return allowSimple;
+    }
+
+    public void setAllowSimple(boolean allowSimple) {
+        this.allowSimple = allowSimple;
+    }
+
+    public boolean isAllowEasyPredicate() {
+        return allowEasyPredicate;
+    }
+
+    public void setAllowEasyPredicate(boolean allowEasyPredicate) {
+        this.allowEasyPredicate = allowEasyPredicate;
+    }
+
+    public boolean isWriteAsString() {
+        return writeAsString;
+    }
+
+    public void setWriteAsString(boolean writeAsString) {
+        this.writeAsString = writeAsString;
+    }
+
+    public String getHeaderName() {
+        return headerName;
     }
 
-    public void setOption(Option option) {
-        this.options = new Option[] { option };
+    public void setHeaderName(String headerName) {
+        this.headerName = headerName;
     }
 
-    public void setOptions(Option[] options) {
+    public Option[] getOptions() {
+        return options;
+    }
+
+    public void setOptions(Option... options) {
         this.options = options;
     }
 
     @Override
-    public Predicate createPredicate(final String predicate) {
-        JsonPathExpression answer = new JsonPathExpression(predicate);
+    public Predicate createPredicate(String expression) {
+        JsonPathExpression answer = (JsonPathExpression) 
createExpression(expression);
         answer.setPredicate(true);
-        answer.setResultType(resultType);
-        answer.setSuppressExceptions(suppressExceptions);
-        answer.setOptions(options);
-        answer.afterPropertiesConfigured(getCamelContext());
         return answer;
     }
 
     @Override
-    public Expression createExpression(final String expression) {
+    public Expression createExpression(String expression) {
         JsonPathExpression answer = new JsonPathExpression(expression);
-        answer.setPredicate(false);
         answer.setResultType(resultType);
         answer.setSuppressExceptions(suppressExceptions);
+        answer.setAllowSimple(allowSimple);
+        answer.setAllowEasyPredicate(allowEasyPredicate);
+        answer.setHeaderName(headerName);
+        answer.setWriteAsString(writeAsString);
+        answer.setHeaderName(headerName);
         answer.setOptions(options);
         answer.afterPropertiesConfigured(getCamelContext());
         return answer;
     }
 
     @Override
-    public boolean isSingleton() {
-        // cannot be singleton due options
-        return false;
+    public Predicate createPredicate(Map<String, Object> properties) {
+        JsonPathExpression json = (JsonPathExpression) 
createExpression(properties);
+        json.setPredicate(true);
+        return json;
     }
+
+    @Override
+    public Expression createExpression(Map<String, Object> properties) {
+        String exp = (String) properties.get("expression");
+        JsonPathExpression answer = new JsonPathExpression(exp);
+        answer.setResultType(property(Class.class, properties, "resultType", 
null));
+        answer.setSuppressExceptions(property(boolean.class, properties, 
"suppressExceptions", true));
+        answer.setAllowEasyPredicate(property(boolean.class, properties, 
"allowEasyPredicate", true));
+        answer.setAllowSimple(property(boolean.class, properties, 
"allowSimple", true));
+        answer.setWriteAsString(property(boolean.class, properties, 
"writeAsString", false));
+        answer.setHeaderName(property(String.class, properties, "headerName", 
null));
+        String option = (String) properties.get("option");
+        if (option != null) {
+            List<Option> list = new ArrayList<>();
+            for (String s : option.split(",")) {
+                
list.add(getCamelContext().getTypeConverter().convertTo(Option.class, s));
+            }
+            answer.setOptions(list.toArray(new Option[list.size()]));
+        }
+        answer.afterPropertiesConfigured(getCamelContext());
+        return answer;
+    }
+
 }
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 7f9769f..e6bea51 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
@@ -128,7 +128,7 @@ public class JsonPathLanguageTest extends CamelTestSupport {
         exchange.getIn().setBody(new File("src/test/resources/type.json"));
 
         JsonPathLanguage lan = (JsonPathLanguage) 
context.resolveLanguage("jsonpath");
-        lan.setOption(Option.SUPPRESS_EXCEPTIONS);
+        lan.setOptions(Option.SUPPRESS_EXCEPTIONS);
 
         Expression exp = lan.createExpression("$.foo");
         String nofoo = exp.evaluate(exchange, String.class);
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Language.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/Language.java
index 1376c76..b046242 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Language.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Language.java
@@ -45,8 +45,8 @@ public interface Language {
     /**
      * Creates an expression based on the given inputs properties
      *
-     * This is used for languages that have been configured with custom 
properties
-     * most noticeable for xpath/xquery/tokenizer languages that have several 
options.
+     * This is used for languages that have been configured with custom 
properties most noticeable for
+     * xpath/xquery/tokenizer languages that have several options.
      *
      * @param  properties arguments
      * @return            the created predicate
@@ -58,8 +58,8 @@ public interface Language {
     /**
      * Creates an expression based on the given inputs properties
      *
-     * This is used for languages that have been configured with custom 
properties
-     * most noticeable for xpath/xquery/tokenizer languages that have several 
options.
+     * This is used for languages that have been configured with custom 
properties most noticeable for
+     * xpath/xquery/tokenizer languages that have several options.
      *
      * @param  properties arguments
      * @return            the created expression
diff --git 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jsonpath.json
 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jsonpath.json
index 532aef0..d30d808 100644
--- 
a/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jsonpath.json
+++ 
b/core/camel-core-engine/src/generated/resources/org/apache/camel/model/language/jsonpath.json
@@ -19,6 +19,7 @@
     "allowEasyPredicate": { "kind": "attribute", "displayName": "Allow Easy 
Predicate", "required": false, "type": "boolean", "javaType": 
"java.lang.Boolean", "deprecated": false, "secret": false, "defaultValue": 
true, "description": "Whether to allow using the easy predicate parser to 
pre-parse predicates." },
     "writeAsString": { "kind": "attribute", "displayName": "Write As String", 
"required": false, "type": "boolean", "javaType": "java.lang.Boolean", 
"deprecated": false, "secret": false, "defaultValue": false, "description": 
"Whether to write the output of each row\/element as a JSON String value 
instead of a Map\/POJO value." },
     "headerName": { "kind": "attribute", "displayName": "Header Name", 
"required": false, "type": "string", "javaType": "java.lang.String", 
"deprecated": false, "secret": false, "description": "Name of header to use as 
input, instead of the message body" },
+    "option": { "kind": "attribute", "displayName": "Option", "required": 
false, "type": "enum", "javaType": "java.lang.String", "enum": [ 
"ALWAYS_RETURN_LIST", "AS_PATH_LIST", "DEFAULT_PATH_LEAF_TO_NULL", 
"REQUIRE_PROPERTIES", "SUPPRESS_EXCEPTIONS" ], "deprecated": false, "secret": 
false, "description": "To configure additional options on json path. Multiple 
values can be separated by comma." },
     "trim": { "kind": "attribute", "displayName": "Trim", "required": false, 
"type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"secret": false, "defaultValue": true, "description": "Whether to trim the 
value to remove leading and trailing whitespaces and line breaks" },
     "id": { "kind": "attribute", "displayName": "Id", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"secret": false, "description": "Sets the id of this node" }
   }
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
index 81947b4..732b24f 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/JsonPathExpression.java
@@ -50,6 +50,9 @@ public class JsonPathExpression extends ExpressionDefinition {
     private String writeAsString;
     @XmlAttribute
     private String headerName;
+    @XmlAttribute
+    @Metadata(enums = 
"DEFAULT_PATH_LEAF_TO_NULL,ALWAYS_RETURN_LIST,AS_PATH_LIST,SUPPRESS_EXCEPTIONS,REQUIRE_PROPERTIES")
+    private String option;
 
     public JsonPathExpression() {
     }
@@ -135,6 +138,17 @@ public class JsonPathExpression extends 
ExpressionDefinition {
         this.headerName = headerName;
     }
 
+    public String getOption() {
+        return option;
+    }
+
+    /**
+     * To configure additional options on json path. Multiple values can be 
separated by comma.
+     */
+    public void setOption(String option) {
+        this.option = option;
+    }
+
     @Override
     public String getLanguage() {
         return "jsonpath";
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
index 669386d..b04303e 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/JsonPathExpressionReifier.java
@@ -22,38 +22,50 @@ import java.util.Map;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.language.JsonPathExpression;
+import org.apache.camel.spi.Language;
 
 public class JsonPathExpressionReifier extends 
ExpressionReifier<JsonPathExpression> {
 
-    // TODO: Update me
-
     public JsonPathExpressionReifier(CamelContext camelContext, 
ExpressionDefinition definition) {
         super(camelContext, (JsonPathExpression) definition);
     }
 
     @Override
-    protected void configureExpression(Expression expression) {
-        bindProperties(expression);
-        super.configureExpression(expression);
+    protected void configureLanguage(Language language) {
+        if (definition.getResultType() == null && 
definition.getResultTypeName() != null) {
+            try {
+                Class<?> clazz = 
camelContext.getClassResolver().resolveMandatoryClass(definition.getResultTypeName());
+                definition.setResultType(clazz);
+            } catch (ClassNotFoundException e) {
+                throw RuntimeCamelException.wrapRuntimeException(e);
+            }
+        }
     }
 
-    @Override
-    protected void configurePredicate(Predicate predicate) {
-        bindProperties(predicate);
-        super.configurePredicate(predicate);
-    }
-
-    private void bindProperties(Object target) {
-        Map<String, Object> properties = new HashMap<>();
-        properties.put("resultType", or(definition.getResultType(), 
definition.getResultTypeName()));
+    private Map<String, Object> createProperties(String exp) {
+        Map<String, Object> properties = new HashMap<>(8);
+        properties.put("expression", exp);
+        properties.put("resultType", definition.getResultType());
         properties.put("suppressExceptions", 
definition.getSuppressExceptions());
         properties.put("allowSimple", definition.getAllowSimple());
         properties.put("allowEasyPredicate", 
definition.getAllowEasyPredicate());
         properties.put("writeAsString", definition.getWriteAsString());
         properties.put("headerName", definition.getHeaderName());
-        setProperties(target, properties);
+        properties.put("option", definition.getOption());
+        return properties;
+    }
+
+    @Override
+    protected Expression createExpression(Language language, String exp) {
+        return language.createExpression(createProperties(exp));
+    }
+
+    @Override
+    protected Predicate createPredicate(Language language, String exp) {
+        return language.createPredicate(createProperties(exp));
     }
 
 }
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java
index e762093..6bd6c12 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/LanguageSupport.java
@@ -17,13 +17,17 @@
 package org.apache.camel.support;
 
 import java.io.InputStream;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.ExpressionIllegalSyntaxException;
 import org.apache.camel.IsSingleton;
+import org.apache.camel.NoSuchBeanException;
 import org.apache.camel.spi.Language;
 import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.TimeUtils;
 
 /**
  * Base language for {@link Language} implementations.
@@ -91,4 +95,72 @@ public abstract class LanguageSupport implements Language, 
IsSingleton, CamelCon
         return false;
     }
 
+    /**
+     * Converts the property to the expected type
+     *
+     * @param  type         the expected type
+     * @param  properties   the options
+     * @param  key          name of the property
+     * @param  defaultValue optional default value
+     * @return              the value converted to the expected type
+     */
+    protected <T> T property(Class<T> type, Map<String, Object> properties, 
String key, Object defaultValue) {
+        Object value = properties.get(key);
+        if (value == null) {
+            value = defaultValue;
+        }
+
+        // if the type is not string based and the value is a bean reference, 
then we need to lookup
+        // the bean from the registry
+        if (value instanceof String && String.class != type) {
+            String text = value.toString();
+
+            if (EndpointHelper.isReferenceParameter(text)) {
+                Object obj;
+                // special for a list where we refer to beans which can be 
either a list or a single element
+                // so use Object.class as type
+                if (type == List.class) {
+                    obj = 
EndpointHelper.resolveReferenceListParameter(camelContext, text, Object.class);
+                } else {
+                    obj = 
EndpointHelper.resolveReferenceParameter(camelContext, text, type);
+                }
+                if (obj == null) {
+                    // no bean found so throw an exception
+                    throw new NoSuchBeanException(text, type.getName());
+                }
+                value = obj;
+            } else if (type == long.class || type == Long.class || type == 
int.class || type == Integer.class) {
+                Object obj = null;
+                // string to long/int then it may be a duration where we can 
convert the value to milli seconds
+                // it may be a time pattern, such as 5s for 5 seconds = 5000
+                try {
+                    long num = TimeUtils.toMilliSeconds(text);
+                    if (type == int.class || type == Integer.class) {
+                        // need to cast to int
+                        obj = (int) num;
+                    } else {
+                        obj = num;
+                    }
+                } catch (IllegalArgumentException e) {
+                    // ignore
+                }
+                if (obj != null) {
+                    value = obj;
+                }
+            }
+        }
+
+        // special for boolean values with string values as we only want to 
accept "true" or "false"
+        if ((type == Boolean.class || type == boolean.class) && value 
instanceof String) {
+            String text = (String) value;
+            if (!text.equalsIgnoreCase("true") && 
!text.equalsIgnoreCase("false")) {
+                throw new IllegalArgumentException(
+                        "Cannot convert the String value: " + value + " to 
type: " + type
+                                                   + " as the value is not 
true or false");
+            }
+        }
+
+        return camelContext.getTypeConverter().convertTo(type, value);
+    }
+
 }
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 354617f..31cea3a 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -2350,6 +2350,7 @@ public class ModelParser extends BaseParser {
                 case "allowEasyPredicate": def.setAllowEasyPredicate(val); 
break;
                 case "allowSimple": def.setAllowSimple(val); break;
                 case "headerName": def.setHeaderName(val); break;
+                case "option": def.setOption(val); break;
                 case "resultType": def.setResultTypeName(val); break;
                 case "suppressExceptions": def.setSuppressExceptions(val); 
break;
                 case "writeAsString": def.setWriteAsString(val); break;
diff --git a/docs/components/modules/languages/pages/jsonpath-language.adoc 
b/docs/components/modules/languages/pages/jsonpath-language.adoc
index 0e57f87..7bfa539 100644
--- a/docs/components/modules/languages/pages/jsonpath-language.adoc
+++ b/docs/components/modules/languages/pages/jsonpath-language.adoc
@@ -31,7 +31,7 @@ from("queue:books.new")
 
 
 // language options: START
-The JsonPath language supports 7 options, which are listed below.
+The JsonPath language supports 8 options, which are listed below.
 
 
 
@@ -44,6 +44,7 @@ The JsonPath language supports 7 options, which are listed 
below.
 | allowEasyPredicate | true | Boolean | Whether to allow using the easy 
predicate parser to pre-parse predicates.
 | writeAsString | false | Boolean | Whether to write the output of each 
row/element as a JSON String value instead of a Map/POJO value.
 | headerName |  | String | Name of header to use as input, instead of the 
message body
+| option |  | String | To configure additional options on json path. Multiple 
values can be separated by comma.
 | trim | true | Boolean | Whether to trim the value to remove leading and 
trailing whitespaces and line breaks
 |===
 // language options: END

Reply via email to