JAMES-2342 Introduce a MessageMoveEvent

Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/8b13708d
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/8b13708d
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/8b13708d

Branch: refs/heads/master
Commit: 8b13708dd9b96a8c30ba0a4155e515fafb19122b
Parents: fdc0f83
Author: Antoine Duprat <[email protected]>
Authored: Tue Mar 6 14:21:19 2018 +0100
Committer: Antoine Duprat <[email protected]>
Committed: Thu Mar 8 11:01:22 2018 +0100

----------------------------------------------------------------------
 mailbox/plugin/spamassassin/pom.xml             |  11 ++
 .../spamassassin/SpamAssassinListener.java      |  35 +++--
 .../spamassassin/SpamAssassinListenerTest.java  | 139 ++++++++++++------
 .../mailbox/store/StoreMessageIdManager.java    |   2 +
 .../mailbox/store/StoreMessageManager.java      |  24 ++-
 .../event/DefaultDelegatingMailboxListener.java |   4 +-
 .../james/mailbox/store/event/EventFactory.java |   9 ++
 .../store/event/MailboxEventDispatcher.java     |   5 +
 .../mailbox/store/event/MessageMoveEvent.java   | 109 ++++++++++++++
 .../AbstractMessageIdManagerSideEffectTest.java |   3 +
 .../store/event/MessageMoveEventTest.java       | 147 +++++++++++++++++++
 .../SpamAssassinListenerModule.java             |   9 +-
 12 files changed, 435 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/plugin/spamassassin/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/spamassassin/pom.xml 
b/mailbox/plugin/spamassassin/pom.xml
index b510523..535c3f5 100644
--- a/mailbox/plugin/spamassassin/pom.xml
+++ b/mailbox/plugin/spamassassin/pom.xml
@@ -37,10 +37,21 @@
             <artifactId>apache-james-mailbox-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>apache-james-mailbox-store</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
----------------------------------------------------------------------
diff --git 
a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
 
b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
index b2501f3..7a6382b 100644
--- 
a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
+++ 
b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassinListener.java
@@ -24,7 +24,11 @@ import javax.inject.Inject;
 
 import org.apache.james.mailbox.Event;
 import org.apache.james.mailbox.Role;
-import org.apache.james.mailbox.store.event.EventFactory;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.event.MessageMoveEvent;
 import org.apache.james.mailbox.store.event.SpamEventListener;
 import org.apache.james.mailbox.store.mail.model.Message;
 import org.slf4j.Logger;
@@ -40,10 +44,12 @@ public class SpamAssassinListener implements 
SpamEventListener {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(SpamAssassinListener.class);
 
     private final SpamAssassin spamAssassin;
+    private final MailboxSessionMapperFactory mapperFactory;
 
     @Inject
-    public SpamAssassinListener(SpamAssassin spamAssassin) {
+    public SpamAssassinListener(SpamAssassin spamAssassin, 
MailboxSessionMapperFactory mapperFactory) {
         this.spamAssassin = spamAssassin;
+        this.mapperFactory = mapperFactory;
     }
 
     @Override
@@ -58,25 +64,30 @@ public class SpamAssassinListener implements 
SpamEventListener {
 
     @Override
     public void event(Event event) {
-        LOGGER.debug("Event {} received in listener.", event);
-        if (event instanceof EventFactory.AddedImpl) {
-            EventFactory.AddedImpl addedToMailboxEvent = 
(EventFactory.AddedImpl) event;
-            if (isEventOnSpamMailbox(addedToMailboxEvent)) {
+        if (event instanceof MessageMoveEvent) {
+            MessageMoveEvent messageMoveEvent = (MessageMoveEvent) event;
+            if (isMessageMovedToSpamMailbox(messageMoveEvent)) {
                 LOGGER.debug("Spam event detected");
-                ImmutableList<InputStream> messages = 
addedToMailboxEvent.getAvailableMessages()
+                ImmutableList<InputStream> messages = 
messageMoveEvent.getMessages()
                     .values()
                     .stream()
                     .map(Throwing.function(Message::getFullContent))
                     .collect(Guavate.toImmutableList());
-                spamAssassin.learnSpam(messages, 
addedToMailboxEvent.getMailboxPath().getUser());
+                spamAssassin.learnSpam(messages, 
messageMoveEvent.getSession().getUser().getUserName());
             }
         }
     }
 
     @VisibleForTesting
-    boolean isEventOnSpamMailbox(MailboxEvent event) {
-        return Role.from(event.getMailboxPath().getName())
-            .filter(role -> role.equals(Role.SPAM))
-            .isPresent();
+    boolean isMessageMovedToSpamMailbox(MessageMoveEvent event) {
+        try {
+            MailboxPath spamMailboxPath = 
MailboxPath.forUser(event.getSession().getUser().getUserName(), 
Role.SPAM.getDefaultMailbox());
+            MailboxId spamMailboxId = 
mapperFactory.getMailboxMapper(event.getSession()).findMailboxByPath(spamMailboxPath).getMailboxId();
+
+            return 
event.getMessageMoves().addedMailboxIds().contains(spamMailboxId);
+        } catch (MailboxException e) {
+            LOGGER.warn("Could not resolve Spam mailbox", e);
+            return false;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
 
b/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
index 72761da..eab5267 100644
--- 
a/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
+++ 
b/mailbox/plugin/spamassassin/src/test/java/org/apache/james/mailbox/spamassassin/SpamAssassinListenerTest.java
@@ -23,83 +23,132 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-import java.util.Map;
-import java.util.SortedMap;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+
+import javax.mail.Flags;
+import javax.mail.util.SharedByteArrayInputStream;
 
-import org.apache.james.mailbox.DefaultMailboxes;
-import org.apache.james.mailbox.MailboxListener.Added;
-import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
+import org.apache.james.mailbox.mock.MockMailboxSession;
+import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.mailbox.model.MessageMetaData;
-import org.apache.james.mailbox.store.event.EventFactory;
-import org.apache.james.mailbox.store.mail.model.Mailbox;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+import org.apache.james.mailbox.model.MessageMoves;
+import org.apache.james.mailbox.model.TestMessageId;
+import org.apache.james.mailbox.store.event.MessageMoveEvent;
+import org.apache.james.mailbox.store.mail.MailboxMapper;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSortedMap;
 
 public class SpamAssassinListenerTest {
 
+    public static final String USER = "user";
+    public static final MockMailboxSession MAILBOX_SESSION = new 
MockMailboxSession(USER);
+    public static final int UID_VALIDITY = 43;
     private SpamAssassin spamAssassin;
     private SpamAssassinListener listener;
+    private MailboxId mailboxId1;
+    private MailboxId mailboxId2;
+    private MailboxId spamMailboxId;
+    private MailboxId spamCapitalMailboxId;
+    private MailboxMapper mailboxMapper;
 
     @Before
-    public void setup() {
+    public void setup() throws MailboxException {
         spamAssassin = mock(SpamAssassin.class);
-        listener = new SpamAssassinListener(spamAssassin);
+        InMemoryMailboxSessionMapperFactory mapperFactory = new 
InMemoryMailboxSessionMapperFactory();
+        mailboxMapper = mapperFactory.getMailboxMapper(MAILBOX_SESSION);
+        mailboxId1 = mailboxMapper.save(new 
SimpleMailbox(MailboxPath.forUser(USER, "mailbox1"), UID_VALIDITY));
+        mailboxId2 = mailboxMapper.save(new 
SimpleMailbox(MailboxPath.forUser(USER, "mailbox2"), UID_VALIDITY));
+        spamMailboxId = mailboxMapper.save(new 
SimpleMailbox(MailboxPath.forUser(USER, "Spam"), UID_VALIDITY));
+        spamCapitalMailboxId = mailboxMapper.save(new 
SimpleMailbox(MailboxPath.forUser(USER, "SPAM"), UID_VALIDITY));
+
+        listener = new SpamAssassinListener(spamAssassin, mapperFactory);
+    }
+
+    @After
+    public void tearDown() throws MailboxException {
+        mailboxMapper.list()
+            .forEach(Throwing.consumer(mailboxMapper::delete));
     }
 
     @Test
-    public void isEventOnSpamMailboxShouldReturnFalseWhenMailboxIsNotSpam() {
-        MailboxSession mailboxSession = null;
-        int uidValidity = 1;
-        Mailbox mailbox = new SimpleMailbox(MailboxPath.forUser("user", 
"mbx"), uidValidity);
-        SortedMap<MessageUid, MessageMetaData> uids = ImmutableSortedMap.of();
-        Map<MessageUid, MailboxMessage> availableMessages = ImmutableMap.of();
-        Added added = new EventFactory().added(mailboxSession, uids, mailbox, 
availableMessages);
-
-        assertThat(listener.isEventOnSpamMailbox(added)).isFalse();
+    public void 
isEventOnSpamMailboxShouldReturnFalseWhenMessageIsMovedToANonSpamMailbox() {
+        MessageMoveEvent messageMoveEvent = MessageMoveEvent.builder()
+            .session(MAILBOX_SESSION)
+            .messageMoves(MessageMoves.builder()
+                .previousMailboxIds(mailboxId1)
+                .targetMailboxIds(mailboxId2)
+                .build())
+            .messages(ImmutableMap.of(MessageUid.of(45),
+                createMessage(mailboxId2)))
+            .build();
+
+        
assertThat(listener.isMessageMovedToSpamMailbox(messageMoveEvent)).isFalse();
     }
 
     @Test
     public void isEventOnSpamMailboxShouldReturnTrueWhenMailboxIsSpam() {
-        MailboxSession mailboxSession = null;
-        int uidValidity = 1;
-        Mailbox mailbox = new SimpleMailbox(MailboxPath.forUser("user", 
DefaultMailboxes.SPAM), uidValidity);
-        SortedMap<MessageUid, MessageMetaData> uids = ImmutableSortedMap.of();
-        Map<MessageUid, MailboxMessage> availableMessages = ImmutableMap.of();
-        Added added = new EventFactory().added(mailboxSession, uids, mailbox, 
availableMessages);
-
-        assertThat(listener.isEventOnSpamMailbox(added)).isTrue();
+        MessageMoveEvent messageMoveEvent = MessageMoveEvent.builder()
+            .session(MAILBOX_SESSION)
+            .messageMoves(MessageMoves.builder()
+                .previousMailboxIds(mailboxId1)
+                .targetMailboxIds(spamMailboxId)
+                .build())
+            .messages(ImmutableMap.of(MessageUid.of(45),
+                createMessage(mailboxId1)))
+            .build();
+
+        
assertThat(listener.isMessageMovedToSpamMailbox(messageMoveEvent)).isTrue();
     }
 
     @Test
     public void 
isEventOnSpamMailboxShouldReturnFalseWhenMailboxIsSpamOtherCase() {
-        MailboxSession mailboxSession = null;
-        int uidValidity = 1;
-        Mailbox mailbox = new SimpleMailbox(MailboxPath.forUser("user", 
"SPAM"), uidValidity);
-        SortedMap<MessageUid, MessageMetaData> uids = ImmutableSortedMap.of();
-        Map<MessageUid, MailboxMessage> availableMessages = ImmutableMap.of();
-        Added added = new EventFactory().added(mailboxSession, uids, mailbox, 
availableMessages);
-
-        assertThat(listener.isEventOnSpamMailbox(added)).isFalse();
+        MessageMoveEvent messageMoveEvent = MessageMoveEvent.builder()
+            .session(MAILBOX_SESSION)
+            .messageMoves(MessageMoves.builder()
+                .previousMailboxIds(mailboxId1)
+                .targetMailboxIds(spamCapitalMailboxId)
+                .build())
+            .messages(ImmutableMap.of(MessageUid.of(45),
+                createMessage(mailboxId1)))
+            .build();
+
+        
assertThat(listener.isMessageMovedToSpamMailbox(messageMoveEvent)).isFalse();
     }
 
     @Test
     public void eventShouldCallSpamAssassinWhenTheEventMatches() {
-        MailboxSession mailboxSession = null;
-        int uidValidity = 1;
-        Mailbox mailbox = new SimpleMailbox(MailboxPath.forUser("user", 
"Spam"), uidValidity);
-        SortedMap<MessageUid, MessageMetaData> uids = ImmutableSortedMap.of();
-        Map<MessageUid, MailboxMessage> availableMessages = ImmutableMap.of();
-        Added added = new EventFactory().added(mailboxSession, uids, mailbox, 
availableMessages);
-
-        listener.event(added);
+        MessageMoveEvent messageMoveEvent = MessageMoveEvent.builder()
+            .session(MAILBOX_SESSION)
+            .messageMoves(MessageMoves.builder()
+                .previousMailboxIds(mailboxId1)
+                .targetMailboxIds(spamMailboxId)
+                .build())
+            .messages(ImmutableMap.of(MessageUid.of(45),
+                createMessage(mailboxId1)))
+            .build();
+
+        listener.event(messageMoveEvent);
 
         verify(spamAssassin).learnSpam(any(), any());
     }
+
+    private SimpleMailboxMessage createMessage(MailboxId mailboxId) {
+        int size = 45;
+        int bodyStartOctet = 25;
+        byte[] content = "Subject: 
test\r\n\r\nBody\r\n".getBytes(StandardCharsets.UTF_8);
+        return new SimpleMailboxMessage(TestMessageId.of(58), new Date(),
+            size, bodyStartOctet, new SharedByteArrayInputStream(content), new 
Flags(), new PropertyBuilder(),
+            mailboxId);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
index a4a448c..d65e6c6 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageIdManager.java
@@ -68,6 +68,7 @@ import com.github.fge.lambdas.Throwing;
 import com.github.fge.lambdas.functions.ThrowingFunction;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
 public class StoreMessageIdManager implements MessageIdManager {
@@ -231,6 +232,7 @@ public class StoreMessageIdManager implements 
MessageIdManager {
 
         addMessageToMailboxes(mailboxMessage, messageMoves.addedMailboxIds(), 
mailboxSession);
         removeMessageFromMailboxes(mailboxMessage, 
messageMoves.removedMailboxIds(), mailboxSession);
+        dispatcher.moved(mailboxSession, messageMoves, 
ImmutableMap.of(mailboxMessage.getUid(), mailboxMessage));
     }
 
     private void removeMessageFromMailboxes(MailboxMessage message, 
Set<MailboxId> mailboxesToRemove, MailboxSession mailboxSession) throws 
MailboxException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
index 23d9108..c095100 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
@@ -55,6 +55,7 @@ import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageId.Factory;
 import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult.FetchGroup;
 import org.apache.james.mailbox.model.MessageResultIterator;
@@ -740,7 +741,22 @@ public class StoreMessageManager implements 
org.apache.james.mailbox.MessageMana
 
     private SortedMap<MessageUid, MessageMetaData> copy(MessageRange set, 
StoreMessageManager to, MailboxSession session) throws MailboxException {
         IteratorWrapper<MailboxMessage> originalRows = new 
IteratorWrapper<>(retrieveOriginalRows(set, session));
-        return collectMetadata(to.copy(originalRows, session));
+
+        SortedMap<MessageUid, MessageMetaData> copiedUids = 
collectMetadata(to.copy(originalRows, session));
+
+        ImmutableMap.Builder<MessageUid, MailboxMessage> messagesMap = 
ImmutableMap.builder();
+        for (MailboxMessage message: originalRows.getEntriesSeen()) {
+            messagesMap.put(message.getUid(), 
immutableMailboxMessageFactory.from(to.getMailboxEntity().getMailboxId(), 
message));
+        }
+        dispatcher.added(session, copiedUids, to.getMailboxEntity(), 
messagesMap.build());
+        dispatcher.moved(session,
+            MessageMoves.builder()
+                .previousMailboxIds(getMailboxEntity().getMailboxId())
+                .targetMailboxIds(to.getMailboxEntity().getMailboxId(), 
getMailboxEntity().getMailboxId())
+                .build(),
+            messagesMap.build());
+
+        return copiedUids;
     }
 
     private SortedMap<MessageUid, MessageMetaData> move(MessageRange set, 
StoreMessageManager to, MailboxSession session) throws MailboxException {
@@ -755,6 +771,12 @@ public class StoreMessageManager implements 
org.apache.james.mailbox.MessageMana
         }
         dispatcher.added(session, moveUids, to.getMailboxEntity(), 
messagesMap.build());
         dispatcher.expunged(session, 
collectMetadata(moveResult.getOriginalMessages()), getMailboxEntity());
+        dispatcher.moved(session,
+                MessageMoves.builder()
+                    .previousMailboxIds(getMailboxEntity().getMailboxId())
+                    .targetMailboxIds(to.getMailboxEntity().getMailboxId())
+                    .build(),
+                messagesMap.build());
         return moveUids;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
index 687ff22..dca2f0c 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/DefaultDelegatingMailboxListener.java
@@ -88,6 +88,7 @@ public class DefaultDelegatingMailboxListener implements 
DelegatingMailboxListen
 
     @Override
     public void event(Event event) {
+        deliverEventToGlobalListeners(event);
         if (event instanceof MailboxEvent) {
             mailboxEvent((MailboxEvent) event);
         }
@@ -102,7 +103,6 @@ public class DefaultDelegatingMailboxListener implements 
DelegatingMailboxListen
             registry.handleRename(renamed.getMailboxPath(), 
renamed.getNewPath());
         }
         deliverEventToMailboxListeners(mailboxEvent, listenerSnapshot);
-        deliverEventToGlobalListeners(mailboxEvent);
     }
 
     protected void deliverEventToMailboxListeners(MailboxEvent event, 
Collection<MailboxListener> listenerSnapshot) {
@@ -111,7 +111,7 @@ public class DefaultDelegatingMailboxListener implements 
DelegatingMailboxListen
         }
     }
 
-    protected void deliverEventToGlobalListeners(MailboxEvent event) {
+    protected void deliverEventToGlobalListeners(Event event) {
         for (MailboxListener mailboxListener : registry.getGlobalListeners()) {
             eventDelivery.deliver(mailboxListener, event);
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
index b7cb1a2..040219a 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/EventFactory.java
@@ -29,6 +29,7 @@ import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.acl.ACLDiff;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.store.StoreMailboxPath;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
@@ -202,4 +203,12 @@ public class EventFactory {
     public MailboxListener.MailboxACLUpdated aclUpdated(MailboxSession 
session, MailboxPath mailboxPath, ACLDiff aclDiff) {
         return new MailboxListener.MailboxACLUpdated(session, mailboxPath, 
aclDiff);
     }
+
+    public MessageMoveEvent moved(MailboxSession session, MessageMoves 
messageMoves, Map<MessageUid, MailboxMessage> messages) {
+        return MessageMoveEvent.builder()
+                .session(session)
+                .messageMoves(messageMoves)
+                .messages(messages)
+                .build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java
index 0f628a1..e64a18f 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java
@@ -31,6 +31,7 @@ import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.acl.ACLDiff;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.MessageMoves;
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.store.SimpleMessageMetaData;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
@@ -153,4 +154,8 @@ public class MailboxEventDispatcher {
     public void aclUpdated(MailboxSession session, MailboxPath mailboxPath, 
ACLDiff aclDiff) {
         listener.event(eventFactory.aclUpdated(session, mailboxPath, aclDiff));
     }
+
+    public void moved(MailboxSession session, MessageMoves messageMoves, 
Map<MessageUid, MailboxMessage> messages) {
+        listener.event(eventFactory.moved(session, messageMoves, messages));
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MessageMoveEvent.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MessageMoveEvent.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MessageMoveEvent.java
new file mode 100644
index 0000000..8fe8c55
--- /dev/null
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MessageMoveEvent.java
@@ -0,0 +1,109 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.mailbox.store.event;
+
+import java.util.Map;
+
+import org.apache.james.mailbox.Event;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MessageMoves;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+public class MessageMoveEvent implements Event {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+
+        private MailboxSession session;
+        private MessageMoves messageMoves;
+        private ImmutableMap.Builder<MessageUid, MailboxMessage> 
messagesBuilder;
+
+        private Builder() {
+            messagesBuilder = ImmutableMap.builder();
+        }
+
+        public Builder session(MailboxSession session) {
+            this.session = session;
+            return this;
+        }
+
+        public Builder messageMoves(MessageMoves messageMoves) {
+            this.messageMoves = messageMoves;
+            return this;
+        }
+
+        public Builder messages(Map<MessageUid, MailboxMessage> messages) {
+            this.messagesBuilder.putAll(messages);
+            return this;
+        }
+
+        public MessageMoveEvent build() {
+            Preconditions.checkNotNull(session, "'session' is mandatory");
+            Preconditions.checkNotNull(messageMoves, "'messageMoves' is 
mandatory");
+
+            ImmutableMap<MessageUid, MailboxMessage> messages = 
messagesBuilder.build();
+            Preconditions.checkArgument(!messages.isEmpty(), "'messages' 
should not be empty");
+
+            return new MessageMoveEvent(session, messageMoves, messages);
+        }
+    }
+
+    private final MailboxSession session;
+    private final MessageMoves messageMoves;
+    private final Map<MessageUid, MailboxMessage> messages;
+
+    @VisibleForTesting
+    MessageMoveEvent(MailboxSession session, MessageMoves messageMoves, 
Map<MessageUid, MailboxMessage> messages) {
+        this.session = session;
+        this.messageMoves = messageMoves;
+        this.messages = messages;
+    }
+
+    @Override
+    public MailboxSession getSession() {
+        return session;
+    }
+
+    public MessageMoves getMessageMoves() {
+        return messageMoves;
+    }
+
+    public Map<MessageUid, MailboxMessage> getMessages() {
+        return messages;
+    }
+
+    public boolean isMoveTo(MailboxId mailboxId) {
+        return messageMoves.addedMailboxIds()
+                .contains(mailboxId);
+    }
+
+    public boolean isMoveFrom(MailboxId mailboxId) {
+        return messageMoves.removedMailboxIds()
+                .contains(mailboxId);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
index 1a7d0a5..3afdaf6 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerSideEffectTest.java
@@ -142,6 +142,7 @@ public abstract class 
AbstractMessageIdManagerSideEffectTest {
         messageIdManager.setInMailboxes(messageId, 
ImmutableList.of(mailbox1.getMailboxId(), mailbox2.getMailboxId()), session);
 
         verify(dispatcher).added(eq(session), eq(mailbox1), 
any(MailboxMessage.class));
+        verify(dispatcher).moved(eq(session), any(), any());
         verifyNoMoreInteractions(dispatcher);
     }
 
@@ -157,6 +158,7 @@ public abstract class 
AbstractMessageIdManagerSideEffectTest {
 
         verify(dispatcher).added(eq(session), eq(mailbox1), 
any(MailboxMessage.class));
         verify(dispatcher).added(eq(session), eq(mailbox3), 
any(MailboxMessage.class));
+        verify(dispatcher).moved(eq(session), any(), any());
         verifyNoMoreInteractions(dispatcher);
     }
 
@@ -186,6 +188,7 @@ public abstract class 
AbstractMessageIdManagerSideEffectTest {
 
         verify(dispatcher).expunged(eq(session), 
any(SimpleMessageMetaData.class), eq(mailbox2));
         verify(dispatcher).added(eq(session), eq(mailbox3), 
any(MailboxMessage.class));
+        verify(dispatcher).moved(eq(session), any(), any());
         verifyNoMoreInteractions(dispatcher);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MessageMoveEventTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MessageMoveEventTest.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MessageMoveEventTest.java
new file mode 100644
index 0000000..5052ff8
--- /dev/null
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/event/MessageMoveEventTest.java
@@ -0,0 +1,147 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.mailbox.store.event;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+
+import java.util.Map;
+
+import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.mock.MockMailboxSession;
+import org.apache.james.mailbox.model.MessageMoves;
+import org.apache.james.mailbox.model.TestId;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+import org.assertj.core.api.JUnitSoftAssertions;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+public class MessageMoveEventTest {
+
+    @Rule
+    public JUnitSoftAssertions softly = new JUnitSoftAssertions();
+
+    @Test
+    public void builderShouldThrowWhenSessionIsNull() {
+        assertThatThrownBy(() -> MessageMoveEvent.builder()
+                .build())
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenMessageMovesIsNull() {
+        assertThatThrownBy(() -> MessageMoveEvent.builder()
+                .session(new MockMailboxSession("[email protected]"))
+                .build())
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenMessagesIsEmpty() {
+        assertThatThrownBy(() -> MessageMoveEvent.builder()
+                .session(new MockMailboxSession("[email protected]"))
+                .messageMoves(MessageMoves.builder()
+                    .previousMailboxIds(TestId.of(1))
+                    .targetMailboxIds(TestId.of(2))
+                    .build())
+                .build())
+            .isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void builderShouldBuildWhenFieldsAreGiven() {
+        MockMailboxSession session = new MockMailboxSession("[email protected]");
+        MessageMoves messageMoves = MessageMoves.builder()
+            .targetMailboxIds(TestId.of(2))
+            .previousMailboxIds(TestId.of(1))
+            .build();
+        Map<MessageUid, MailboxMessage> messages = 
ImmutableMap.of(MessageUid.of(1), mock(MailboxMessage.class));
+
+        MessageMoveEvent event = MessageMoveEvent.builder()
+            .session(session)
+            .messageMoves(messageMoves)
+            .messages(messages)
+            .build();
+
+        softly.assertThat(event.getSession()).isEqualTo(session);
+        softly.assertThat(event.getMessageMoves()).isEqualTo(messageMoves);
+        softly.assertThat(event.getMessages()).isEqualTo(messages);
+    }
+
+    @Test
+    public void isMoveToShouldReturnFalseWhenMailboxIdIsNotInAddedMailboxIds() 
{
+        MessageMoveEvent event = MessageMoveEvent.builder()
+            .session(new MockMailboxSession("[email protected]"))
+            .messageMoves(MessageMoves.builder()
+                    .previousMailboxIds(TestId.of(1))
+                    .targetMailboxIds(TestId.of(2))
+                    .build())
+            .messages(ImmutableMap.of(MessageUid.of(1), 
mock(MailboxMessage.class)))
+            .build();
+
+        assertThat(event.isMoveTo(TestId.of(123))).isFalse();
+    }
+
+    @Test
+    public void isMoveToShouldReturnTrueWhenMailboxIdIsInAddedMailboxIds() {
+        TestId mailboxId = TestId.of(123);
+        MessageMoveEvent event = MessageMoveEvent.builder()
+            .session(new MockMailboxSession("[email protected]"))
+            .messageMoves(MessageMoves.builder()
+                .previousMailboxIds(TestId.of(1))
+                .targetMailboxIds(TestId.of(2), mailboxId)
+                .build())
+            .messages(ImmutableMap.of(MessageUid.of(1), 
mock(MailboxMessage.class)))
+            .build();
+
+        assertThat(event.isMoveTo(mailboxId)).isTrue();
+    }
+
+    @Test
+    public void 
isMoveFromShouldReturnFalseWhenMailboxIdIsNotInRemovedMailboxIds() {
+        MessageMoveEvent event = MessageMoveEvent.builder()
+            .session(new MockMailboxSession("[email protected]"))
+            .messageMoves(MessageMoves.builder()
+                    .previousMailboxIds(TestId.of(1))
+                    .targetMailboxIds(TestId.of(2))
+                    .build())
+            .messages(ImmutableMap.of(MessageUid.of(1), 
mock(MailboxMessage.class)))
+            .build();
+
+        assertThat(event.isMoveFrom(TestId.of(123))).isFalse();
+    }
+
+    @Test
+    public void isMoveFromShouldReturnTrueWhenMailboxIdIsInRemovedMailboxIds() 
{
+        TestId mailboxId = TestId.of(123);
+        MessageMoveEvent event = MessageMoveEvent.builder()
+            .session(new MockMailboxSession("[email protected]"))
+            .messageMoves(MessageMoves.builder()
+                .previousMailboxIds(TestId.of(1), mailboxId)
+                .targetMailboxIds(TestId.of(2))
+                .build())
+            .messages(ImmutableMap.of(MessageUid.of(1), 
mock(MailboxMessage.class)))
+            .build();
+
+        assertThat(event.isMoveFrom(mailboxId)).isTrue();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b13708d/server/container/guice/mailbox-plugin-spamassassin/src/main/java/org/apache/james/modules/spamassassin/SpamAssassinListenerModule.java
----------------------------------------------------------------------
diff --git 
a/server/container/guice/mailbox-plugin-spamassassin/src/main/java/org/apache/james/modules/spamassassin/SpamAssassinListenerModule.java
 
b/server/container/guice/mailbox-plugin-spamassassin/src/main/java/org/apache/james/modules/spamassassin/SpamAssassinListenerModule.java
index 8054bd4..6fe431f 100644
--- 
a/server/container/guice/mailbox-plugin-spamassassin/src/main/java/org/apache/james/modules/spamassassin/SpamAssassinListenerModule.java
+++ 
b/server/container/guice/mailbox-plugin-spamassassin/src/main/java/org/apache/james/modules/spamassassin/SpamAssassinListenerModule.java
@@ -32,6 +32,7 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.spamassassin.SpamAssassin;
 import org.apache.james.mailbox.spamassassin.SpamAssassinConfiguration;
 import org.apache.james.mailbox.spamassassin.SpamAssassinListener;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.utils.ConfigurationPerformer;
 import org.apache.james.utils.PropertiesProvider;
@@ -60,17 +61,21 @@ public class SpamAssassinListenerModule extends 
AbstractModule {
 
         private final SpamAssassinConfiguration spamAssassinConfiguration;
         private final StoreMailboxManager storeMailboxManager;
+        private final MailboxSessionMapperFactory mapperFactory;
 
         @Inject
-        public 
SpamAssassinListenerConfigurationPerformer(SpamAssassinConfiguration 
spamAssassinConfiguration, StoreMailboxManager storeMailboxManager) {
+        public 
SpamAssassinListenerConfigurationPerformer(SpamAssassinConfiguration 
spamAssassinConfiguration,
+                                                          StoreMailboxManager 
storeMailboxManager,
+                                                          
MailboxSessionMapperFactory mapperFactory) {
             this.spamAssassinConfiguration = spamAssassinConfiguration;
             this.storeMailboxManager = storeMailboxManager;
+            this.mapperFactory = mapperFactory;
         }
 
         @Override
         public void initModule() {
             try {
-                SpamAssassinListener spamAssassinListener = new 
SpamAssassinListener(new SpamAssassin(spamAssassinConfiguration));
+                SpamAssassinListener spamAssassinListener = new 
SpamAssassinListener(new SpamAssassin(spamAssassinConfiguration), 
mapperFactory);
                 MailboxSession session = null;
                 storeMailboxManager.addGlobalListener(spamAssassinListener, 
session);
             } catch (MailboxException e) {


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

Reply via email to