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

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

commit bd9e46bdc712a157febb8f6f3a5e45a3f9c8bd62
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jan 14 11:27:04 2026 +0100

    CAMEL-22583: camel-core - Add convertTo function to simple language
---
 .../org/apache/camel/catalog/languages/simple.json |  2 +-
 .../language/csimple/joor/OriginalSimpleTest.java  | 10 +++++++++
 .../modules/languages/pages/simple-language.adoc   |  1 +
 .../language/simple/SimpleExpressionBuilder.java   |  3 +++
 .../simple/ast/SimpleFunctionExpression.java       | 24 ++++++++++++++++++----
 .../apache/camel/language/simple/SimpleTest.java   | 18 ++++++++++++++++
 6 files changed, 53 insertions(+), 5 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
index 924442008b66..f7dbf5cd4835 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
@@ -71,7 +71,7 @@
     "substring(head,tail)": { "index": 45, "kind": "function", "displayName": 
"Substring", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Returns a substring of 
the message body\/expression. If only one positive number, then the returned 
string is clipped from the beginning. If only one negative number, then the 
returned string is clipped fr [...]
     "random(min,max)": { "index": 46, "kind": "function", "displayName": 
"Generate Random Number", "group": "function", "label": "function", "required": 
false, "javaType": "int", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a random number between min (included) and max (excluded).", "ognl": 
false, "suffix": "}" },
     "skip(num)": { "index": 47, "kind": "function", "displayName": "Skip First 
Items from the Message Body", "group": "function", "label": "function", 
"required": false, "javaType": "java.util.Iterator", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The skip function iterates the message body and skips 
the first number of items. This can be used with the Splitter EIP to split a 
message body and skip the first N number of  [...]
-    "convertTo(exp,type)": { "index": 48, "kind": "function", "displayName": 
"Convert To", "group": "function", "label": "function", "required": false, 
"javaType": "", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Converts the message body 
(or expression) to the specified type.", "ognl": false, "suffix": "}" },
+    "convertTo(exp,type)": { "index": 48, "kind": "function", "displayName": 
"Convert To", "group": "function", "label": "function", "required": false, 
"javaType": "", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Converts the message body 
(or expression) to the specified type.", "ognl": true, "suffix": "}" },
     "trim(exp)": { "index": 49, "kind": "function", "displayName": "Trim", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The trim function trims 
the message body (or expression) by removing all leading and trailing white 
spaces.", "ognl": false, "suffix": "}" },
     "length(exp)": { "index": 50, "kind": "function", "displayName": "Length", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The payload length (number of bytes) of the 
message body (or expression).", "ognl": false, "suffix": "}" },
     "size(exp)": { "index": 51, "kind": "function", "displayName": "Size", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The size of the message body (or expression). 
If the payload is java.util.Collection or java.util.Map based then the size is 
the number of elements; otherwise the payload size in bytes.", "ognl": false, 
"suffix": "}" },
diff --git 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
index 806bf99e03fc..118a62abacb5 100644
--- 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
+++ 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
@@ -42,6 +42,7 @@ import org.apache.camel.Predicate;
 import org.apache.camel.component.bean.MethodNotFoundException;
 import org.apache.camel.language.bean.RuntimeBeanExpressionException;
 import org.apache.camel.language.csimple.CSimpleLanguage;
+import org.apache.camel.language.simple.SimpleTest;
 import org.apache.camel.language.simple.types.SimpleIllegalSyntaxException;
 import org.apache.camel.spi.ExchangeFormatter;
 import org.apache.camel.spi.Language;
@@ -2276,6 +2277,15 @@ public class OriginalSimpleTest extends 
LanguageTestSupport {
         assertEquals(Boolean.TRUE, s);
     }
 
+    @Test
+    public void testConvertToOGNL() {
+        exchange.getIn().setBody(new SimpleTest.OrderLine(123, "Camel in 
Action"));
+
+        
assertExpression("${convertTo(${body},org.apache.camel.language.simple.SimpleTest$OrderLine).getId}",
 123);
+        
assertExpression("${convertTo(${body},org.apache.camel.language.simple.SimpleTest$OrderLine).getName}",
+                "Camel in Action");
+    }
+
     @Test
     public void testSize() {
         exchange.getMessage().setBody(new int[] { 4, 7, 9 });
diff --git 
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
 
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
index 4b0fee763ebd..e6ad1b8eb142 100644
--- 
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
+++ 
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
@@ -295,6 +295,7 @@ log sensitive data from the message itself.
 |concat(exp,exp,separator) |String |Performs a string concat using two 
expressions (message body as default) with optional separator
 
 |convertTo(exp,type) |Object |Converts the message body (or expression) to the 
specified type.
+|convertTo(exp,type).*OGNL* |Object |Converts the message body (or expression) 
to the specified type and then invoke methods using a Camel OGNL expression.
 
 |length(exp) |int |The payload length (number of bytes) of the message body 
(or expression).
 
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
index 54f4c3f53347..b57a79616241 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
@@ -322,6 +322,9 @@ public final class SimpleExpressionBuilder {
             @Override
             public Object evaluate(Exchange exchange) {
                 Object body = exp.evaluate(exchange, clazz);
+                if (body == null) {
+                    return null;
+                }
                 Expression ognlExp = bean.createExpression(null, new Object[] 
{ null, body, ognl });
                 ognlExp.init(exchange.getContext());
                 return ognlExp.evaluate(exchange, Object.class);
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
index b331eab0617d..aeb19e589610 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
@@ -2086,12 +2086,12 @@ public class SimpleFunctionExpression extends 
LiteralExpression {
         }
 
         // convertTo function
-        // TODO: ongl
         remainder = ifStartsWithReturnRemainder("convertTo(", function);
         if (remainder != null) {
+            String ognl = null;
             String exp = "body";
             String type;
-            String values = StringHelper.beforeLast(remainder, ")");
+            String values = StringHelper.before(remainder, ")");
             if (values == null || ObjectHelper.isEmpty(values)) {
                 throw new SimpleParserException(
                         "Valid syntax: ${convertTo(type)} or 
${convertTo(exp,type)} was: " + function,
@@ -2114,11 +2114,27 @@ public class SimpleFunctionExpression extends 
LiteralExpression {
             }
             type = appendClass(type);
             type = type.replace('$', '.');
-
             if (ObjectHelper.isEmpty(exp)) {
                 exp = "null";
             }
-            return "Object value = " + exp + ";\n        return 
convertTo(exchange, " + type + ", value);";
+
+            remainder = StringHelper.after(remainder, ")");
+            if (ObjectHelper.isNotEmpty(remainder)) {
+                boolean invalid = 
OgnlHelper.isInvalidValidOgnlExpression(remainder);
+                if (invalid) {
+                    throw new SimpleParserException(
+                            "Valid syntax: ${convertTo(type).OGNL} or 
${convertTo(exp,type).OGNL} was: " + function,
+                            token.getIndex());
+                }
+                ognl = ognlCodeMethods(remainder, type);
+            }
+
+            String code = "Object value = " + exp + ";\n        return 
convertTo(exchange, " + type + ", value)";
+            if (ognl != null) {
+                code += ognl;
+            }
+            code += ";";
+            return code;
         }
 
         // uppercase function
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
index 30744c367c33..b0605feca4e9 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
@@ -2504,6 +2504,24 @@ public class SimpleTest extends LanguageTestSupport {
         assertEquals(Boolean.TRUE, s);
     }
 
+    @Test
+    public void testConvertToOGNL() {
+        exchange.getIn().setBody(new OrderLine(123, "Camel in Action"));
+
+        
assertExpression("${convertTo(${body},org.apache.camel.language.simple.SimpleTest$OrderLine).getId}",
 123);
+        
assertExpression("${convertTo(${body},org.apache.camel.language.simple.SimpleTest$OrderLine).getName}",
+                "Camel in Action");
+    }
+
+    @Test
+    public void testConvertToOGNLArray() {
+        exchange.getIn().setBody(new SimpleTest.OrderLine(123, "Camel in 
Action"));
+
+        
assertExpression("${convertTo(${body},org.apache.camel.language.simple.SimpleTest$OrderLine).getId}",
 123);
+        
assertExpression("${convertTo(${body},org.apache.camel.language.simple.SimpleTest$OrderLine).getName}",
+                "Camel in Action");
+    }
+
     @Test
     public void testTrim() {
         exchange.getMessage().setBody("   Hello World ");

Reply via email to