Author: btellier
Date: Fri Jul  3 14:32:05 2015
New Revision: 1689014

URL: http://svn.apache.org/r1689014
Log:
MAILBOX-240 Improve flags update API

Added:
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/FlagsUpdateCalculator.java
    
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/FlagsUpdateCalculatorTest.java
Modified:
    
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
    
james/mailbox/trunk/caching/src/main/java/org/apache/james/mailbox/caching/CachingMessageMapper.java
    
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
    
james/mailbox/trunk/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
    
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java
    
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
    
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/StoreMessageResultIteratorTest.java
    
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java

Modified: 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
 (original)
+++ 
james/mailbox/trunk/api/src/main/java/org/apache/james/mailbox/MessageManager.java
 Fri Jul  3 14:32:05 2015
@@ -49,6 +49,12 @@ import org.apache.james.mailbox.model.Me
  */
 public interface MessageManager {
 
+    enum FlagsUpdateMode {
+        ADD,
+        REMOVE,
+        REPLACE
+    }
+
     /**
      * Return the count
      * 
@@ -116,20 +122,14 @@ public interface MessageManager {
      * Sets flags on messages within the given range. The new flags are 
returned
      * for each message altered.
      * 
-     * @param flags
-     *            Flags to be set
-     * @param value
-     *            true = set, false = unset
-     * @param replace
-     *            replace all Flags with this flags, value has to be true
-     * @param set
-     *            the range of messages
-     * @param mailboxSession
-     *            not null
+     * @param flags Flags to be taken into account for transformation of 
stored flags
+     * @param flagsUpdateMode Mode of the transformation of stored flags
+     * @param set the range of messages
+     * @param mailboxSession not null
      * @return new flags indexed by UID
      * @throws MailboxException
      */
-    Map<Long, Flags> setFlags(Flags flags, boolean value, boolean replace, 
MessageRange set, MailboxSession mailboxSession) throws MailboxException;
+    Map<Long, Flags> setFlags(Flags flags, FlagsUpdateMode flagsUpdateMode, 
MessageRange set, MailboxSession mailboxSession) throws MailboxException;
 
     /**
      * Appends a message to this mailbox. This method must return a higher UID

Modified: 
james/mailbox/trunk/caching/src/main/java/org/apache/james/mailbox/caching/CachingMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/caching/src/main/java/org/apache/james/mailbox/caching/CachingMessageMapper.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/caching/src/main/java/org/apache/james/mailbox/caching/CachingMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/caching/src/main/java/org/apache/james/mailbox/caching/CachingMessageMapper.java
 Fri Jul  3 14:32:05 2015
@@ -3,12 +3,11 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import javax.mail.Flags;
-
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.model.MailboxId;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
@@ -97,13 +96,12 @@ public class CachingMessageMapper<Id ext
        }
 
        @Override
-       public Iterator<UpdatedFlags> updateFlags(Mailbox<Id> mailbox, Flags 
flags,
-                       boolean value, boolean replace, MessageRange set)
+       public Iterator<UpdatedFlags> updateFlags(Mailbox<Id> mailbox, 
FlagsUpdateCalculator calculator, MessageRange set)
                        throws MailboxException {
                //check if there are in fact any updates
                if (set.iterator().hasNext())
                        invalidateMetadata(mailbox);
-               return underlying.updateFlags(mailbox, flags, value, replace, 
set);
+               return underlying.updateFlags(mailbox, calculator, set);
        }
 
 

Modified: 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
 Fri Jul  3 14:32:05 2015
@@ -78,6 +78,7 @@ import org.apache.james.mailbox.exceptio
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 import org.apache.james.mailbox.store.SimpleMessageMetaData;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
@@ -421,33 +422,23 @@ public class CassandraMessageMapper impl
         return ByteBuffer.wrap(ByteStreams.toByteArray(stream));
     }
 
-    /**
-     *
-     * @param mailbox Mailbox were messages are located
-     * @param flags Flags used for update
-     * @param value True if you want to set provided flags to true, false to 
set these flag to false
-     * @param replace true if we want to replace current flags by those 
provided
-     * @param set Range of messages to update
-     * @return Updated flag information
-     * @throws MailboxException
-     */
     @Override
-    public Iterator<UpdatedFlags> updateFlags(Mailbox<CassandraId> mailbox, 
Flags flags, boolean value, boolean replace, MessageRange set) throws 
MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(Mailbox<CassandraId> mailbox, 
FlagsUpdateCalculator flagsUpdateCalculator, MessageRange set) throws 
MailboxException {
         ImmutableList.Builder<UpdatedFlags> result = ImmutableList.builder();
         for (Row row : session.execute(buildQuery(mailbox, set))) {
-            updateMessage(mailbox, flags, value, replace, result, row);
+            updateMessage(mailbox, flagsUpdateCalculator, result, row);
         }
         return result.build().iterator();
     }
 
-    private void updateMessage(Mailbox<CassandraId> mailbox, Flags flags, 
boolean value, boolean replace, ImmutableList.Builder<UpdatedFlags> result, Row 
row) throws MailboxException {
+    private void updateMessage(Mailbox<CassandraId> mailbox, 
FlagsUpdateCalculator flagsUpdateCalculator, 
ImmutableList.Builder<UpdatedFlags> result, Row row) throws MailboxException {
         // Get the message and basic information about it
         Message<CassandraId> message = message(row);
         long flagVersion = row.getLong(FLAG_VERSION);
         long uid = message.getUid();
         // update flags
         Flags originFlags = message.createFlags();
-        Flags updatedFlags = buildFlags(message, flags, value, replace);
+        Flags updatedFlags = flagsUpdateCalculator.buildNewFlags(originFlags);
         message.setFlags(updatedFlags);
         // Update the ModSeq
         long previousModSeq = message.getModSeq();
@@ -470,7 +461,7 @@ public class CassandraMessageMapper impl
                 flagVersion = newRow.getLong(FLAG_VERSION);
                 // update flags
                 originFlags = message.createFlags();
-                updatedFlags = buildFlags(message, flags, value, replace);
+                updatedFlags = 
flagsUpdateCalculator.buildNewFlags(originFlags);
                 message.setFlags(updatedFlags);
                 // Update ModSeq
                 if (previousModSeq != message.getModSeq()) {
@@ -506,20 +497,6 @@ public class CassandraMessageMapper impl
         return resultSet.one();
     }
 
-    private Flags buildFlags(Message<CassandraId> message, Flags flags, 
boolean value, boolean replace) {
-        if (replace) {
-            return flags;
-        } else {
-            Flags updatedFlags = message.createFlags();
-            if (value) {
-                updatedFlags.add(flags);
-            } else {
-                updatedFlags.remove(flags);
-            }
-            return updatedFlags;
-        }
-    }
-
     @Override
     public MessageMetaData copy(Mailbox<CassandraId> mailbox, 
Message<CassandraId> original) throws MailboxException {
 

Modified: 
james/mailbox/trunk/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/hbase/src/main/java/org/apache/james/mailbox/hbase/mail/HBaseMessageMapper.java
 Fri Jul  3 14:32:05 2015
@@ -71,6 +71,7 @@ import org.apache.james.mailbox.model.Me
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageRange.Type;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 import org.apache.james.mailbox.store.SimpleMessageMetaData;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.ModSeqProvider;
@@ -494,7 +495,7 @@ public class HBaseMessageMapper extends
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#updateFlags(org.apache.james.mailbox.store.mail.model.Mailbox,
 javax.mail.Flags, boolean, boolean, org.apache.james.mailbox.MessageRange)
      */
     @Override
-    public Iterator<UpdatedFlags> updateFlags(final Mailbox<HBaseId> mailbox, 
final Flags flags, final boolean value, final boolean replace, MessageRange 
set) throws MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(final Mailbox<HBaseId> mailbox, 
FlagsUpdateCalculator flagsUpdateCalculator, MessageRange set) throws 
MailboxException {
 
         final List<UpdatedFlags> updatedFlags = new ArrayList<UpdatedFlags>();
         Iterator<Message<HBaseId>> messagesFound = findInMailbox(mailbox, set, 
FetchType.Metadata, -1);
@@ -514,18 +515,7 @@ public class HBaseMessageMapper extends
                 Put put = null;
                 final Message<HBaseId> member = messagesFound.next();
                 Flags originalFlags = member.createFlags();
-
-                if (replace) {
-                    member.setFlags(flags);
-                } else {
-                    Flags current = member.createFlags();
-                    if (value) {
-                        current.add(flags);
-                    } else {
-                        current.remove(flags);
-                    }
-                    member.setFlags(current);
-                }
+                
member.setFlags(flagsUpdateCalculator.buildNewFlags(originalFlags));
                 Flags newFlags = member.createFlags();
                 put = flagsToPut(member, newFlags);
                 if (UpdatedFlags.flagsChanged(originalFlags, newFlags)) {

Modified: 
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/MaildirMessageMapper.java
 Fri Jul  3 14:32:05 2015
@@ -46,6 +46,7 @@ import org.apache.james.mailbox.model.Me
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageRange.Type;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 import org.apache.james.mailbox.store.SimpleMessageMetaData;
 import org.apache.james.mailbox.store.mail.AbstractMessageMapper;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
@@ -171,8 +172,7 @@ public class MaildirMessageMapper extend
      *      org.apache.james.mailbox.model.MessageRange)
      */
     @Override
-    public Iterator<UpdatedFlags> updateFlags(final Mailbox<MaildirId> 
mailbox, final Flags flags, final boolean value,
-            final boolean replace, final MessageRange set) throws 
MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(final Mailbox<MaildirId> 
mailbox, final FlagsUpdateCalculator flagsUpdateCalculator, final MessageRange 
set) throws MailboxException {
         final List<UpdatedFlags> updatedFlags = new ArrayList<UpdatedFlags>();
         final MaildirFolder folder = maildirStore.createMaildirFolder(mailbox);
 
@@ -180,17 +180,7 @@ public class MaildirMessageMapper extend
         while (it.hasNext()) {
             final Message<MaildirId> member = it.next();
             Flags originalFlags = member.createFlags();
-            if (replace) {
-                member.setFlags(flags);
-            } else {
-                Flags current = member.createFlags();
-                if (value) {
-                    current.add(flags);
-                } else {
-                    current.remove(flags);
-                }
-                member.setFlags(current);
-            }
+            
member.setFlags(flagsUpdateCalculator.buildNewFlags(originalFlags));
             Flags newFlags = member.createFlags();
 
             try {

Added: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/FlagsUpdateCalculator.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/FlagsUpdateCalculator.java?rev=1689014&view=auto
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/FlagsUpdateCalculator.java
 (added)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/FlagsUpdateCalculator.java
 Fri Jul  3 14:32:05 2015
@@ -0,0 +1,51 @@
+/****************************************************************
+ * 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 javax.mail.Flags;
+
+import org.apache.james.mailbox.MessageManager;
+
+public class FlagsUpdateCalculator {
+
+    private final Flags providedFlags;
+    private final MessageManager.FlagsUpdateMode mode;
+
+    public FlagsUpdateCalculator(Flags providedFlags, 
MessageManager.FlagsUpdateMode mode) {
+        this.providedFlags = providedFlags;
+        this.mode = mode;
+    }
+
+    public Flags buildNewFlags(Flags flags) {
+        Flags updatedFlags = new Flags(flags);
+        switch (mode) {
+        case REPLACE:
+            return new Flags(providedFlags);
+        case ADD:
+            updatedFlags.add(providedFlags);
+            break;
+        case REMOVE:
+            updatedFlags.remove(providedFlags);
+            break;
+        }
+        return updatedFlags;
+    }
+
+}

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/StoreMessageManager.java
 Fri Jul  3 14:32:05 2015
@@ -515,7 +515,7 @@ public class StoreMessageManager<Id exte
      *      boolean, boolean, org.apache.james.mailbox.model.MessageRange,
      *      org.apache.james.mailbox.MailboxSession)
      */
-    public Map<Long, Flags> setFlags(final Flags flags, final boolean value, 
final boolean replace, final MessageRange set, MailboxSession mailboxSession) 
throws MailboxException {
+    public Map<Long, Flags> setFlags(final Flags flags, final FlagsUpdateMode 
flagsUpdateMode, final MessageRange set, MailboxSession mailboxSession) throws 
MailboxException {
 
         if (!isWriteable(mailboxSession)) {
             throw new ReadOnlyException(new 
StoreMailboxPath<Id>(getMailboxEntity()), mailboxSession.getPathDelimiter());
@@ -529,7 +529,7 @@ public class StoreMessageManager<Id exte
         Iterator<UpdatedFlags> it = messageMapper.execute(new 
Mapper.Transaction<Iterator<UpdatedFlags>>() {
 
             public Iterator<UpdatedFlags> run() throws MailboxException {
-                return messageMapper.updateFlags(getMailboxEntity(), flags, 
value, replace, set);
+                return messageMapper.updateFlags(getMailboxEntity(), new 
FlagsUpdateCalculator(flags, flagsUpdateMode), set);
             }
         });
 
@@ -654,7 +654,7 @@ public class StoreMessageManager<Id exte
                 for (MessageRange range : ranges) {
                     if (reset) {
                         // only call save if we need to
-                        messageMapper.updateFlags(getMailboxEntity(), new 
Flags(Flag.RECENT), false, false, range);
+                        messageMapper.updateFlags(getMailboxEntity(), new 
FlagsUpdateCalculator(new Flags(Flag.RECENT), FlagsUpdateMode.REMOVE), range);
                     }
                 }
                 return members;

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractMessageMapper.java
 Fri Jul  3 14:32:05 2015
@@ -29,6 +29,7 @@ import org.apache.james.mailbox.exceptio
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 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.Message;
@@ -68,7 +69,7 @@ public abstract class AbstractMessageMap
     /**
      * @see 
org.apache.james.mailbox.store.mail.MessageMapper#updateFlags(org.apache.james.mailbox.store.mail.model.Mailbox,
 javax.mail.Flags, boolean, boolean, 
org.apache.james.mailbox.model.MessageRange)
      */
-    public Iterator<UpdatedFlags> updateFlags(final Mailbox<Id> mailbox, final 
Flags flags, final boolean value, final boolean replace, final MessageRange 
set) throws MailboxException {
+    public Iterator<UpdatedFlags> updateFlags(final Mailbox<Id> mailbox, final 
FlagsUpdateCalculator flagsUpdateCalculator, final MessageRange set) throws 
MailboxException {
         final List<UpdatedFlags> updatedFlags = new ArrayList<UpdatedFlags>();
         Iterator<Message<Id>> messages = findInMailbox(mailbox, set, 
FetchType.Metadata, -1);
         
@@ -82,17 +83,7 @@ public abstract class AbstractMessageMap
         while(messages.hasNext()) {
                final Message<Id> member = messages.next();
             Flags originalFlags = member.createFlags();
-            if (replace) {
-                member.setFlags(flags);
-            } else {
-                Flags current = member.createFlags();
-                if (value) {
-                    current.add(flags);
-                } else {
-                    current.remove(flags);
-                }
-                member.setFlags(current);
-            }
+            
member.setFlags(flagsUpdateCalculator.buildNewFlags(originalFlags));
             Flags newFlags = member.createFlags();
             if (UpdatedFlags.flagsChanged(originalFlags, newFlags)) {
                 // increase the mod-seq as we changed the flags

Modified: 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
 (original)
+++ 
james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/MessageMapper.java
 Fri Jul  3 14:32:05 2015
@@ -22,12 +22,11 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import javax.mail.Flags;
-
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 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.Message;
@@ -133,14 +132,12 @@ public interface MessageMapper<Id extend
      * Update flags for the given {@link MessageRange}. Only the flags may be 
modified after a message was saved to a mailbox.
      * 
      * @param mailbox
-     * @param flags
-     * @param value
-     * @param replace
+     * @param flagsUpdateCalculator How to update flags
      * @param set
      * @return updatedFlags
      * @throws MailboxException
      */
-    Iterator<UpdatedFlags> updateFlags(Mailbox<Id> mailbox, final Flags flags, 
final boolean value, final boolean replace,
+    Iterator<UpdatedFlags> updateFlags(Mailbox<Id> mailbox, final 
FlagsUpdateCalculator flagsUpdateCalculator,
             final MessageRange set) throws MailboxException;
     
     /**

Added: 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/FlagsUpdateCalculatorTest.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/FlagsUpdateCalculatorTest.java?rev=1689014&view=auto
==============================================================================
--- 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/FlagsUpdateCalculatorTest.java
 (added)
+++ 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/FlagsUpdateCalculatorTest.java
 Fri Jul  3 14:32:05 2015
@@ -0,0 +1,60 @@
+/****************************************************************
+ * 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.assertj.core.api.Assertions.assertThat;
+
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.FlagsBuilder;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
+import org.junit.Test;
+
+public class FlagsUpdateCalculatorTest {
+
+    @Test
+    public void flagsShouldBeReplacedWhenReplaceIsTrueAndValueIsTrue() {
+        FlagsUpdateCalculator flagsUpdateCalculator = new 
FlagsUpdateCalculator(
+            new FlagsBuilder().add(Flags.Flag.DELETED, 
Flags.Flag.FLAGGED).add("userflag").build(),
+            MessageManager.FlagsUpdateMode.REPLACE);
+        assertThat(flagsUpdateCalculator.buildNewFlags(new 
FlagsBuilder().add(Flags.Flag.RECENT, Flags.Flag.FLAGGED).build()))
+            .isEqualTo(new FlagsBuilder().add(Flags.Flag.DELETED, 
Flags.Flag.FLAGGED).add("userflag").build());
+    }
+
+    @Test
+    public void flagsShouldBeAddedWhenReplaceIsFalseAndValueIsTrue() {
+        FlagsUpdateCalculator flagsUpdateCalculator = new 
FlagsUpdateCalculator(
+            new FlagsBuilder().add(Flags.Flag.DELETED, 
Flags.Flag.FLAGGED).add("userflag").build(),
+            MessageManager.FlagsUpdateMode.ADD);
+        assertThat(flagsUpdateCalculator.buildNewFlags(new 
FlagsBuilder().add(Flags.Flag.RECENT, Flags.Flag.FLAGGED).build()))
+            .isEqualTo(new FlagsBuilder().add(Flags.Flag.DELETED, 
Flags.Flag.FLAGGED, Flags.Flag.RECENT).add("userflag").build());
+    }
+
+    @Test
+    public void flagsShouldBeRemovedWhenReplaceIsFalseAndValueIsFalse() {
+        FlagsUpdateCalculator flagsUpdateCalculator = new 
FlagsUpdateCalculator(
+            new FlagsBuilder().add(Flags.Flag.DELETED, 
Flags.Flag.FLAGGED).add("userflag").build(),
+            MessageManager.FlagsUpdateMode.REMOVE);
+        assertThat(flagsUpdateCalculator.buildNewFlags(new 
FlagsBuilder().add(Flags.Flag.RECENT, Flags.Flag.FLAGGED).build()))
+            .isEqualTo(new Flags(Flags.Flag.RECENT));
+    }
+
+}

Modified: 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/StoreMessageResultIteratorTest.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/StoreMessageResultIteratorTest.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/StoreMessageResultIteratorTest.java
 (original)
+++ 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/StoreMessageResultIteratorTest.java
 Fri Jul  3 14:32:05 2015
@@ -125,8 +125,7 @@ public class StoreMessageResultIteratorT
             }
 
             @Override
-            public Iterator<UpdatedFlags> updateFlags(Mailbox<TestId> mailbox, 
Flags flags, boolean value,
-                    boolean replace, MessageRange set) throws MailboxException 
{
+            public Iterator<UpdatedFlags> updateFlags(Mailbox<TestId> mailbox, 
FlagsUpdateCalculator calculator, MessageRange set) throws MailboxException {
                 throw new UnsupportedOperationException();
             }
 

Modified: 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java
URL: 
http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java?rev=1689014&r1=1689013&r2=1689014&view=diff
==============================================================================
--- 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java
 (original)
+++ 
james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/mail/model/AbstractMessageMapperTest.java
 Fri Jul  3 14:32:05 2015
@@ -30,11 +30,13 @@ import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
 import org.apache.james.mailbox.FlagsBuilder;
+import org.apache.james.mailbox.MessageManager.FlagsUpdateMode;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageMetaData;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.FlagsUpdateCalculator;
 import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
@@ -120,15 +122,15 @@ public abstract class AbstractMessageMap
     @Test
     public void 
mailboxUnSeenCountShouldBeDecrementedAfterAMessageIsMarkedSeen() throws 
MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), true, true, 
MessageRange.one(message1.getUid())).hasNext();
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid())).hasNext();
         
assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(4);
     }
 
     @Test
     public void 
mailboxUnSeenCountShouldBeDecrementedAfterAMessageIsMarkedUnSeen() throws 
MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), true, true, MessageRange.one(message1.getUid()));
-        messageMapper.updateFlags(benwaInboxMailbox, new Flags(), true, true, 
MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
         
assertThat(messageMapper.countUnseenMessagesInMailbox(benwaInboxMailbox)).isEqualTo(5);
     }
     
@@ -263,9 +265,9 @@ public abstract class AbstractMessageMap
     @Test
     public void 
findRecentUidsInMailboxShouldReturnListOfMessagesHoldingFlagsRecent() throws 
MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.RECENT), true, true, MessageRange.one(message2.getUid()));
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.RECENT), true, true, MessageRange.one(message4.getUid()));
-        messageMapper.updateFlags(benwaWorkMailbox, new 
Flags(Flags.Flag.RECENT), true, true, MessageRange.one(message6.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.RECENT), FlagsUpdateMode.REPLACE), 
MessageRange.one(message2.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.RECENT), FlagsUpdateMode.REPLACE), 
MessageRange.one(message4.getUid()));
+        messageMapper.updateFlags(benwaWorkMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.RECENT), FlagsUpdateMode.REPLACE), 
MessageRange.one(message6.getUid()));
         
assertThat(messageMapper.findRecentMessageUidsInMailbox(benwaInboxMailbox)).containsOnly(message2.getUid(),
 message4.getUid());
     }
     
@@ -283,9 +285,9 @@ public abstract class AbstractMessageMap
     @Test
     public void findFirstUnseenMessageUidShouldReturnUid2WhenUid2isSeen() 
throws MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), true, true, MessageRange.one(message1.getUid()));
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), true, true, MessageRange.one(message3.getUid()));
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), true, true, MessageRange.one(message5.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.one(message3.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.one(message5.getUid()));
         
assertThat(messageMapper.findFirstUnseenMessageUid(benwaInboxMailbox)).isEqualTo(message2.getUid());
     }
     
@@ -471,70 +473,69 @@ public abstract class AbstractMessageMap
     @Test
     public void flagsReplacementShouldReplaceStoredMessageFlags() throws 
MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.FLAGGED), true, true, MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
         
MessageAssert.assertThat(retrieveMessageFromStorage(message1)).hasFlags(new 
Flags(Flags.Flag.FLAGGED));
     }
 
     @Test
     public void 
flagsReplacementShouldReturnAnUpdatedFlagHighlightingTheReplacement() throws 
MailboxException {
         saveMessages();
-        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.FLAGGED), true, true, MessageRange.one(message1.getUid())))
-            .containsOnly(new UpdatedFlags(message1.getUid(), 
messageMapper.getHighestModSeq(benwaInboxMailbox), new Flags(), new 
Flags(Flags.Flag.FLAGGED)));
+        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid())))
+            .containsOnly(new UpdatedFlags(message1.getUid(), modSeq + 1, new 
Flags(), new Flags(Flags.Flag.FLAGGED)));
     }
 
     @Test
     public void 
flagsAdditionShouldReturnAnUpdatedFlagHighlightingTheAddition() throws 
MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.FLAGGED), true, true, MessageRange.one(message1.getUid()));
-        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), true, false, MessageRange.one(message1.getUid())))
-            .containsOnly(new UpdatedFlags(message1.getUid(), 
messageMapper.getHighestModSeq(benwaInboxMailbox), new 
Flags(Flags.Flag.FLAGGED),
-                new FlagsBuilder().add(Flags.Flag.SEEN, 
Flags.Flag.FLAGGED).build()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
+        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.ADD), 
MessageRange.one(message1.getUid())))
+            .containsOnly(new UpdatedFlags(message1.getUid(), modSeq + 1, new 
Flags(Flags.Flag.FLAGGED), new FlagsBuilder().add(Flags.Flag.SEEN, 
Flags.Flag.FLAGGED).build()));
     }
 
     @Test
     public void flagsAdditionShouldUpdateStoredMessageFlags() throws 
MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.FLAGGED), true, true, MessageRange.one(message1.getUid()));
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), true, false, MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.FLAGGED), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.ADD), 
MessageRange.one(message1.getUid()));
         
MessageAssert.assertThat(retrieveMessageFromStorage(message1)).hasFlags(new 
FlagsBuilder().add(Flags.Flag.SEEN, Flags.Flag.FLAGGED).build());
     }
 
     @Test
     public void flagsRemovalShouldReturnAnUpdatedFlagHighlightingTheRemoval() 
throws MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsBuilder().add(Flags.Flag.FLAGGED, Flags.Flag.SEEN).build(), true, true, 
MessageRange.one(message1.getUid()));
-        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), false, false, MessageRange.one(message1.getUid())))
-            .containsOnly(new UpdatedFlags(message1.getUid(), 
messageMapper.getHighestModSeq(benwaInboxMailbox),
-                new FlagsBuilder().add(Flags.Flag.SEEN, 
Flags.Flag.FLAGGED).build(), new Flags(Flags.Flag.FLAGGED)));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new FlagsBuilder().add(Flags.Flag.FLAGGED, 
Flags.Flag.SEEN).build(), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
+        long modSeq = messageMapper.getHighestModSeq(benwaInboxMailbox);
+        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REMOVE), 
MessageRange.one(message1.getUid())))
+            .containsOnly(new UpdatedFlags(message1.getUid(), modSeq + 1, new 
FlagsBuilder().add(Flags.Flag.SEEN, Flags.Flag.FLAGGED).build(), new 
Flags(Flags.Flag.FLAGGED)));
     }
 
     @Test
     public void flagsRemovalShouldUpdateStoredMessageFlags() throws 
MailboxException {
         saveMessages();
-        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsBuilder().add(Flags.Flag.FLAGGED, Flags.Flag.SEEN).build(), true, true, 
MessageRange.one(message1.getUid()));
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), false, false, MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new FlagsBuilder().add(Flags.Flag.FLAGGED, 
Flags.Flag.SEEN).build(), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REMOVE), 
MessageRange.one(message1.getUid()));
         
MessageAssert.assertThat(retrieveMessageFromStorage(message1)).hasFlags(new 
Flags(Flags.Flag.FLAGGED));
     }
 
     @Test
     public void updateFlagsOnRangeShouldAffectMessagesContainedInThisRange() 
throws MailboxException {
         saveMessages();
-        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), false, true, MessageRange.range(message1.getUid(), 
message3.getUid())))
+        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.range(message1.getUid(), message3.getUid())))
             .hasSize(3);
     }
 
     @Test
     public void 
updateFlagsWithRangeFromShouldAffectMessagesContainedInThisRange() throws 
MailboxException {
         saveMessages();
-        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), false, true, MessageRange.from(message3.getUid())))
-            .hasSize(3);
+        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.from(message3.getUid()))).hasSize(3);
     }
 
     @Test
     public void updateFlagsWithRangeAllRangeShouldAffectAllMessages() throws 
MailboxException {
         saveMessages();
-        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.SEEN), false, true, MessageRange.all()))
-            .hasSize(5);
+        assertThat(messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.SEEN), FlagsUpdateMode.REPLACE), 
MessageRange.all())).hasSize(5);
     }
         
     @Test
@@ -609,8 +610,8 @@ public abstract class AbstractMessageMap
     }
 
     private Map<Long, MessageMetaData> markThenPerformExpunge(MessageRange 
range) throws MailboxException {
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.DELETED), true, true, MessageRange.one(message1.getUid()));
-        messageMapper.updateFlags(benwaInboxMailbox, new 
Flags(Flags.Flag.DELETED), true, true, MessageRange.one(message4.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.DELETED), FlagsUpdateMode.REPLACE), 
MessageRange.one(message1.getUid()));
+        messageMapper.updateFlags(benwaInboxMailbox, new 
FlagsUpdateCalculator(new Flags(Flags.Flag.DELETED), FlagsUpdateMode.REPLACE), 
MessageRange.one(message4.getUid()));
         return 
messageMapper.expungeMarkedForDeletionInMailbox(benwaInboxMailbox, range);
     }
 



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

Reply via email to