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 e776cc3287f14d5d80984c30028332c47f4bb9c2
Author: Quan Tran <[email protected]>
AuthorDate: Thu Mar 19 16:15:30 2026 +0700

    JAMES-4191 [Memory] DeletedMessageVaultHook should append vault only when 
owner no longer has reference to the deleted message
---
 .../org/apache/james/vault/DeletedMessageVaultHook.java   | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git 
a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultHook.java
 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultHook.java
index 387d060dc6..cff86ab2a9 100644
--- 
a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultHook.java
+++ 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/DeletedMessageVaultHook.java
@@ -24,6 +24,7 @@ import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
 import java.util.List;
 import java.util.Objects;
+import java.util.function.Predicate;
 
 import jakarta.inject.Inject;
 
@@ -38,6 +39,7 @@ import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.MessageMapper;
+import org.apache.james.util.FunctionalUtils;
 import org.reactivestreams.Publisher;
 
 import com.google.common.base.Preconditions;
@@ -115,6 +117,7 @@ public class DeletedMessageVaultHook implements 
PreDeletionHook {
         Preconditions.checkNotNull(deleteOperation);
 
         return groupMetadataByOwnerAndMessageId(deleteOperation)
+            .filterWhen(this::isUnreferencedByOwner)
             .flatMap(this::appendToTheVault, CONCURRENCY)
             .then();
     }
@@ -131,6 +134,18 @@ public class DeletedMessageVaultHook implements 
PreDeletionHook {
                 .flatMap(fullContent -> 
Mono.from(deletedMessageVault.append(pairs.getRight(), fullContent))));
     }
 
+    private Mono<Boolean> isUnreferencedByOwner(DeletedMessageMailboxContext 
deletedMessageMailboxContext) {
+        return 
mapperFactory.getMessageIdMapper(session).findMailboxesReactive(deletedMessageMailboxContext.getMessageId())
+            .filter(excludeDeletingMailbox(deletedMessageMailboxContext))
+            .flatMap(this::retrieveMailboxUser, CONCURRENCY)
+            .any(owner -> 
owner.equals(deletedMessageMailboxContext.getOwner()))
+            .map(FunctionalUtils.negate());
+    }
+
+    private Predicate<MailboxId> 
excludeDeletingMailbox(DeletedMessageMailboxContext 
deletedMessageMailboxContext) {
+        return mailboxId -> 
!deletedMessageMailboxContext.getOwnerMailboxes().contains(mailboxId);
+    }
+
     private Flux<DeletedMessageMailboxContext> 
groupMetadataByOwnerAndMessageId(DeleteOperation deleteOperation) {
         return Flux.fromIterable(deleteOperation.getDeletionMetadataList())
             .groupBy(MetadataWithMailboxId::getMailboxId)


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

Reply via email to