You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by bt...@apache.org on 2022/11/22 07:11:47 UTC

[james-project] 02/12: JAMES-3858 Add STATUS item for MAILBOXID

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

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

commit e82359cc0cbb7511aa788d3e798e8ed7dc49ff25
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Nov 17 10:38:59 2022 +0700

    JAMES-3858 Add STATUS item for MAILBOXID
---
 .../org/apache/james/imap/scripts/Status.test      |  4 ++++
 .../org/apache/james/imap/api/ImapConstants.java   |  2 ++
 .../james/imap/api/message/StatusDataItems.java    |  6 ++++++
 .../imap/decode/parser/StatusCommandParser.java    | 25 ++++++++++++++++++++--
 .../imap/encode/MailboxStatusResponseEncoder.java  |  9 ++++++++
 .../message/response/MailboxStatusResponse.java    |  9 +++++++-
 .../james/imap/processor/StatusProcessor.java      | 15 +++++++++++--
 .../encode/MailboxStatusResponseEncoderTest.java   |  2 +-
 8 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Status.test b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Status.test
index 0e060cba36..66cddc0794 100644
--- a/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Status.test
+++ b/mpt/impl/imap-mailbox/core/src/main/resources/org/apache/james/imap/scripts/Status.test
@@ -121,6 +121,10 @@ C: A013 STATUS statustest (UNSEEN SIZE MESSAGES DELETED DELETED-STORAGE)
 S: \* STATUS \"statustest\" \(MESSAGES 4 SIZE 1016 DELETED 2 DELETED-STORAGE 508 UNSEEN 4\)
 S: A013 OK STATUS completed.
 
+C: a014 STATUS statustest (MAILBOXID)
+S: \* STATUS \"statustest\" \(MAILBOXID \(.+\)\)
+S: a014 OK STATUS completed.
+
 # Cleanup
 C: a1 DELETE statustest
 S: a1 OK DELETE completed.
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
index 4c9d1274f8..fb90dc3359 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/ImapConstants.java
@@ -146,6 +146,8 @@ public interface ImapConstants {
 
     String STATUS_UNSEEN = "UNSEEN";
 
+    String STATUS_MAILBOXID = "MAILBOXID";
+
     String STATUS_UIDVALIDITY = "UIDVALIDITY";
 
     String STATUS_UIDNEXT = "UIDNEXT";
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/api/message/StatusDataItems.java b/protocols/imap/src/main/java/org/apache/james/imap/api/message/StatusDataItems.java
index ce2a1483dc..62db255315 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/api/message/StatusDataItems.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/api/message/StatusDataItems.java
@@ -30,6 +30,8 @@ public class StatusDataItems {
         // See https://www.rfc-editor.org/rfc/rfc7889.html
         APPENDLIMIT,
         MESSAGES,
+        // https://www.rfc-editor.org/rfc/rfc8474.html#section-4.3
+        MAILBOXID,
         RECENT,
         UID_NEXT,
         UID_VALIDITY,
@@ -72,6 +74,10 @@ public class StatusDataItems {
     public boolean isUnseen() {
         return statusItems.contains(StatusItem.UNSEEN);
     }
+
+    public boolean isMailboxId() {
+        return statusItems.contains(StatusItem.MAILBOXID);
+    }
     
     public boolean isHighestModSeq() {
         return statusItems.contains(StatusItem.HIGHEST_MODSEQ);
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StatusCommandParser.java b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StatusCommandParser.java
index b1bd70bba2..b5e1800a84 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StatusCommandParser.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StatusCommandParser.java
@@ -76,7 +76,7 @@ public class StatusCommandParser extends AbstractImapCommandParser {
             return readAppendLimit(request);
         }
         if (c == 'm' || c == 'M') {
-            return readMessages(request);
+            return readM(request);
         }
         if (c == 'd' || c == 'D') {
             return readDeleted(request);
@@ -96,6 +96,16 @@ public class StatusCommandParser extends AbstractImapCommandParser {
         throw new DecodingException(HumanReadableText.ILLEGAL_ARGUMENTS, "Unknown status item: '" + request.consumeWord(ImapRequestLineReader.NoopCharValidator.INSTANCE) + "'");
     }
 
+    private StatusDataItems.StatusItem readM(ImapRequestLineReader request) throws DecodingException {
+        request.consume();
+        char c2 = request.nextChar();
+        if (c2 == 'e' || c2 == 'E') {
+            return readMessages(request);
+        } else {
+            return readMailboxId(request);
+        }
+    }
+
     private StatusDataItems.StatusItem readU(ImapRequestLineReader request) throws DecodingException {
         char c;
         assertChar(request, 'u', 'U');
@@ -192,7 +202,6 @@ public class StatusCommandParser extends AbstractImapCommandParser {
     }
 
     private StatusDataItems.StatusItem readMessages(ImapRequestLineReader request) throws DecodingException {
-        assertChar(request, 'm', 'M');
         assertChar(request, 'e', 'E');
         assertChar(request, 's', 'S');
         assertChar(request, 's', 'S');
@@ -226,6 +235,18 @@ public class StatusCommandParser extends AbstractImapCommandParser {
         return StatusDataItems.StatusItem.DELETED;
     }
 
+    private StatusDataItems.StatusItem readMailboxId(ImapRequestLineReader request) throws DecodingException {
+        assertChar(request, 'a', 'A');
+        assertChar(request, 'i', 'I');
+        assertChar(request, 'l', 'L');
+        assertChar(request, 'b', 'B');
+        assertChar(request, 'o', 'O');
+        assertChar(request, 'x', 'X');
+        assertChar(request, 'i', 'I');
+        assertChar(request, 'd', 'D');
+        return StatusDataItems.StatusItem.MAILBOXID;
+    }
+
     private void assertChar(ImapRequestLineReader reader, char low, char up) throws DecodingException {
         char c = reader.consume();
         if (c != low && c != up) {
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java b/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java
index 6042b9134f..92a62f1fb3 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/encode/MailboxStatusResponseEncoder.java
@@ -26,6 +26,7 @@ import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.message.response.MailboxStatusResponse;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.UidValidity;
 
 /**
@@ -49,6 +50,7 @@ public class MailboxStatusResponseEncoder implements ImapConstants, ImapResponse
         ModSeq highestModSeq = response.getHighestModSeq();
         UidValidity uidValidity = response.getUidValidity();
         Long unseen = response.getUnseen();
+        MailboxId mailboxId = response.getMailboxId();
         String mailboxName = response.getMailbox();
 
         composer.untagged();
@@ -106,6 +108,13 @@ public class MailboxStatusResponseEncoder implements ImapConstants, ImapResponse
             composer.message(unseen);
         }
 
+        if (mailboxId != null) {
+            composer.message(STATUS_MAILBOXID);
+            composer.openParen();
+            composer.message(mailboxId.serialize());
+            composer.closeParen();
+        }
+
         composer.closeParen();
         composer.end();
     }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java b/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java
index 1a557b1e9b..869b9bba36 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/message/response/MailboxStatusResponse.java
@@ -24,6 +24,7 @@ import java.util.Optional;
 import org.apache.james.imap.api.message.response.ImapResponseMessage;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
+import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.UidValidity;
 
 /**
@@ -41,8 +42,9 @@ public class MailboxStatusResponse implements ImapResponseMessage {
     private final Long unseen;
     private final String mailbox;
     private final ModSeq highestModSeq;
+    private final MailboxId mailboxId;
 
-    public MailboxStatusResponse(Optional<Long> appendLimit, Long size, Long deleted, Long deletedStorage, Long messages, Long recent, MessageUid uidNext, ModSeq highestModSeq, UidValidity uidValidity, Long unseen, String mailbox) {
+    public MailboxStatusResponse(Optional<Long> appendLimit, Long size, Long deleted, Long deletedStorage, Long messages, Long recent, MessageUid uidNext, ModSeq highestModSeq, UidValidity uidValidity, Long unseen, String mailbox, MailboxId mailboxId) {
         this.appendLimit = appendLimit;
         this.size = size;
         this.deleted = deleted;
@@ -54,6 +56,7 @@ public class MailboxStatusResponse implements ImapResponseMessage {
         this.unseen = unseen;
         this.mailbox = mailbox;
         this.highestModSeq = highestModSeq;
+        this.mailboxId = mailboxId;
     }
 
     public Optional<Long> getAppendLimit() {
@@ -135,6 +138,10 @@ public class MailboxStatusResponse implements ImapResponseMessage {
         return highestModSeq;
     }
 
+    public MailboxId getMailboxId() {
+        return mailboxId;
+    }
+
     public String toString() {
         return "Status response[mailbox='" + mailbox + "' messages=" + messages + " recent=" + recent + " uidnext=" + uidNext + " uidvalidity=" + uidValidity + " unseen=" + unseen + "]";
     }
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
index 79da9c1e2e..495004e721 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/StatusProcessor.java
@@ -44,6 +44,7 @@ import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.ModSeq;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.FetchGroup;
+import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult;
@@ -153,11 +154,13 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> imp
                 UidValidity uidValidity = uidValidity(statusDataItems, metaData);
                 Long unseen = unseen(statusDataItems, metaData);
                 ModSeq highestModSeq = highestModSeq(statusDataItems, metaData);
-                return new MailboxStatusResponse(appendLimit,
+                MailboxId mailboxId = mailboxId(statusDataItems, mailbox);
+                return new MailboxStatusResponse(
+                    appendLimit,
                     maybeIterationResult.flatMap(result -> result.getSize(statusDataItems)).orElse(null),
                     maybeIterationResult.flatMap(result -> result.getDeleted(statusDataItems)).orElse(null),
                     maybeIterationResult.flatMap(result -> result.getDeletedStorage(statusDataItems)).orElse(null),
-                    messages, recent, uidNext, highestModSeq, uidValidity, unseen, request.getMailboxName());
+                    messages, recent, uidNext, highestModSeq, uidValidity, unseen, request.getMailboxName(), mailboxId);
             });
     }
 
@@ -176,6 +179,14 @@ public class StatusProcessor extends AbstractMailboxProcessor<StatusRequest> imp
             return null;
         }
     }
+    
+    private MailboxId mailboxId(StatusDataItems statusDataItems, MessageManager mailbox) {
+        if (statusDataItems.isMailboxId()) {
+            return mailbox.getId();
+        } else {
+            return null;
+        }
+    }
 
     private Optional<Long> appendLimit(StatusDataItems statusDataItems) {
         if (statusDataItems.isAppendLimit()) {
diff --git a/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java b/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java
index 3e2e7d9988..2c590d8824 100644
--- a/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java
+++ b/protocols/imap/src/test/java/org/apache/james/imap/encode/MailboxStatusResponseEncoderTest.java
@@ -59,7 +59,7 @@ class MailboxStatusResponseEncoderTest  {
         final String mailbox = "A mailbox named desire";
 
         encoder.encode(new MailboxStatusResponse(null, null, null, deletedStorage, messages, recent, uidNext,
-                null, uidValidity, unseen, mailbox), composer);
+                null, uidValidity, unseen, mailbox, null), composer);
         assertThat(writer.getString()).isEqualTo("* STATUS \"A mailbox named desire\" (MESSAGES 2 DELETED-STORAGE 13 RECENT 3 UIDNEXT 5 UIDVALIDITY 7 UNSEEN 11)\r\n");
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org