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

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


The following commit(s) were added to refs/heads/camel-4.18.x by this push:
     new 60635125566c CAMEL-23035: camel-core - Simple language using colon or 
question mark can conflict with ternary operator
60635125566c is described below

commit 60635125566c74089d1ccc28e054894549c1a6e4
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Feb 19 15:22:46 2026 +0100

    CAMEL-23035: camel-core - Simple language using colon or question mark can 
conflict with ternary operator
---
 .../csimple/joor/OriginalSimpleOperatorTest.java   | 18 ++++++++
 .../language/csimple/joor/OriginalSimpleTest.java  | 14 ++----
 .../language/simple/SimpleExpressionParser.java    | 52 +++-------------------
 .../camel/language/simple/SimpleOperatorTest.java  | 11 +++++
 4 files changed, 39 insertions(+), 56 deletions(-)

diff --git 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
index 36cf952228ae..6a4aef11970d 100644
--- 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
+++ 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleOperatorTest.java
@@ -806,6 +806,24 @@ public class OriginalSimpleOperatorTest extends 
LanguageTestSupport {
         assertExpression("${body} ?: 'World'", 1);
     }
 
+    @Test
+    public void testTernaryLog() {
+        exchange.getIn().setBody("Hello World");
+        assertExpression(">>> Message received from WebSocket Client : 
${body}",
+                ">>> Message received from WebSocket Client : Hello World");
+
+        exchange.getMessage().setHeader(Exchange.FILE_NAME, "foo.txt");
+        assertExpression("This is a test bug ${header.CamelFileName}",
+                "This is a test bug foo.txt");
+
+        assertExpression("This is a test bug : ${header.CamelFileName}",
+                "This is a test bug : foo.txt");
+
+        assertExpression("This is a test bug ? ${header.CamelFileName}",
+                "This is a test bug ? foo.txt");
+
+    }
+
     @Override
     protected String getLanguageName() {
         return "csimple";
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 72654454ef82..27fe37ac8efb 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
@@ -2938,10 +2938,10 @@ public class OriginalSimpleTest extends 
LanguageTestSupport {
         // Test with body
         exchange.getIn().setBody("Hello World");
         exchange.getIn().setHeader("foo", 44);
-        assertExpression("${header.foo > 0 ? ${body} : 'Bye World'}", "Hello 
World");
+        assertExpression("${header.foo > 0 ? body : 'Bye World'}", "Hello 
World");
         exchange.getIn().setHeader("foo", -123);
-        assertExpression("${header.foo > 0 ? ${body} : 'Bye World'}", "Bye 
World");
-        assertExpression("${header.foo > 0 ? ${body} : ${null}}", null);
+        assertExpression("${header.foo > 0 ? body : 'Bye World'}", "Bye 
World");
+        assertExpression("${header.foo > 0 ? body : null}", null);
 
         // Test with file name
         exchange.getIn().setHeader("CamelFileName", "testfile.txt");
@@ -2981,13 +2981,7 @@ public class OriginalSimpleTest extends 
LanguageTestSupport {
 
     @Test
     public void testTernaryOperatorNested() {
-        // Nested ternary operators
-        exchange.getIn().setHeader("score", 95);
-        assertExpression("${header.score >= 90 ? 'A' : ${header.score} >= 80 ? 
'B' : 'C'}", "A");
-        exchange.getIn().setHeader("score", 85);
-        assertExpression("${header.score >= 90 ? 'A' : ${header.score} >= 80 ? 
'B' : 'C'}", "B");
-        exchange.getIn().setHeader("score", 75);
-        assertExpression("${header.score >= 90 ? 'A' : ${header.score} >= 80 ? 
'B' : 'C'}", "C");
+        // not supported in csimple
     }
 
     @Test
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 cc902f066a5a..5ff3b4c4ec0c 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
@@ -31,7 +31,6 @@ import org.apache.camel.language.simple.ast.OtherExpression;
 import org.apache.camel.language.simple.ast.SimpleFunctionEnd;
 import org.apache.camel.language.simple.ast.SimpleFunctionStart;
 import org.apache.camel.language.simple.ast.SimpleNode;
-import org.apache.camel.language.simple.ast.TernaryExpression;
 import org.apache.camel.language.simple.ast.UnaryExpression;
 import org.apache.camel.language.simple.types.ChainOperatorType;
 import org.apache.camel.language.simple.types.OtherOperatorType;
@@ -143,11 +142,10 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
         // parse the expression using the following grammar
         nextToken();
         while (!token.getType().isEol()) {
-            // an expression supports just template (eg text), functions, 
unary, ternary, or other operator
+            // an expression supports just template (eg text), functions, 
unary, or other operator
             templateText();
             functionText();
             unaryOperator();
-            ternaryOperator();
             chainOperator();
             otherOperator();
             nextToken();
@@ -165,8 +163,6 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
         prepareBlocks();
         // compact and stack unary operators
         prepareUnaryExpressions();
-        // compact and stack ternary expressions
-        prepareTernaryExpressions();
         // compact and stack chain expressions
         prepareChainExpression();
         // compact and stack other expressions
@@ -248,7 +244,6 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
 
         // counter to keep track of number of functions in the tokens
         AtomicInteger functions = new AtomicInteger();
-        AtomicInteger ternary = new AtomicInteger();
 
         LiteralNode imageToken = null;
         for (SimpleToken token : tokens) {
@@ -258,7 +253,7 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
             }
 
             // create a node from the token
-            SimpleNode node = createNode(token, functions, ternary);
+            SimpleNode node = createNode(token, functions);
             if (node != null) {
                 // a new token was created so the current image token need to 
be added first
                 if (imageToken != null) {
@@ -285,8 +280,8 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
         }
     }
 
-    private SimpleNode createNode(SimpleToken token, AtomicInteger functions, 
AtomicInteger ternary) {
-        // expression only support functions, unary operators, ternary 
operators, and other operators
+    private SimpleNode createNode(SimpleToken token, AtomicInteger functions) {
+        // expression only support functions, unary operators, operators, and 
other operators
         if (token.getType().isFunctionStart()) {
             // starting a new function
             functions.incrementAndGet();
@@ -300,14 +295,6 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
             if (!nodes.isEmpty() && nodes.get(nodes.size() - 1) instanceof 
SimpleFunctionEnd) {
                 return new UnaryExpression(token);
             }
-        } else if (token.getType().isTernaryStart()) {
-            // starting a new ternary
-            ternary.incrementAndGet();
-            return new TernaryExpression(token);
-        } else if (ternary.get() > 0 && token.getType().isTernaryEnd()) {
-            // there must be a start ternary already, to let this be an end 
ternary
-            ternary.decrementAndGet();
-            return new TernaryExpression(token);
         } else if (token.getType().isChain()) {
             return new ChainExpression(token);
         } else if (token.getType().isOther()) {
@@ -394,9 +381,9 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
     // - other operator = operator attached to both the left and right hand 
side nodes
 
     protected void templateText() {
-        // for template, we accept anything but functions / ternary operator / 
other operator
+        // for template, we accept anything but functions / other operator
         while (!token.getType().isFunctionStart() && 
!token.getType().isFunctionEnd() && !token.getType().isEol()
-                && !token.getType().isTernary() && !token.getType().isOther() 
&& !token.getType().isChain()) {
+                && !token.getType().isOther() && !token.getType().isChain()) {
             nextToken();
         }
     }
@@ -481,33 +468,6 @@ public class SimpleExpressionParser extends 
BaseSimpleParser {
         return false;
     }
 
-    protected boolean ternaryOperator() {
-        if (accept(TokenType.ternaryOperator)) {
-            nextToken();
-            // there should be at least one whitespace after the operator
-            expectAndAcceptMore(TokenType.whiteSpace);
-
-            // then we expect either some quoted text, another function, or a 
numeric, boolean or null value
-            if (singleQuotedLiteralWithFunctionsText()
-                    || doubleQuotedLiteralWithFunctionsText()
-                    || functionText()
-                    || numericValue()
-                    || booleanValue()
-                    || nullValue()) {
-                // then after the right hand side value, there should be a 
whitespace if there is more tokens
-                nextToken();
-                if (!token.getType().isEol()) {
-                    expect(TokenType.whiteSpace);
-                }
-            } else {
-                throw new SimpleParserException(
-                        "Ternary operator does not support token " + token, 
token.getIndex());
-            }
-            return true;
-        }
-        return false;
-    }
-
     protected boolean unaryOperator() {
         if (accept(TokenType.unaryOperator)) {
             nextToken();
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 cb8807a94108..6d123c342f72 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
@@ -895,6 +895,17 @@ public class SimpleOperatorTest extends 
LanguageTestSupport {
         exchange.getIn().setBody("Hello World");
         assertExpression(">>> Message received from WebSocket Client : 
${body}",
                 ">>> Message received from WebSocket Client : Hello World");
+
+        exchange.getMessage().setHeader(Exchange.FILE_NAME, "foo.txt");
+        assertExpression("This is a test bug ${header.CamelFileName}",
+                "This is a test bug foo.txt");
+
+        assertExpression("This is a test bug : ${header.CamelFileName}",
+                "This is a test bug : foo.txt");
+
+        assertExpression("This is a test bug ? ${header.CamelFileName}",
+                "This is a test bug ? foo.txt");
+
     }
 
     @Test

Reply via email to