You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2015/11/28 13:54:12 UTC

svn commit: r1716953 - in /james/project/trunk/mailbox: cassandra/src/main/java/org/apache/james/mailbox/cassandra/ hbase/src/main/java/org/apache/james/mailbox/hbase/ jcr/src/main/java/org/apache/james/mailbox/jcr/ jpa/src/main/java/org/apache/james/m...

Author: btellier
Date: Sat Nov 28 12:54:11 2015
New Revision: 1716953

URL: http://svn.apache.org/viewvc?rev=1716953&view=rev
Log:
MAILBOX-211 Moving event related interfaces and classes

Added:
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AbstractDelegatingMailboxListener.java
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/HashMapDelegatingMailboxListener.java
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java
    james/project/trunk/mailbox/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherTest.java
Removed:
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/AbstractDelegatingMailboxListener.java
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/HashMapDelegatingMailboxListener.java
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/MailboxEventDispatcher.java
    james/project/trunk/mailbox/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java
Modified:
    james/project/trunk/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
    james/project/trunk/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMessageManager.java
    james/project/trunk/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java
    james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
    james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
    james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java

Modified: james/project/trunk/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java (original)
+++ james/project/trunk/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/CassandraMessageManager.java Sat Nov 28 12:54:11 2015
@@ -28,7 +28,7 @@ import org.apache.james.mailbox.acl.Unio
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
-import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.mail.model.Mailbox;

Modified: james/project/trunk/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMessageManager.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMessageManager.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMessageManager.java (original)
+++ james/project/trunk/mailbox/hbase/src/main/java/org/apache/james/mailbox/hbase/HBaseMessageManager.java Sat Nov 28 12:54:11 2015
@@ -27,7 +27,7 @@ import org.apache.james.mailbox.acl.Mail
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
-import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.mail.model.Mailbox;

Modified: james/project/trunk/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java (original)
+++ james/project/trunk/mailbox/jcr/src/main/java/org/apache/james/mailbox/jcr/JCRMessageManager.java Sat Nov 28 12:54:11 2015
@@ -32,7 +32,7 @@ import org.apache.james.mailbox.jcr.mail
 import org.apache.james.mailbox.jcr.mail.model.JCRMessage;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
-import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.mail.model.Message;

Modified: james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java (original)
+++ james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/JPAMessageManager.java Sat Nov 28 12:54:11 2015
@@ -32,7 +32,7 @@ import org.apache.james.mailbox.jpa.mail
 import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
-import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.mail.model.Mailbox;

Modified: james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java (original)
+++ james/project/trunk/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java Sat Nov 28 12:54:11 2015
@@ -35,7 +35,7 @@ import org.apache.james.mailbox.jpa.mail
 import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMessage;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
-import org.apache.james.mailbox.store.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.Message;

Modified: james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java (original)
+++ james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java Sat Nov 28 12:54:11 2015
@@ -55,12 +55,14 @@ import org.apache.james.mailbox.model.Me
 import org.apache.james.mailbox.model.SimpleMailboxACL;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
+import org.apache.james.mailbox.store.event.AbstractDelegatingMailboxListener;
+import org.apache.james.mailbox.store.event.HashMapDelegatingMailboxListener;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.model.MailboxId;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
 import org.apache.james.mailbox.store.quota.DefaultQuotaRootResolver;
-import org.apache.james.mailbox.store.quota.ListeningCurrentQuotaUpdater;
 import org.apache.james.mailbox.store.quota.NoQuotaManager;
 import org.apache.james.mailbox.store.quota.QuotaUpdater;
 import org.apache.james.mailbox.store.search.ListeningMessageSearchIndex;

Modified: james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java (original)
+++ james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java Sat Nov 28 12:54:11 2015
@@ -60,6 +60,7 @@ import org.apache.james.mailbox.model.Si
 import org.apache.james.mailbox.model.UpdatedFlags;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.MessageMapperFactory;

Added: james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AbstractDelegatingMailboxListener.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AbstractDelegatingMailboxListener.java?rev=1716953&view=auto
==============================================================================
--- james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AbstractDelegatingMailboxListener.java (added)
+++ james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/AbstractDelegatingMailboxListener.java Sat Nov 28 12:54:11 2015
@@ -0,0 +1,185 @@
+/****************************************************************
+ * 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.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxListenerSupport;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+
+public abstract class AbstractDelegatingMailboxListener implements MailboxListener, MailboxListenerSupport{
+    
+    protected AbstractDelegatingMailboxListener() {
+    }
+    
+    /**
+     * Receive the event and dispatch it to the right {@link MailboxListener} depending on
+     * {@link org.apache.james.mailbox.MailboxListener.Event#getMailboxPath()}
+     */
+    public void event(Event event) {
+        MailboxPath path = event.getMailboxPath();
+        Map<MailboxPath, List<MailboxListener>> listeners = getListeners();
+        List<MailboxListener> mListeners = null;
+        synchronized (listeners) {
+            mListeners = listeners.get(path);
+            if (mListeners != null && mListeners.isEmpty() == false) {
+             // take snapshot of the listeners list for later
+                mListeners = new ArrayList<MailboxListener>(mListeners);
+                
+                if (event instanceof MailboxDeletion) {
+                    // remove listeners if the mailbox was deleted
+                    listeners.remove(path);
+                } else if (event instanceof MailboxRenamed) {
+                    // handle rename events
+                    MailboxRenamed renamed = (MailboxRenamed) event;
+                    List<MailboxListener> l = listeners.remove(path);
+                    if (l != null) {
+                        listeners.put(renamed.getNewPath(), l);
+                    }
+                }
+                
+            }
+            
+        }
+        //outside the synchronized block against deadlocks from propagated events wanting to lock the listeners
+        if (mListeners != null) {
+            int sz = mListeners.size();
+            for (int i = 0; i < sz; i++) {
+                MailboxListener l = mListeners.get(i);
+                l.event(event);
+            }
+        }
+        
+        List<MailboxListener> globalListeners = getGlobalListeners();
+        if (globalListeners != null) {
+            synchronized (globalListeners) {
+                if (globalListeners.isEmpty() == false) {
+                    List<MailboxListener> closedListener = new ArrayList<MailboxListener>();
+                    //TODO do not fire them inside synchronized block too?
+                    int sz = globalListeners.size();
+                    for (int i = 0; i < sz; i++) {
+                        MailboxListener l = globalListeners.get(i);
+                        l.event(event);
+                        
+                    }
+                    
+                  
+                    if (closedListener.isEmpty() == false) {
+                        globalListeners.removeAll(closedListener);
+                    }
+                }
+            }
+        }
+        
+    }
+    
+    /**
+     * @see org.apache.james.mailbox.MailboxListenerSupport#addListener(org.apache.james.mailbox.model.MailboxPath, org.apache.james.mailbox.MailboxListener, org.apache.james.mailbox.MailboxSession)
+     */
+    public void addListener(MailboxPath path, MailboxListener listener, MailboxSession session) throws MailboxException {
+        Map<MailboxPath, List<MailboxListener>> listeners = getListeners();
+        
+        if (listeners != null) {
+            synchronized (listeners) {
+                List<MailboxListener> mListeners = listeners.get(path);
+                if (mListeners == null) {
+                    mListeners = new ArrayList<MailboxListener>();
+                    listeners.put(path, mListeners);
+                }
+                if (mListeners.contains(listener) == false) {
+                    mListeners.add(listener);
+                }        
+            }
+        } else {
+            throw new MailboxException("Cannot add MailboxListener to null list");
+        }
+    }
+
+    /**
+     * @see org.apache.james.mailbox.MailboxListenerSupport#addGlobalListener(org.apache.james.mailbox.MailboxListener, org.apache.james.mailbox.MailboxSession)
+     */
+    public void addGlobalListener(MailboxListener listener, MailboxSession session) throws MailboxException {
+        List<MailboxListener> gListeners = getGlobalListeners();
+        
+        if (gListeners != null) {
+            synchronized (gListeners) {
+                gListeners.add(listener);
+            }
+        } else {
+            throw new MailboxException("Cannot add MailboxListener to null list");
+        }
+    }
+
+    /**
+     * @see org.apache.james.mailbox.MailboxListenerSupport#removeListener(org.apache.james.mailbox.model.MailboxPath, org.apache.james.mailbox.MailboxListener, org.apache.james.mailbox.MailboxSession)
+     */
+    public void removeListener(MailboxPath mailboxPath, MailboxListener listener, MailboxSession session) throws MailboxException {
+        Map<MailboxPath, List<MailboxListener>> listeners = getListeners();
+        
+        if (listeners != null) {
+            synchronized (listeners) {
+                List<MailboxListener> mListeners = listeners.get(mailboxPath);
+                if (mListeners != null) {
+                    mListeners.remove(listener);
+                    if (mListeners.isEmpty()) {
+                        listeners.remove(mailboxPath);
+                    }
+                }
+            }
+        } else {
+            throw new MailboxException("Cannot remove MailboxListener from null list");
+        }
+    }
+
+    /**
+     * @see org.apache.james.mailbox.MailboxListenerSupport#removeGlobalListener(org.apache.james.mailbox.MailboxListener, org.apache.james.mailbox.MailboxSession)
+     */
+    public void removeGlobalListener(MailboxListener listener, MailboxSession session) throws MailboxException {
+        List<MailboxListener> gListeners = getGlobalListeners();
+
+        if (gListeners != null) {
+            synchronized (gListeners) {
+                gListeners.remove(listener);
+            }
+        } else {
+            throw new MailboxException("Cannot remove MailboxListener from null list");
+        }
+    }
+
+    /**
+     * Return the {@link Map} which is used to store the {@link MailboxListener}
+     * 
+     * @return listeners
+     */
+    protected abstract Map<MailboxPath, List<MailboxListener>> getListeners();
+    
+    /**
+     * Return the {@link List} which is used tos tore the global {@link MailboxListener}
+     * 
+     * @return globalListeners
+     */
+    protected abstract List<MailboxListener> getGlobalListeners();
+    
+    
+}

Added: james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/HashMapDelegatingMailboxListener.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/HashMapDelegatingMailboxListener.java?rev=1716953&view=auto
==============================================================================
--- james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/HashMapDelegatingMailboxListener.java (added)
+++ james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/HashMapDelegatingMailboxListener.java Sat Nov 28 12:54:11 2015
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.model.MailboxPath;
+
+/**
+ * Receive a {@link org.apache.james.mailbox.MailboxListener.Event} and delegate it to an other
+ * {@link MailboxListener} depending on the registered name
+ *
+ */
+public class HashMapDelegatingMailboxListener extends AbstractDelegatingMailboxListener{
+
+    private Map<MailboxPath, List<MailboxListener>> listeners = new HashMap<MailboxPath, List<MailboxListener>>();
+    private List<MailboxListener> globalListeners = new ArrayList<MailboxListener>();
+
+    @Override
+    public ListenerType getType() {
+        return ListenerType.EACH_NODE;
+    }
+
+    @Override
+    protected Map<MailboxPath, List<MailboxListener>> getListeners() {
+        return listeners;
+    }
+
+    @Override
+    protected List<MailboxListener> getGlobalListeners() {
+        return globalListeners;
+    }
+    
+}

Added: james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java?rev=1716953&view=auto
==============================================================================
--- james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java (added)
+++ james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/event/MailboxEventDispatcher.java Sat Nov 28 12:54:11 2015
@@ -0,0 +1,299 @@
+/****************************************************************
+ * 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.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxListener.MailboxAdded;
+import org.apache.james.mailbox.MailboxListener.MailboxDeletion;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageMetaData;
+import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.StoreMailboxPath;
+import org.apache.james.mailbox.store.mail.model.MailboxId;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+/**
+ * Helper class to dispatch {@link org.apache.james.mailbox.MailboxListener.Event}'s to registerend MailboxListener
+ */
+public class MailboxEventDispatcher<Id extends MailboxId> {
+
+    
+    private final MailboxListener listener;
+
+    public MailboxEventDispatcher(MailboxListener listener) {
+        this.listener = listener;
+    }
+    
+
+    /**
+     * Should get called when a new message was added to a Mailbox. All
+     * registered MailboxListener will get triggered then
+     * 
+     * @param session The mailbox session
+     * @param uids Sorted map with uids and message meta data
+     * @param mailbox The mailbox
+     */
+    public void added(MailboxSession session, SortedMap<Long, MessageMetaData> uids, Mailbox<Id> mailbox) {
+        final AddedImpl added = new AddedImpl(session, mailbox, uids);
+        listener.event(added);
+    }
+
+    /**
+     * Should get called when a message was expunged from a Mailbox. All
+     * registered MailboxListener will get triggered then
+     * 
+     * @param session The mailbox session
+     * @param uids Sorted map with uids and message meta data
+     * @param mailbox The mailbox
+     */
+    public void expunged(final MailboxSession session,  Map<Long, MessageMetaData> uids, Mailbox<Id> mailbox) {
+        final ExpungedImpl expunged = new ExpungedImpl(session, mailbox, uids);
+        listener.event(expunged);
+    }
+
+    /**
+     * Should get called when the message flags were update in a Mailbox. All
+     * registered MailboxListener will get triggered then
+     * 
+     * @param session
+     * @param uids
+     * @param mailbox
+     * @param uflags
+     */
+    public void flagsUpdated(MailboxSession session, final List<Long> uids, final Mailbox<Id> mailbox, final List<UpdatedFlags> uflags) {
+        final FlagsUpdatedImpl flags = new FlagsUpdatedImpl(session, mailbox, uids, uflags);
+        listener.event(flags);
+    }
+
+
+
+    /**
+     * Should get called when a Mailbox was renamed. All registered
+     * MailboxListener will get triggered then
+     * 
+     * @param session
+     * @param from
+     * @param to
+     */
+    public void mailboxRenamed(MailboxSession session, MailboxPath from, Mailbox<Id> to) {
+        listener.event(new MailboxRenamedEventImpl(session, from, to));
+    }
+
+    public final class AddedImpl extends MailboxListener.Added {
+
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+        private SortedMap<Long, MessageMetaData> added;
+        private final Mailbox<Id> mailbox;
+
+        public AddedImpl(final MailboxSession session, final Mailbox<Id> mailbox, final SortedMap<Long, MessageMetaData> added) {
+            super(session, new StoreMailboxPath<Id>(mailbox));
+            this.added = added;
+            this.mailbox = mailbox;
+        }
+
+        /**
+         * @see org.apache.james.mailbox.MailboxListener.MessageEvent#getUids()
+         */
+        public List<Long> getUids() {
+            return new ArrayList<Long>(added.keySet());
+        }
+
+        /**
+         * @see org.apache.james.mailbox.MailboxListener.Added#getMetaData(long)
+         */
+        public MessageMetaData getMetaData(long uid) {
+            return added.get(uid);
+        }
+        
+        public Mailbox<Id> getMailbox() {
+            return mailbox;
+        }
+    }
+
+    public final class ExpungedImpl extends MailboxListener.Expunged {
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+        private final Map<Long, MessageMetaData> uids;
+        private final Mailbox<Id> mailbox;
+
+        public ExpungedImpl(MailboxSession session, final Mailbox<Id> mailbox, final  Map<Long, MessageMetaData> uids) {
+            super(session,  new StoreMailboxPath<Id>(mailbox));
+            this.uids = uids;
+            this.mailbox = mailbox;
+        }
+
+        /**
+         * @see org.apache.james.mailbox.MailboxListener.MessageEvent#getUids()
+         */
+        public List<Long> getUids() {
+            return new ArrayList<Long>(uids.keySet());
+        }
+        
+        /**
+         * @see org.apache.james.mailbox.MailboxListener.Expunged#getMetaData(long)
+         */
+        public MessageMetaData getMetaData(long uid) {
+            return uids.get(uid);
+        }
+        
+        public Mailbox<Id> getMailbox() {
+            return mailbox;
+        }
+    }
+
+    public final class FlagsUpdatedImpl extends MailboxListener.FlagsUpdated {
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+        private final List<Long> uids;
+
+        private final Mailbox<Id> mailbox;
+
+        private final List<UpdatedFlags> uFlags;
+
+        public FlagsUpdatedImpl(MailboxSession session, final Mailbox<Id> mailbox, final List<Long> uids, final List<UpdatedFlags> uFlags) {
+            super(session, new StoreMailboxPath<Id>(mailbox));
+            this.uids = uids;
+            this.uFlags = uFlags;
+            this.mailbox = mailbox;
+        }
+
+        /**
+         * @see org.apache.james.mailbox.MailboxListener.MessageEvent#getUids()
+         */
+        public List<Long> getUids() {
+            return uids;
+        }
+
+        /**
+         * @see org.apache.james.mailbox.MailboxListener.FlagsUpdated#getUpdatedFlags()
+         */
+        public List<UpdatedFlags> getUpdatedFlags() {
+            return uFlags;
+        }
+        
+        public Mailbox<Id> getMailbox() {
+            return mailbox;
+        }
+
+    }
+
+    public final class MailboxDeletionImpl extends MailboxDeletion {
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+        private final Mailbox<Id> mailbox;
+
+        public MailboxDeletionImpl(MailboxSession session, Mailbox<Id> mailbox) {
+            super(session, new StoreMailboxPath<Id>(mailbox));
+            this.mailbox = mailbox;
+        }
+        
+        
+        public Mailbox<Id> getMailbox() {
+            return mailbox;
+        }
+
+    }
+    
+    public final class MailboxAddedImpl extends MailboxAdded {
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+        
+        private final Mailbox<Id> mailbox;
+
+        public MailboxAddedImpl(MailboxSession session, Mailbox<Id> mailbox) {
+            super(session,  new StoreMailboxPath<Id>(mailbox));
+            this.mailbox = mailbox;
+        }
+        
+        
+        public Mailbox<Id> getMailbox() {
+            return mailbox;
+        }
+
+    }
+    /**
+     * Should get called when a Mailbox was deleted. All registered
+     * MailboxListener will get triggered then
+     * 
+     * @param session
+     * @param mailbox
+     */
+    public void mailboxDeleted(MailboxSession session, Mailbox<Id> mailbox) {
+        final MailboxDeletion event = new MailboxDeletionImpl(session, mailbox);
+        listener.event(event);
+    }
+
+    /**
+     * Should get called when a Mailbox was added. All registered
+     * MailboxListener will get triggered then
+     * 
+     * @param session
+     * @param mailbox
+     */
+    public void mailboxAdded(MailboxSession session, Mailbox<Id> mailbox) {
+        final MailboxAdded event = new MailboxAddedImpl(session, mailbox);
+        listener.event(event);
+    }
+
+    public final class MailboxRenamedEventImpl extends MailboxListener.MailboxRenamed {
+        /**
+         * 
+         */
+        private static final long serialVersionUID = 1L;
+        
+        private final MailboxPath newPath;
+        private final Mailbox<Id> newMailbox;
+
+        public MailboxRenamedEventImpl(final MailboxSession session, final MailboxPath oldPath, final Mailbox<Id> newMailbox) {
+            super(session, oldPath);
+            this.newPath = new StoreMailboxPath<Id>(newMailbox);
+            this.newMailbox = newMailbox;
+        }
+
+        /**
+         * @see
+         * org.apache.james.mailbox.MailboxListener.MailboxRenamed#getNewPath()
+         */
+        public MailboxPath getNewPath() {
+            return newPath;
+        }
+        
+        public Mailbox<Id> getNewMailbox() {
+            return newMailbox;
+        }
+    }
+}

Modified: james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java?rev=1716953&r1=1716952&r2=1716953&view=diff
==============================================================================
--- james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java (original)
+++ james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/ListeningMessageSearchIndex.java Sat Nov 28 12:54:11 2015
@@ -28,10 +28,10 @@ import org.apache.james.mailbox.MailboxS
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
-import org.apache.james.mailbox.store.MailboxEventDispatcher.AddedImpl;
-import org.apache.james.mailbox.store.MailboxEventDispatcher.ExpungedImpl;
-import org.apache.james.mailbox.store.MailboxEventDispatcher.FlagsUpdatedImpl;
-import org.apache.james.mailbox.store.MailboxEventDispatcher.MailboxDeletionImpl;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher.AddedImpl;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher.ExpungedImpl;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher.FlagsUpdatedImpl;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher.MailboxDeletionImpl;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.MessageMapperFactory;
 import org.apache.james.mailbox.store.mail.model.MailboxId;

Added: james/project/trunk/mailbox/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherTest.java
URL: http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherTest.java?rev=1716953&view=auto
==============================================================================
--- james/project/trunk/mailbox/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherTest.java (added)
+++ james/project/trunk/mailbox/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherTest.java Sat Nov 28 12:54:11 2015
@@ -0,0 +1,349 @@
+/****************************************************************
+ * 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;
+
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.Iterator;
+
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.MailboxListener;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.mock.MockMailboxSession;
+import org.apache.james.mailbox.model.MailboxACL;
+import org.apache.james.mailbox.model.MessageResult;
+import org.apache.james.mailbox.model.SimpleMailboxACL;
+import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.util.EventCollector;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(JMock.class)
+public class MailboxEventDispatcherTest {
+
+    MailboxEventDispatcher<TestId> dispatcher;
+
+    EventCollector collector;
+
+    MessageResult result;
+    int sessionId = 10;
+
+    private MailboxSession session = new MockMailboxSession("test") {
+
+        @Override
+        public long getSessionId() {
+            return sessionId;
+        }
+        
+    };
+
+    private Mockery mockery = new JUnit4Mockery();
+
+    private Mailbox<TestId> mailbox = new Mailbox<TestId>() {
+
+        @Override
+        public TestId getMailboxId() {
+            return TestId.of(1L);
+        }
+
+        @Override
+        public String getNamespace() {
+            return null;
+        }
+
+        @Override
+        public void setNamespace(String namespace) {            
+        }
+
+        @Override
+        public String getUser() {
+            return null;
+        }
+
+        @Override
+        public void setUser(String user) {
+            
+        }
+
+        @Override
+        public String getName() {
+            return "test";
+        }
+
+        @Override
+        public void setName(String name) {
+        }
+
+        @Override
+        public long getUidValidity() {
+            return 0;
+        }
+        
+        @Override
+        public MailboxACL getACL() {
+            return SimpleMailboxACL.EMPTY;
+        }
+
+        @Override
+        public void setACL(MailboxACL acl) {
+        }
+
+    };
+    
+    @Before
+    public void setUp() throws Exception {
+        collector = new EventCollector();
+
+        dispatcher = new MailboxEventDispatcher<TestId>(collector);
+        result = mockery.mock(MessageResult.class);
+        mockery.checking(new Expectations() {{
+            allowing(result).getUid();will(returnValue(23L));
+        }});
+    }
+
+
+    @Test
+    public void testShouldReturnNoChangesWhenSystemFlagsUnchanged() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1,  new Flags(
+                Flags.Flag.DELETED), new Flags(Flags.Flag.DELETED))));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowAnsweredAdded() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(),
+                new Flags(Flags.Flag.ANSWERED))));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.ANSWERED, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowAnsweredRemoved() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(
+                Flags.Flag.ANSWERED), new Flags())));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.ANSWERED, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowDeletedAdded() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(),
+                new Flags(Flags.Flag.DELETED))));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.DELETED, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowDeletedRemoved() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(
+                Flags.Flag.DELETED), new Flags())));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.DELETED, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowDraftAdded() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(),
+                new Flags(Flags.Flag.DRAFT))));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.DRAFT, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowDraftRemoved() {
+        dispatcher.flagsUpdated(session,Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(
+                Flags.Flag.DRAFT), new Flags())));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.DRAFT, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowFlaggedAdded() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(),
+                new Flags(Flags.Flag.FLAGGED))));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.FLAGGED, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowFlaggedRemoved() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(
+                Flags.Flag.FLAGGED), new Flags())));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.FLAGGED, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowRecentAdded() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(),
+                new Flags(Flags.Flag.RECENT))));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.RECENT, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowRecentRemoved() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(
+                Flags.Flag.RECENT), new Flags())));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.RECENT, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowSeenAdded() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(),
+                new Flags(Flags.Flag.SEEN))));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.SEEN, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowSeenRemoved() {
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, new Flags(
+                Flags.Flag.SEEN), new Flags())));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.SEEN, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testShouldShowMixedChanges() {
+        Flags originals = new Flags();
+        originals.add(Flags.Flag.DRAFT);
+        originals.add(Flags.Flag.RECENT);
+        Flags updated = new Flags();
+        updated.add(Flags.Flag.ANSWERED);
+        updated.add(Flags.Flag.DRAFT);
+        updated.add(Flags.Flag.SEEN);
+
+        dispatcher.flagsUpdated(session, Arrays.asList(result.getUid()), mailbox, Arrays.asList(new UpdatedFlags(result.getUid(), -1, originals, updated)));
+        assertEquals(1, collector.getEvents().size());
+        assertTrue(collector.getEvents().get(0) instanceof MailboxListener.FlagsUpdated);
+        MailboxListener.FlagsUpdated event = (MailboxListener.FlagsUpdated) collector.getEvents()
+                .get(0);
+        Iterator<Flags.Flag> iterator = event.getUpdatedFlags().get(0).systemFlagIterator();
+        assertNotNull(iterator);
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.ANSWERED, iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.RECENT, iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Flags.Flag.SEEN, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+}



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