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 ba5fe898dc3f CAMEL-22868: camel-core - Add not variant to startsWith
and endsWith operator in simple language (#20862)
ba5fe898dc3f is described below
commit ba5fe898dc3f4422ba53afa6224a823074363de0
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Jan 17 18:05:37 2026 +0100
CAMEL-22868: camel-core - Add not variant to startsWith and endsWith
operator in simple language (#20862)
---
.../csimple/joor/OriginalSimpleOperatorTest.java | 27 ++++++++++++++++++++++
.../modules/languages/pages/simple-language.adoc | 13 ++++++-----
.../camel/language/simple/SimpleTokenizer.java | 20 ++++++++--------
.../language/simple/ast/BinaryExpression.java | 10 ++++++++
.../language/simple/types/BinaryOperatorType.java | 16 ++++++++++---
.../camel/language/simple/SimpleOperatorTest.java | 27 ++++++++++++++++++++++
6 files changed, 95 insertions(+), 18 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 51f1cef4ec9a..9e11a8ed20fd 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
@@ -761,6 +761,20 @@ public class OriginalSimpleOperatorTest extends
LanguageTestSupport {
assertPredicate("${in.body} startsWith 'Hi'", false);
}
+ @Test
+ public void testNotStartsWith() {
+ exchange.getIn().setBody("Hello there");
+ assertPredicate("${in.body} !startsWith 'Bye'", true);
+ assertPredicate("${in.body} !startsWith 'Hello'", false);
+ assertPredicate("${in.body} !startsWith 'B'", true);
+ assertPredicate("${in.body} !startsWith 'H'", false);
+ assertPredicate("${in.body} !startsWith 'Bye there'", true);
+ assertPredicate("${in.body} !startsWith 'Hello there'", false);
+ assertPredicate("${in.body} !startsWith 'Hello ther'", false);
+ assertPredicate("${in.body} !startsWith 'ello there'", true);
+ assertPredicate("${in.body} !startsWith 'Hi'", true);
+ }
+
@Test
public void testEndsWith() {
exchange.getIn().setBody("Hello there");
@@ -778,6 +792,19 @@ public class OriginalSimpleOperatorTest extends
LanguageTestSupport {
assertPredicate("${in.body} endsWith 'Hi'", false);
}
+ @Test
+ public void testNotEndsWith() {
+ exchange.getIn().setBody("Hello there");
+ assertPredicate("${in.body} !endsWith 'B'", true);
+ assertPredicate("${in.body} !endsWith 'world'", true);
+ assertPredicate("${in.body} !endsWith 'there'", false);
+ assertPredicate("${in.body} !endsWith 're'", false);
+ assertPredicate("${in.body} !endsWith ' there'", false);
+ assertPredicate("${in.body} !endsWith 'Hello there'", false);
+ assertPredicate("${in.body} !endsWith 'Hello ther'", true);
+ assertPredicate("${in.body} !endsWith 'Hi'", true);
+ }
+
@Override
protected String getLanguageName() {
return "csimple";
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 f8bacd5dfa01..1be00ca5da83 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
@@ -629,16 +629,17 @@ is a set of four values with an empty value and then the
three medals.
|!is |For matching if the left-hand side type is not an instance of the value.
|range |For matching if the left-hand side is within a range of values defined
-as numbers: `from..to`..
+as numbers: `from..to`.
|!range |For matching if the left-hand side is not within a range of values
-defined as numbers: `from..to`. .
+defined as numbers: `from..to`.
-|startsWith |For testing if the left-hand side string starts
-with the right-hand string.
+|startsWith |For testing if the left-hand side string starts with the
right-hand string.
+|!startsWith |For testing if the left-hand side string does not start with the
right-hand string.
+
+|endsWith |For testing if the left-hand side string ends with the right-hand
string.
+|!endsWith |For testing if the left-hand side string does not end with the
right-hand string.
-|endsWith |For testing if the left-hand side string ends with
-the right-hand string.
|===
And the following unary operators can be used:
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleTokenizer.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleTokenizer.java
index 506e07fbfa0b..bbaf198ab832 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleTokenizer.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleTokenizer.java
@@ -27,7 +27,7 @@ import org.apache.camel.util.ObjectHelper;
public final class SimpleTokenizer {
// keep this number in sync with tokens list
- private static final int NUMBER_OF_TOKENS = 47;
+ private static final int NUMBER_OF_TOKENS = 49;
private static final SimpleTokenType[] KNOWN_TOKENS = new
SimpleTokenType[NUMBER_OF_TOKENS];
@@ -79,22 +79,24 @@ public final class SimpleTokenizer {
KNOWN_TOKENS[36] = new SimpleTokenType(TokenType.binaryOperator,
"!range");
KNOWN_TOKENS[37] = new SimpleTokenType(TokenType.binaryOperator,
"range");
KNOWN_TOKENS[38] = new SimpleTokenType(TokenType.binaryOperator,
"startsWith");
- KNOWN_TOKENS[39] = new SimpleTokenType(TokenType.binaryOperator,
"starts with"); // deprecated
- KNOWN_TOKENS[40] = new SimpleTokenType(TokenType.binaryOperator,
"endsWith");
- KNOWN_TOKENS[41] = new SimpleTokenType(TokenType.binaryOperator, "ends
with"); // deprecated
+ KNOWN_TOKENS[39] = new SimpleTokenType(TokenType.binaryOperator,
"starts with");
+ KNOWN_TOKENS[40] = new SimpleTokenType(TokenType.binaryOperator,
"!startsWith");
+ KNOWN_TOKENS[41] = new SimpleTokenType(TokenType.binaryOperator,
"endsWith");
+ KNOWN_TOKENS[42] = new SimpleTokenType(TokenType.binaryOperator, "ends
with");
+ KNOWN_TOKENS[43] = new SimpleTokenType(TokenType.binaryOperator,
"!endsWith");
// unary operators
- KNOWN_TOKENS[42] = new SimpleTokenType(TokenType.unaryOperator, "++");
- KNOWN_TOKENS[43] = new SimpleTokenType(TokenType.unaryOperator, "--");
+ KNOWN_TOKENS[44] = new SimpleTokenType(TokenType.unaryOperator, "++");
+ KNOWN_TOKENS[45] = new SimpleTokenType(TokenType.unaryOperator, "--");
// logical operators
- KNOWN_TOKENS[44] = new SimpleTokenType(TokenType.logicalOperator,
"&&");
- KNOWN_TOKENS[45] = new SimpleTokenType(TokenType.logicalOperator,
"||");
+ KNOWN_TOKENS[46] = new SimpleTokenType(TokenType.logicalOperator,
"&&");
+ KNOWN_TOKENS[47] = new SimpleTokenType(TokenType.logicalOperator,
"||");
//binary operator
// it is added as the last item because unary -- has the priority
// if unary not found it is highly possible - operator is run into.
- KNOWN_TOKENS[46] = new SimpleTokenType(TokenType.minusValue, "-");
+ KNOWN_TOKENS[48] = new SimpleTokenType(TokenType.minusValue, "-");
}
private SimpleTokenizer() {
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java
index 64fec4a9d5b4..559ad32bc6be 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/BinaryExpression.java
@@ -127,8 +127,14 @@ public class BinaryExpression extends BaseSimpleNode {
return createRangeExpression(camelContext, expression, leftExp,
rightExp);
} else if (operator == BinaryOperatorType.STARTS_WITH) {
return createExpression(camelContext, leftExp, rightExp,
PredicateBuilder.startsWith(leftExp, rightExp));
+ } else if (operator == BinaryOperatorType.NOT_STARTS_WITH) {
+ return createExpression(camelContext, leftExp, rightExp,
+ PredicateBuilder.not(PredicateBuilder.startsWith(leftExp,
rightExp)));
} else if (operator == BinaryOperatorType.ENDS_WITH) {
return createExpression(camelContext, leftExp, rightExp,
PredicateBuilder.endsWith(leftExp, rightExp));
+ } else if (operator == BinaryOperatorType.NOT_ENDS_WITH) {
+ return createExpression(camelContext, leftExp, rightExp,
+ PredicateBuilder.not(PredicateBuilder.endsWith(leftExp,
rightExp)));
}
throw new SimpleParserException("Unknown binary operator " + operator,
token.getIndex());
@@ -351,8 +357,12 @@ public class BinaryExpression extends BaseSimpleNode {
return "!range(exchange, " + leftExp + ", " + rightExp + ")";
} else if (operator == BinaryOperatorType.STARTS_WITH) {
return "startsWith(exchange, " + leftExp + ", " + rightExp + ")";
+ } else if (operator == BinaryOperatorType.NOT_STARTS_WITH) {
+ return "!startsWith(exchange, " + leftExp + ", " + rightExp + ")";
} else if (operator == BinaryOperatorType.ENDS_WITH) {
return "endsWith(exchange, " + leftExp + ", " + rightExp + ")";
+ } else if (operator == BinaryOperatorType.NOT_ENDS_WITH) {
+ return "!endsWith(exchange, " + leftExp + ", " + rightExp + ")";
}
throw new SimpleParserException("Unknown binary operator " + operator,
token.getIndex());
diff --git
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/types/BinaryOperatorType.java
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/types/BinaryOperatorType.java
index c0b8dca08267..fb82fc584a0e 100644
---
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/types/BinaryOperatorType.java
+++
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/types/BinaryOperatorType.java
@@ -45,7 +45,9 @@ public enum BinaryOperatorType {
RANGE,
NOT_RANGE,
STARTS_WITH,
- ENDS_WITH;
+ NOT_STARTS_WITH,
+ ENDS_WITH,
+ NOT_ENDS_WITH;
private static final Logger LOG =
LoggerFactory.getLogger(BinaryOperatorType.class);
@@ -115,6 +117,10 @@ public enum BinaryOperatorType {
} else if ("ends with".equals(text)) {
LOG.warn("Simple operator `ends with` is deprecated, use
`endsWith` instead");
return ENDS_WITH;
+ } else if ("!startsWith".equals(text)) {
+ return NOT_STARTS_WITH;
+ } else if ("!endsWith".equals(text)) {
+ return NOT_ENDS_WITH;
}
throw new IllegalArgumentException("Operator not supported: " + text);
}
@@ -162,8 +168,12 @@ public enum BinaryOperatorType {
return "!range";
} else if (operator == STARTS_WITH) {
return "startsWith";
+ } else if (operator == NOT_STARTS_WITH) {
+ return "!startsWith";
} else if (operator == ENDS_WITH) {
return "endsWith";
+ } else if (operator == NOT_ENDS_WITH) {
+ return "!endsWith";
}
return "";
}
@@ -264,9 +274,9 @@ public enum BinaryOperatorType {
return new ParameterType[] { ParameterType.LiteralWithFunction,
ParameterType.Function };
} else if (operator == NOT_RANGE) {
return new ParameterType[] { ParameterType.LiteralWithFunction,
ParameterType.Function };
- } else if (operator == STARTS_WITH) {
+ } else if (operator == STARTS_WITH || operator == NOT_STARTS_WITH) {
return null;
- } else if (operator == ENDS_WITH) {
+ } else if (operator == ENDS_WITH || operator == NOT_ENDS_WITH) {
return null;
}
return null;
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 b0973f552e87..8360f656447e 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
@@ -783,6 +783,20 @@ public class SimpleOperatorTest extends
LanguageTestSupport {
assertPredicate("${in.body} starts with 01234", false);
}
+ @Test
+ public void testNotStartsWith() {
+ exchange.getIn().setBody("Hello there");
+ assertPredicate("${in.body} !startsWith 'Bye'", true);
+ assertPredicate("${in.body} !startsWith 'Hello'", false);
+ assertPredicate("${in.body} !startsWith 'B'", true);
+ assertPredicate("${in.body} !startsWith 'H'", false);
+ assertPredicate("${in.body} !startsWith 'Bye there'", true);
+ assertPredicate("${in.body} !startsWith 'Hello there'", false);
+ assertPredicate("${in.body} !startsWith 'Hello ther'", false);
+ assertPredicate("${in.body} !startsWith 'ello there'", true);
+ assertPredicate("${in.body} !startsWith 'Hi'", true);
+ }
+
@Test
public void testEndsWith() {
exchange.getIn().setBody("Hello there");
@@ -800,6 +814,19 @@ public class SimpleOperatorTest extends
LanguageTestSupport {
assertPredicate("${in.body} endsWith 'Hi'", false);
}
+ @Test
+ public void testNotEndsWith() {
+ exchange.getIn().setBody("Hello there");
+ assertPredicate("${in.body} !endsWith 'B'", true);
+ assertPredicate("${in.body} !endsWith 'world'", true);
+ assertPredicate("${in.body} !endsWith 'there'", false);
+ assertPredicate("${in.body} !endsWith 're'", false);
+ assertPredicate("${in.body} !endsWith ' there'", false);
+ assertPredicate("${in.body} !endsWith 'Hello there'", false);
+ assertPredicate("${in.body} !endsWith 'Hello ther'", true);
+ assertPredicate("${in.body} !endsWith 'Hi'", true);
+ }
+
@Override
protected String getLanguageName() {
return "simple";