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