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

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

commit 319bdee4748eb7b10458cba04d99377876014dfc
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jan 30 11:37:27 2026 +0100

    CAMEL-22899: camel-core - Simple language - Add custom function in init 
block via chains
---
 .../modules/languages/pages/simple-language.adoc   | 11 ++++++-
 .../simple/DefaultSimpleFunctionRegistry.java      | 16 ++++++++-
 .../language/simple/SimpleExpressionBuilder.java   | 38 ++++++++++++++++++++++
 .../language/simple/SimpleExpressionParser.java    |  3 ++
 .../simple/ast/SimpleFunctionExpression.java       | 23 +++++++++++++
 .../language/simple/SimpleInitBlockChainTest.java  | 15 +++++++++
 6 files changed, 104 insertions(+), 2 deletions(-)

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 827e990751dd..ef750015a187 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
@@ -1272,6 +1272,8 @@ $init{
 }init$
 ----
 
+NOTE: You cannot declare custom functions that call other function functions. 
This is currently not supported.
+
 The function will by default use the message body as the input, such that the 
following:
 
 [source,java]
@@ -1281,7 +1283,14 @@ simple("Incoming message: $cleanUp()");
 
 Would then call the _clean_ function with the message body as the input, which 
will then be used for trim, normalize and upper-casing.
 
-NOTE: You cannot declare custom functions that call other function functions. 
This is currently not supported.
+A custom function can also use a **single** parameter, however then the syntax 
must use `${name(...)}` style, such as:
+
+[source,java]
+----
+simple("Incoming message: ${cleanUp('  Please   clean  this   text for    me 
')}");
+----
+
+Here the parameter is a fixed `String` but you can also pass in other type of 
value such as a number, boolean, or even a nested function.
 
 
 == OGNL Expression Support
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/DefaultSimpleFunctionRegistry.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/DefaultSimpleFunctionRegistry.java
index f7227c936d85..cb351b103b50 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/DefaultSimpleFunctionRegistry.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/DefaultSimpleFunctionRegistry.java
@@ -19,16 +19,30 @@ package org.apache.camel.language.simple;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.Expression;
 import org.apache.camel.NonManagedService;
 import org.apache.camel.support.service.ServiceSupport;
 
-public class DefaultSimpleFunctionRegistry extends ServiceSupport implements 
SimpleFunctionRegistry, NonManagedService {
+public class DefaultSimpleFunctionRegistry extends ServiceSupport implements 
CamelContextAware, SimpleFunctionRegistry, NonManagedService {
 
     private final Map<String, Expression> functions = new 
ConcurrentHashMap<>();
+    private CamelContext camelContext;
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
 
     @Override
     public void addFunction(String name, Expression expression) {
+        expression.init(camelContext);
         functions.put(name, 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 f99ac465b254..e132ce47751f 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
@@ -2863,6 +2863,44 @@ public final class SimpleExpressionBuilder {
         };
     }
 
+    public static Expression customFunction(final String name, final String 
parameter) {
+        return new ExpressionAdapter() {
+            private Expression func;
+            private Expression exp;
+
+            @Override
+            public void init(CamelContext context) {
+                super.init(context);
+                SimpleFunctionRegistry registry
+                        = 
context.getCamelContextExtension().getContextPlugin(SimpleFunctionRegistry.class);
+                func = registry.getFunction(name);
+                if (func == null) {
+                    throw new IllegalArgumentException("No custom simple 
function with name: " + name);
+                }
+                exp = ExpressionBuilder.simpleExpression(parameter);
+            }
+
+            @Override
+            public Object evaluate(Exchange exchange) {
+                final Object originalBody = exchange.getMessage().getBody();
+                try {
+                    Object input = exp.evaluate(exchange, Object.class);
+                    if (input != null) {
+                        exchange.getMessage().setBody(input);
+                        return func.evaluate(exchange, Object.class);
+                    }
+                    return null;
+                } finally {
+                    exchange.getMessage().setBody(originalBody);
+                }
+            }
+
+            public String toString() {
+                return "function(" + name + ")";
+            }
+        };
+    }
+
     /**
      * Expression adapter for OGNL expression from Message Header or Exchange 
property
      */
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
index 347ddb58f63a..c0771c6de995 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionParser.java
@@ -95,7 +95,10 @@ public class SimpleExpressionParser extends BaseSimpleParser 
{
                 }
                 // use $$key() as local function in the expression afterwards
                 for (String key : initParser.getInitFunctions()) {
+                    // no-arg functions
                     this.expression = this.expression.replace("$" + key + 
"()", "${function." + key + "}");
+                    // arg functions
+                    this.expression = this.expression.replace("${" + key + 
"(", "${function(" + key + ",");
                 }
             }
 
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 d0ea95103ac3..5df606606e8e 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
@@ -620,6 +620,29 @@ public class SimpleFunctionExpression extends 
LiteralExpression {
             return answer;
         }
 
+        remainder = ifStartsWithReturnRemainder("function(", function);
+        if (remainder != null) {
+            String key;
+            String param;
+            String values = StringHelper.beforeLast(remainder, ")");
+            if (values == null || ObjectHelper.isEmpty(values)) {
+                throw new SimpleParserException(
+                        "Valid syntax: ${function(key,exp)} was: " + function,
+                        token.getIndex());
+            }
+            String[] tokens = StringQuoteHelper.splitSafeQuote(values, ',', 
true, true);
+            if (tokens.length != 2) {
+                throw new SimpleParserException(
+                        "Valid syntax: ${function(key,exp)} was: " + function,
+                        token.getIndex());
+            }
+            key = StringHelper.removeQuotes(tokens[0]);
+            key = key.trim();
+            param = tokens[1];
+            param = StringHelper.removeLeadingAndEndingQuotes(param.trim());
+            return SimpleExpressionBuilder.customFunction(key, param);
+        }
+
         return null;
     }
 
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockChainTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockChainTest.java
index 0eb4f44c59f0..6f2b5170cda2 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockChainTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleInitBlockChainTest.java
@@ -36,6 +36,14 @@ public class SimpleInitBlockChainTest extends 
LanguageTestSupport {
             You said: $clean() in $count() words
             """;
 
+    private static final String INIT3 = """
+            $init{
+              $clean ~:= ${trim()} ~> ${normalizeWhitespace()} ~> 
${uppercase()}
+            }init$
+            You said: ${clean('  Clean this text  please ...    ')} and then 
do something else
+            """;
+
+
     @Test
     public void testInitBlockChain() throws Exception {
         exchange.getMessage().setBody("   Hello  big   World      ");
@@ -50,6 +58,13 @@ public class SimpleInitBlockChainTest extends 
LanguageTestSupport {
         assertExpression(exchange, INIT2, "You said: HELLO BIG WORLD in 3 
words\n");
     }
 
+    @Test
+    public void testInitBlockChain3() throws Exception {
+        exchange.getMessage().setBody("Hello World");
+
+        assertExpression(exchange, INIT3, "You said: CLEAN THIS TEXT PLEASE 
... and then do something else\n");
+    }
+
     @Override
     protected String getLanguageName() {
         return "simple";

Reply via email to