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

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit ec4db92c8eb6ce96e7153431b1d50ccdaa546c29
Author: Trung NGUYEN <[email protected]>
AuthorDate: Mon Sep 8 18:30:28 2025 +0200

    JAMES-4143 Add JMAP StartWith Filter
---
 .../src/main/java/org/apache/james/jmap/api/filtering/Rule.java     | 3 ++-
 .../java/org/apache/james/jmap/mailet/filter/ContentMatcher.java    | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git 
a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
 
b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
index 645c1705ad..234623f981 100644
--- 
a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
+++ 
b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/filtering/Rule.java
@@ -161,7 +161,8 @@ public class Rule {
             CONTAINS("contains"),
             NOT_CONTAINS("not-contains"),
             EXACTLY_EQUALS("exactly-equals"),
-            NOT_EXACTLY_EQUALS("not-exactly-equals");
+            NOT_EXACTLY_EQUALS("not-exactly-equals"),
+            START_WITH("start-with");
             
             public static Optional<Comparator> find(String comparatorName) {
                 return Arrays.stream(values())
diff --git 
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
 
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
index 3d30af8633..fd62f30215 100644
--- 
a/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
+++ 
b/server/protocols/jmap-rfc-8621/src/main/java/org/apache/james/jmap/mailet/filter/ContentMatcher.java
@@ -94,18 +94,23 @@ public interface ContentMatcher {
     ContentMatcher STRING_NOT_CONTAINS_MATCHER = 
negate(STRING_CONTAINS_MATCHER);
     ContentMatcher STRING_EXACTLY_EQUALS_MATCHER = (contents, valueToMatch) -> 
contents.anyMatch(content -> StringUtils.equals(content, valueToMatch));
     ContentMatcher STRING_NOT_EXACTLY_EQUALS_MATCHER = 
negate(STRING_EXACTLY_EQUALS_MATCHER);
+    ContentMatcher STRING_START_WITH_MATCHER = (contents, valueToMatch) -> 
contents.anyMatch(content -> content.startsWith(valueToMatch));
 
     ContentMatcher ADDRESS_CONTAINS_MATCHER = (contents, valueToMatch) -> 
contents
         .map(ContentMatcher::asAddressHeader)
         .anyMatch(addressHeader -> 
StringUtils.containsIgnoreCase(addressHeader.fullAddress, valueToMatch));
     ContentMatcher ADDRESS_NOT_CONTAINS_MATCHER = 
negate(ADDRESS_CONTAINS_MATCHER);
     ContentMatcher ADDRESS_NOT_EXACTLY_EQUALS_MATCHER = negate(new 
ExactAddressContentMatcher());
+    ContentMatcher ADDRESS_START_WITH_MATCHER = (contents, valueToMatch) -> 
contents
+        .map(ContentMatcher::asAddressHeader)
+        .anyMatch(addressHeader -> 
addressHeader.fullAddress.startsWith(valueToMatch));
 
     Map<Rule.Condition.Comparator, ContentMatcher> 
HEADER_ADDRESS_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, 
ContentMatcher>builder()
         .put(Rule.Condition.Comparator.CONTAINS, ADDRESS_CONTAINS_MATCHER)
         .put(Rule.Condition.Comparator.NOT_CONTAINS, 
ADDRESS_NOT_CONTAINS_MATCHER)
         .put(Rule.Condition.Comparator.EXACTLY_EQUALS, new 
ExactAddressContentMatcher())
         .put(Rule.Condition.Comparator.NOT_EXACTLY_EQUALS, 
ADDRESS_NOT_EXACTLY_EQUALS_MATCHER)
+        .put(Rule.Condition.Comparator.START_WITH, ADDRESS_START_WITH_MATCHER)
         .build();
 
     Map<Rule.Condition.Comparator, ContentMatcher> 
CONTENT_STRING_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Comparator, 
ContentMatcher>builder()
@@ -113,6 +118,7 @@ public interface ContentMatcher {
         .put(Rule.Condition.Comparator.NOT_CONTAINS, 
STRING_NOT_CONTAINS_MATCHER)
         .put(Rule.Condition.Comparator.EXACTLY_EQUALS, 
STRING_EXACTLY_EQUALS_MATCHER)
         .put(Rule.Condition.Comparator.NOT_EXACTLY_EQUALS, 
STRING_NOT_EXACTLY_EQUALS_MATCHER)
+        .put(Rule.Condition.Comparator.START_WITH, STRING_START_WITH_MATCHER)
         .build();
 
     Map<Rule.Condition.Field, Map<Rule.Condition.Comparator, ContentMatcher>> 
CONTENT_MATCHER_REGISTRY = ImmutableMap.<Rule.Condition.Field, 
Map<Rule.Condition.Comparator, ContentMatcher>>builder()


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to