This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 9377f77cc8ce CAMEL-23047: camel-core - Add val function to simple
9377f77cc8ce is described below
commit 9377f77cc8ce144a332ddbb8cc8b3017dba0b1c1
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Feb 21 20:05:25 2026 +0100
CAMEL-23047: camel-core - Add val function to simple
---
.../org/apache/camel/catalog/languages/simple.json | 9 ++---
.../language/csimple/joor/OriginalSimpleTest.java | 18 ++++++++++
.../org/apache/camel/language/simple/simple.json | 9 ++---
.../modules/languages/pages/simple-language.adoc | 1 +
.../camel/language/simple/SimpleConstants.java | 4 +++
.../simple/ast/SimpleFunctionExpression.java | 28 ++++++++++++++++
.../camel/language/simple/SimpleInitBlockTest.java | 39 ++++++++++++++++++++++
.../apache/camel/language/simple/SimpleTest.java | 22 ++++++++++++
.../java/org/apache/camel/util/SimpleUtils.java | 1 +
9 files changed, 123 insertions(+), 8 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 9cceb9d61384..e8afbc37b6a8 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
@@ -136,9 +136,10 @@
"unquote(exp)": { "index": 108, "kind": "function", "displayName":
"Unquote", "group": "string", "label": "string", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns the message body
(or expression) with any leading\/ending quotes removed", "ognl": false,
"suffix": "}" },
"uppercase(exp)": { "index": 109, "kind": "function", "displayName":
"Uppercase", "group": "string", "label": "string", "required": false,
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Uppercases the message
body (or expression)", "ognl": false, "suffix": "}" },
"uuid(type)": { "index": 110, "kind": "function", "displayName": "Generate
UUID", "group": "other", "label": "other", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns a UUID using the
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and
`simple` as the type. If no type is given, the default is used. It is also
possible to use a custom `UuidGenera [...]
- "variable.name": { "index": 111, "kind": "function", "displayName":
"Variable", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
- "variableAs(key,type)": { "index": 112, "kind": "function", "displayName":
"Variable As", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Converts the variable to
the given type (classname).", "ognl": false, "suffix": "}" },
- "variables": { "index": 113, "kind": "function", "displayName":
"Variables", "group": "core", "label": "core", "required": false, "javaType":
"java.util.Map", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns all the variables
from the current Exchange in a Map", "ognl": false, "suffix": "}" },
- "xpath(input,exp)": { "index": 114, "kind": "function", "displayName":
"XPath", "group": "xml", "label": "xml", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optional), you ca [...]
+ "val(exp)": { "index": 111, "kind": "function", "displayName": "Value",
"group": "core", "label": "core", "required": false, "javaType": "Object",
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "Returns the expression as a constant value",
"ognl": false, "suffix": "}" },
+ "variable.name": { "index": 112, "kind": "function", "displayName":
"Variable", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
+ "variableAs(key,type)": { "index": 113, "kind": "function", "displayName":
"Variable As", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Converts the variable to
the given type (classname).", "ognl": false, "suffix": "}" },
+ "variables": { "index": 114, "kind": "function", "displayName":
"Variables", "group": "core", "label": "core", "required": false, "javaType":
"java.util.Map", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns all the variables
from the current Exchange in a Map", "ognl": false, "suffix": "}" },
+ "xpath(input,exp)": { "index": 115, "kind": "function", "displayName":
"XPath", "group": "xml", "label": "xml", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optional), you ca [...]
}
}
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 27fe37ac8efb..069b5566c72d 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
@@ -2867,6 +2867,24 @@ public class OriginalSimpleTest extends
LanguageTestSupport {
assertEquals("carlsberg", s);
}
+ @Test
+ public void testVal() {
+ exchange.getMessage().setBody(123);
+
+ Expression expression =
context.resolveLanguage("csimple").createExpression("${val(abc)}");
+ String s = expression.evaluate(exchange, String.class);
+ assertEquals("abc", s);
+
+ expression =
context.resolveLanguage("csimple").createExpression("${val(${body})}");
+ s = expression.evaluate(exchange, String.class);
+ assertEquals("123", s);
+
+ expression =
context.resolveLanguage("csimple").createExpression("${val(${body})}");
+ Object obj = expression.evaluate(exchange, Object.class);
+ assertIsInstanceOf(Integer.class, obj);
+ assertEquals(123, obj);
+ }
+
@Test
public void testSetHeader() {
exchange.getMessage().setBody("Hello World");
diff --git
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
index 9cceb9d61384..e8afbc37b6a8 100644
---
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
+++
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
@@ -136,9 +136,10 @@
"unquote(exp)": { "index": 108, "kind": "function", "displayName":
"Unquote", "group": "string", "label": "string", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns the message body
(or expression) with any leading\/ending quotes removed", "ognl": false,
"suffix": "}" },
"uppercase(exp)": { "index": 109, "kind": "function", "displayName":
"Uppercase", "group": "string", "label": "string", "required": false,
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote":
"", "autowired": false, "secret": false, "description": "Uppercases the message
body (or expression)", "ognl": false, "suffix": "}" },
"uuid(type)": { "index": 110, "kind": "function", "displayName": "Generate
UUID", "group": "other", "label": "other", "required": false, "javaType":
"String", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns a UUID using the
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and
`simple` as the type. If no type is given, the default is used. It is also
possible to use a custom `UuidGenera [...]
- "variable.name": { "index": 111, "kind": "function", "displayName":
"Variable", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
- "variableAs(key,type)": { "index": 112, "kind": "function", "displayName":
"Variable As", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Converts the variable to
the given type (classname).", "ognl": false, "suffix": "}" },
- "variables": { "index": 113, "kind": "function", "displayName":
"Variables", "group": "core", "label": "core", "required": false, "javaType":
"java.util.Map", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns all the variables
from the current Exchange in a Map", "ognl": false, "suffix": "}" },
- "xpath(input,exp)": { "index": 114, "kind": "function", "displayName":
"XPath", "group": "xml", "label": "xml", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optional), you ca [...]
+ "val(exp)": { "index": 111, "kind": "function", "displayName": "Value",
"group": "core", "label": "core", "required": false, "javaType": "Object",
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false,
"secret": false, "description": "Returns the expression as a constant value",
"ognl": false, "suffix": "}" },
+ "variable.name": { "index": 112, "kind": "function", "displayName":
"Variable", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "The variable with the
given name", "ognl": true, "suffix": "}" },
+ "variableAs(key,type)": { "index": 113, "kind": "function", "displayName":
"Variable As", "group": "core", "label": "core", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Converts the variable to
the given type (classname).", "ognl": false, "suffix": "}" },
+ "variables": { "index": 114, "kind": "function", "displayName":
"Variables", "group": "core", "label": "core", "required": false, "javaType":
"java.util.Map", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "Returns all the variables
from the current Exchange in a Map", "ognl": false, "suffix": "}" },
+ "xpath(input,exp)": { "index": 115, "kind": "function", "displayName":
"XPath", "group": "xml", "label": "xml", "required": false, "javaType":
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "",
"autowired": false, "secret": false, "description": "When working with XML
data, then this allows using the XPath language, for example, to extract data
from the message body (in XML format). This requires having camel-xpath JAR on
the classpath. For input (optional), you ca [...]
}
}
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 cc971b83f780..3d02ba4c3763 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
@@ -186,6 +186,7 @@ to access Camel functionality and content of the message
being routed.
|`stepId` | `String` | Returns the id of the current step the `Exchange` is
being routed. Returns `null` if there are no steps.
|`throwException(type,msg)` | `Exception` | Deliberately throws an error. Uses
`IllegalArgumentException` by default if no type is specified (use fully
qualified classname).
|`type:name.field` | `Object` | To refer to a type or field by its fully
qualified classname. For example: `type:org.apache.camel.Exchange.FILE_NAME`.
+|`val(exp)` | `Object` |
|`variable.key` | `Object` | To look up the variable with the given key.
|`variable.key._OGNL_` | `Object` | To look up the variable with the given key
and then invoke Camel _OGNL syntax_.
|`variable[key]` | `Object` | *Deprecated* To look up the variable with the
given key.
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
index a408692a33fb..5d2accbbdefa 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
@@ -450,6 +450,10 @@ public final class SimpleConstants {
label = "other", javaType = "String", displayName = "Generate
UUID")
public static final String UUID = "uuid(type)";
+ @Metadata(description = "Returns the expression as a constant value",
+ label = "core", javaType = "Object", displayName = "Value")
+ public static final String VAL = "val(exp)";
+
@Metadata(description = "The variable with the given name", label =
"core,ognl", javaType = "Object")
public static final String VARIABLE = "variable.name";
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 0541b094e630..7b56bdf513db 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
@@ -1317,6 +1317,19 @@ public class SimpleFunctionExpression extends
LiteralExpression {
return SimpleExpressionBuilder.trimExpression(exp);
}
+ // val function
+ remainder = ifStartsWithReturnRemainder("val(", function);
+ if (remainder != null) {
+ String exp = null;
+ String value = StringHelper.beforeLast(remainder, ")");
+ if (value == null || ObjectHelper.isEmpty(value)) {
+ throw new SimpleParserException(
+ "Valid syntax: ${val(exp)} was: " + function,
+ token.getIndex());
+ }
+ return ExpressionBuilder.simpleExpression(value);
+ }
+
// capitalize
remainder = ifStartsWithReturnRemainder("capitalize(", function);
if (remainder != null) {
@@ -3231,6 +3244,21 @@ public class SimpleFunctionExpression extends
LiteralExpression {
return "Object o = " + exp + ";\n return trim(exchange,
o);";
}
+ // val function
+ remainder = ifStartsWithReturnRemainder("val(", function);
+ if (remainder != null) {
+ String values = StringHelper.beforeLast(remainder, ")");
+ if (values == null || ObjectHelper.isEmpty(values)) {
+ throw new SimpleParserException(
+ "Valid syntax: ${val(exp)} was: " + function,
+ token.getIndex());
+ }
+ String s = values;
+ s = StringHelper.removeLeadingAndEndingQuotes(s);
+ s = StringQuoteHelper.doubleQuote(s);
+ return "Object o = " + s + ";\n return o;";
+ }
+
// isEmpty function
remainder = ifStartsWithReturnRemainder("isEmpty(", function);
if (remainder != null) {
diff --git
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockTest.java
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockTest.java
index 2af7bc087c1e..cae5757d4afd 100644
---
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockTest.java
@@ -16,10 +16,13 @@
*/
package org.apache.camel.language.simple;
+import org.apache.camel.Expression;
import org.apache.camel.LanguageTestSupport;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
public class SimpleInitBlockTest extends LanguageTestSupport {
private static final String INIT = """
@@ -106,6 +109,42 @@ public class SimpleInitBlockTest extends
LanguageTestSupport {
assertExpression(exchange, INIT4, "orderId=123,total=208\n");
}
+ @Test
+ public void testInitBlockAverageFunction() {
+ String exp = """
+ $init{
+ $a := ${body}
+ $b := ${header.foo}
+ $c := ${header.bar}
+ }init$
+ average: ${average($a,$b,$c)}
+ """;
+
+ exchange.getMessage().setBody(1);
+ exchange.getMessage().setHeader("foo", 2);
+ exchange.getMessage().setHeader("bar", 3);
+
+ Expression expression =
context.resolveLanguage("simple").createExpression(exp);
+ String s = expression.evaluate(exchange, String.class);
+ assertEquals("average: 2\n", s);
+ }
+
+ @Test
+ public void testInitBlockAverageVal() {
+ String exp = """
+ $init{
+ $a := ${val(4)}
+ $b := ${val(5)}
+ $c := ${val(6)}
+ }init$
+ average: ${average($a,$b,$c)}
+ """;
+
+ Expression expression =
context.resolveLanguage("simple").createExpression(exp);
+ String s = expression.evaluate(exchange, String.class);
+ assertEquals("average: 5\n", s);
+ }
+
@Override
protected String getLanguageName() {
return "simple";
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 b6554b08653d..cc92d6dfc9ac 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
@@ -3193,6 +3193,10 @@ public class SimpleTest extends LanguageTestSupport {
s = expression.evaluate(exchange, String.class);
assertEquals("Hello World", s);
+ expression =
context.resolveLanguage("simple").createExpression("${concat('a','b')}");
+ s = expression.evaluate(exchange, String.class);
+ assertEquals("ab", s);
+
expression =
context.resolveLanguage("simple").createExpression("${concat(${body}, 'World',
'_')}");
s = expression.evaluate(exchange, String.class);
assertEquals("Hello_World", s);
@@ -3301,6 +3305,24 @@ public class SimpleTest extends LanguageTestSupport {
assertEquals("Hi Camel", out);
}
+ @Test
+ public void testVal() {
+ exchange.getMessage().setBody(123);
+
+ Expression expression =
context.resolveLanguage("simple").createExpression("${val(abc)}");
+ String s = expression.evaluate(exchange, String.class);
+ assertEquals("abc", s);
+
+ expression =
context.resolveLanguage("simple").createExpression("${val(${body})}");
+ s = expression.evaluate(exchange, String.class);
+ assertEquals("123", s);
+
+ expression =
context.resolveLanguage("simple").createExpression("${val(${body})}");
+ Object obj = expression.evaluate(exchange, Object.class);
+ assertIsInstanceOf(Integer.class, obj);
+ assertEquals(123, obj);
+ }
+
@Test
public void testSetHeader() {
exchange.getMessage().setBody("Hello World");
diff --git
a/core/camel-util/src/main/java/org/apache/camel/util/SimpleUtils.java
b/core/camel-util/src/main/java/org/apache/camel/util/SimpleUtils.java
index 2f477a1ada86..ec9922efcbcd 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/SimpleUtils.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/SimpleUtils.java
@@ -135,6 +135,7 @@ public class SimpleUtils {
"unquote",
"uppercase",
"uuid",
+ "val",
"variable",
"variableas",
"variables",