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

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

commit 245c52d1e90244ff35dac2b4c859356be2853c43
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Jan 17 16:03:15 2026 +0100

    CAMEL-22868: camel-core - Add not variant to startsWith and endsWith 
operator in simple language
---
 .../csimple/joor/OriginalSimpleOperatorTest.java   | 27 ++++++++++++++++++++++
 .../modules/languages/pages/simple-language.adoc   |  8 +++++--
 .../camel/language/simple/SimpleTokenizer.java     | 18 ++++++++-------
 .../language/simple/ast/BinaryExpression.java      | 10 ++++++++
 .../language/simple/types/BinaryOperatorType.java  | 16 ++++++++++---
 .../camel/language/simple/SimpleOperatorTest.java  | 27 ++++++++++++++++++++++
 6 files changed, 93 insertions(+), 13 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 e63ea699d1ea..c913d2881c6d 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,20 +629,24 @@ 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.
 
 |starts with |Same as the startsWith operator.
 
+|!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.
 
 |ends with |Same as the endsWith operator.
+
+|!endsWith |For testing if the left-hand side string does not end 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 f898c4885079..f4211c80f34b 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];
 
@@ -80,21 +80,23 @@ public final class SimpleTokenizer {
         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");
-        KNOWN_TOKENS[40] = new SimpleTokenType(TokenType.binaryOperator, 
"endsWith");
-        KNOWN_TOKENS[41] = new SimpleTokenType(TokenType.binaryOperator, "ends 
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 46c24968580a..8e582ea98520 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
@@ -42,7 +42,9 @@ public enum BinaryOperatorType {
     RANGE,
     NOT_RANGE,
     STARTS_WITH,
-    ENDS_WITH;
+    NOT_STARTS_WITH,
+    ENDS_WITH,
+    NOT_ENDS_WITH;
 
     public static BinaryOperatorType asOperator(String text) {
         if ("==".equals(text)) {
@@ -89,6 +91,10 @@ public enum BinaryOperatorType {
             return STARTS_WITH;
         } else if ("endsWith".equals(text) || "ends with".equals(text)) {
             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);
     }
@@ -136,8 +142,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 "";
     }
@@ -238,9 +248,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";

Reply via email to