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 404cce386a9c CAMEL-22899: camel-core - Simple language chain operator 
to support  for explicit declaring input parameter position
404cce386a9c is described below

commit 404cce386a9c9c62d5de5c890e81191294e3612d
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jan 29 16:19:50 2026 +0100

    CAMEL-22899: camel-core - Simple language chain operator to support  for 
explicit declaring input parameter position
---
 .../modules/languages/pages/simple-language.adoc   | 22 +++++++++--
 .../camel/language/simple/ast/ChainExpression.java | 45 +++++++++++++++++++++-
 .../camel/language/simple/SimpleOperatorTest.java  | 11 ++++++
 3 files changed, 73 insertions(+), 5 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 ba44eb8dee2a..6cbc590598de 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
@@ -867,9 +867,6 @@ simple("${header.username} ?: 'Guest'");
 
 ==== Chain Operator
 
-IMPORTANT: The chain operator only supports passing results via the message 
body. This may change in the future to allow more flexible syntax to
-specify which parameter to use as input in the next fuction.
-
 The syntax for the chain operator is:
 
 [source,text]
@@ -895,6 +892,25 @@ The _null safe_ variant (`?~>`) can be used to avoid 
`NullPointerException` if i
 
 However, many of the simple functions have NPE protection built-in, so this 
variant is only needed in special situations.
 
+==== Using $param as input parameter value
+
+IMPORTANT: The chain operator will by default pass results via the message 
body. This usually works well with most functions.
+However, when you need to be in full control then use `$param` as the magic 
parameter which represents the passed value from the previous function in the 
chain.
+
+Suppose the message body contains `"   Hello World from the Camel "` then the 
following chain works out of the box:
+
+[source,java]
+----
+simple("${trim()} ~> ${replace('Hello','Hi')} ~> ${split(' ')} ~> ${size()}");
+----
+
+And here is the same example where we explicit use `$param` in the parameters 
where we need the input to be:
+
+[source,java]
+----
+simple("${trim()} ~> ${replace('Hello','Hi',$param)} ~> ${split($param,' ')} 
~> ${size($param)}");
+----
+
 
 === Boolean Operators
 
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/ChainExpression.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/ChainExpression.java
index 955843346854..fcbcb64d6977 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/ChainExpression.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/ChainExpression.java
@@ -27,6 +27,7 @@ import org.apache.camel.language.simple.BaseSimpleParser;
 import org.apache.camel.language.simple.types.ChainOperatorType;
 import org.apache.camel.language.simple.types.SimpleParserException;
 import org.apache.camel.language.simple.types.SimpleToken;
+import org.apache.camel.support.ExpressionAdapter;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 
@@ -35,6 +36,8 @@ import org.apache.camel.util.StringHelper;
  */
 public class ChainExpression extends BaseSimpleNode {
 
+    private static final String CHAIN_VARIABLE = "CamelSimpleChainParam";
+
     private final ChainOperatorType operator;
     private SimpleNode left;
     private final List<SimpleNode> right = new ArrayList<>();
@@ -86,15 +89,53 @@ public class ChainExpression extends BaseSimpleNode {
 
         final List<Expression> rightExp = new ArrayList<>();
         for (SimpleNode rn : right) {
+            boolean param = false;
             if (rn instanceof LiteralExpression le) {
                 String text = le.getText();
                 String changed = 
StringHelper.removeLeadingAndEndingQuotes(text);
+                if (changed.contains("$param")) {
+                    changed = changed.replace("$param", "${variable." + 
CHAIN_VARIABLE + "}");
+                    param = true;
+                }
                 if (!changed.equals(text)) {
                     le.replaceText(changed);
                 }
+            } else if (rn instanceof SimpleFunctionStart sf) {
+                for (var child : sf.getBlock().getChildren()) {
+                    if (child instanceof LiteralExpression le) {
+                        String text = le.getText();
+                        String changed = 
StringHelper.removeLeadingAndEndingQuotes(text);
+                        if (changed.contains("$param")) {
+                            changed = changed.replace("$param", "${variable." 
+ CHAIN_VARIABLE + "}");
+                            param = true;
+                        }
+                        if (!changed.equals(text)) {
+                            le.replaceText(changed);
+                        }
+                    }
+                }
+            }
+            final Expression exp = rn.createExpression(camelContext, 
expression);
+            Expression target = exp;
+            if (param) {
+                target = new ExpressionAdapter() {
+                    @Override
+                    public Object evaluate(Exchange exchange) {
+                        exchange.setVariable(CHAIN_VARIABLE, 
exchange.getMessage().getBody());
+                        try {
+                            return exp.evaluate(exchange, Object.class);
+                        } finally {
+                            exchange.removeVariable(CHAIN_VARIABLE);
+                        }
+                    }
+
+                    @Override
+                    public String toString() {
+                        return exp.toString();
+                    }
+                };
             }
-            Expression exp = rn.createExpression(camelContext, expression);
-            rightExp.add(exp);
+            rightExp.add(target);
         }
 
         if (operator == ChainOperatorType.CHAIN || operator == 
ChainOperatorType.CHAIN_NULL_SAFE) {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
index 5effdce5234d..cb8807a94108 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleOperatorTest.java
@@ -951,6 +951,17 @@ public class SimpleOperatorTest extends 
LanguageTestSupport {
         assertTrue(matches);
     }
 
+    @Test
+    public void testChainParam() {
+        exchange.getIn().setBody("   Hello World from the Camel   ");
+        // no param
+        assertExpression("${trim()} ~> ${replace('Hello','Hi')}", "Hi World 
from the Camel");
+        assertExpression("${trim()} ~> ${replace('Hello','Hi')} ~> ${split(' 
')} ~> ${size()}", 5);
+        // with $param
+        assertExpression("${trim()} ~> ${replace('Hello','Hi',$param)}", "Hi 
World from the Camel");
+        assertExpression("${trim()} ~> ${replace('Hello','Hi',$param)} ~> 
${split($param,' ')} ~> ${size($param)}", 5);
+    }
+
     @Override
     protected String getLanguageName() {
         return "simple";

Reply via email to