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 no...@apache.org on 2011/06/25 14:29:26 UTC

svn commit: r1139535 [2/2] - in /james/mailbox/trunk: jcr/src/main/java/org/apache/james/mailbox/jcr/ jcr/src/main/java/org/apache/james/mailbox/jcr/mail/ jcr/src/main/java/org/apache/james/mailbox/jcr/mail/model/ jcr/src/main/resources/org/apache/jame...

Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java?rev=1139535&view=auto
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java (added)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/AbstractLockingUidProvider.java Sat Jun 25 12:29:24 2011
@@ -0,0 +1,49 @@
+/****************************************************************
+ * 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.mail;
+
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxPathLocker;
+import org.apache.james.mailbox.MailboxPathLocker.LockAwareExecution;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.store.StoreMailboxPath;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+public abstract class AbstractLockingUidProvider<Id> implements UidProvider<Id>{
+
+    private final MailboxPathLocker locker;
+
+    public AbstractLockingUidProvider(MailboxPathLocker locker) {
+        this.locker = locker;
+    }
+    
+    @Override
+    public long nextUid(final MailboxSession session, final Mailbox<Id> mailbox) throws MailboxException {
+        return locker.executeWithLock(session, new StoreMailboxPath<Id>(mailbox), new LockAwareExecution<Long>() {
+
+            @Override
+            public Long execute() throws MailboxException {
+                return lockedNextUid(session, mailbox);
+            }
+        });
+    }
+    
+    protected abstract long lockedNextUid(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException;
+
+}

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=1139535&r1=1139534&r2=1139535&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 Sat Jun 25 12:29:24 2011
@@ -21,9 +21,6 @@ package org.apache.james.mailbox.store.m
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
 
 import javax.mail.Flags;
 
@@ -43,13 +40,15 @@ import org.apache.james.mailbox.store.tr
  * @param <Id>
  */
 public abstract class AbstractMessageMapper<Id> extends TransactionalMapper implements MessageMapper<Id>{
-    
-    private final static ConcurrentHashMap<Object, AtomicLong> seqs = new ConcurrentHashMap<Object, AtomicLong>();
-    private final static ConcurrentHashMap<Object, AtomicLong> uids = new ConcurrentHashMap<Object, AtomicLong>();
+   
     protected final MailboxSession mailboxSession;
+    private final UidProvider<Id> uidProvider;
+    private final ModSeqProvider<Id> modSeqProvider;
 
-    public AbstractMessageMapper(MailboxSession mailboxSession) {
+    public AbstractMessageMapper(MailboxSession mailboxSession, UidProvider<Id> uidProvider, ModSeqProvider<Id> modSeqProvider) {
         this.mailboxSession = mailboxSession;
+        this.uidProvider = uidProvider;
+        this.modSeqProvider = modSeqProvider;
     }
     
     
@@ -58,7 +57,7 @@ public abstract class AbstractMessageMap
      * @see org.apache.james.mailbox.store.mail.MessageMapper#getHighestModSeq(org.apache.james.mailbox.store.mail.model.Mailbox)
      */
     public long getHighestModSeq(Mailbox<Id> mailbox) throws MailboxException {
-        return retrieveLastUsedModSeq(mailbox).get();
+        return modSeqProvider.highestModSeq(mailboxSession, mailbox);
     }
 
     /*
@@ -66,102 +65,10 @@ public abstract class AbstractMessageMap
      * @see org.apache.james.mailbox.store.mail.MessageMapper#getLastUid(org.apache.james.mailbox.store.mail.model.Mailbox)
      */
     public long getLastUid(Mailbox<Id> mailbox) throws MailboxException {
-        return retrieveLastUid(mailbox).get();
-    }
-
-    
-    private long nextUid(Mailbox<Id> mailbox) throws MailboxException {       
-        return retrieveLastUid(mailbox).incrementAndGet();
+        return uidProvider.lastUid(mailboxSession, mailbox);
     }
     
-    
-    /**
-     * Return the next mod-seq which can be used while append a Message to the {@link Mailbox}.
-     * Its important that the returned mod-seq is higher then the last used and that the next call of this method does not return the same mod-swq. 
-     * 
-     * @param mailbox
-     * @return nextUid
-     * @throws MailboxException
-     */
-    private long nextModSeq(Mailbox<Id> mailbox) throws MailboxException {
-        return retrieveLastUsedModSeq(mailbox).incrementAndGet();
-    }
-
 
-    /**
-     * Retrieve the last used mod-seq for the {@link Mailbox} from cache or via lazy lookup.
-     * 
-     * @param session
-     * @param mailbox
-     * @return lastModSeq
-     * @throws MailboxException
-     */
-    protected AtomicLong retrieveLastUsedModSeq(Mailbox<Id> mailbox) throws MailboxException {
-        AtomicLong seq = seqs.get(mailbox.getMailboxId());
-
-        if (seq == null) {
-            seq = new AtomicLong(higestModSeq(mailbox));
-            AtomicLong cachedSeq = seqs.putIfAbsent(mailbox.getMailboxId(), seq);
-            if (cachedSeq != null) {
-                seq = cachedSeq;
-            }
-        }
-
-        return seq;
-    }
-    
-    private long higestModSeq(Mailbox<Id> mailbox) throws MailboxException {
-        long modSeq = calculateHigestModSeq(mailbox);
-        if (modSeq < 1) {
-            modSeq = mailbox.getHighestKnownModSeq();
-        }
-        return modSeq;
-    }
-    
-    /**
-     * Retrieve the last uid for the {@link Mailbox} from cache or via lazy lookup.
-     * 
-     * @param mailbox
-     * @return lastUid
-     * @throws MailboxException
-     */
-    protected AtomicLong retrieveLastUid(Mailbox<Id> mailbox) throws MailboxException {
-        AtomicLong uid = uids.get(mailbox.getMailboxId());
-
-        if (uid == null) {
-            uid = new AtomicLong(lastUid(mailbox));
-            AtomicLong cachedUid = uids.putIfAbsent(mailbox.getMailboxId(), uid);
-            if (cachedUid != null) {
-                uid = cachedUid;
-            }
-        }
-
-        return uid;
-    }
-    
-    private long lastUid(Mailbox<Id> mailbox) throws MailboxException {
-        long uid = calculateLastUid(mailbox);
-        if (uid < 1) {
-            uid = mailbox.getLastKnownUid();
-        }
-        return uid;
-    }
-    
-    /*
-     * (non-Javadoc)
-     * @see org.apache.james.mailbox.store.mail.MessageMapper#expungeMarkedForDeletionInMailbox(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.MessageRange)
-     */
-    public Map<Long, MessageMetaData> expungeMarkedForDeletionInMailbox(Mailbox<Id> mailbox, MessageRange set) throws MailboxException {
-        Map<Long, MessageMetaData> data = expungeMarkedForDeletion(mailbox, set);
-        if (data.isEmpty() == false) {
-
-            // Increase the mod-sequence and save it with the uid for this mailbox in a permanent way
-            // See MAILBOX-75 
-            saveSequences(mailbox, getLastUid(mailbox), nextModSeq(mailbox));
-
-        }
-        return data;
-    }
 
     
     /*
@@ -176,7 +83,10 @@ public abstract class AbstractMessageMap
                 
                 long modSeq = -1;
                 if (members.isEmpty() == false) {
-                    modSeq = nextModSeq(mailbox);
+                    // if a mailbox does not support mod-sequences the provider may be null
+                    if (modSeqProvider != null) {
+                        modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox);
+                    }
                 }
                 for (final Message<Id> member : members) {
                     Flags originalFlags = member.createFlags();
@@ -217,8 +127,12 @@ public abstract class AbstractMessageMap
      * @see org.apache.james.mailbox.store.mail.MessageMapper#add(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.store.mail.model.Message)
      */
     public MessageMetaData add(final Mailbox<Id> mailbox, Message<Id> message) throws MailboxException {
-        message.setUid(nextUid(mailbox));
-        message.setModSeq(nextModSeq(mailbox));
+        message.setUid(uidProvider.nextUid(mailboxSession, mailbox));
+        
+        // if a mailbox does not support mod-sequences the provider may be null
+        if (modSeqProvider != null) {
+            message.setModSeq(modSeqProvider.nextModSeq(mailboxSession, mailbox));
+        }
         MessageMetaData data = save(mailbox, message);
        
         return data;
@@ -231,35 +145,17 @@ public abstract class AbstractMessageMap
      * @see org.apache.james.mailbox.store.mail.MessageMapper#copy(org.apache.james.mailbox.store.mail.model.Mailbox, org.apache.james.mailbox.store.mail.model.Message)
      */
     public MessageMetaData copy(final Mailbox<Id> mailbox, final Message<Id> original) throws MailboxException {
-        long uid = nextUid(mailbox);
-        long modSeq = nextModSeq(mailbox);
+        long uid = uidProvider.nextUid(mailboxSession, mailbox);
+        long modSeq = -1;
+        if (modSeqProvider != null) {
+            modSeq = modSeqProvider.nextModSeq(mailboxSession, mailbox);
+        }
         final MessageMetaData metaData = copy(mailbox, uid, modSeq, original);  
         
         return metaData;
     }
 
    
-
-    /**
-     * Return the higest mod-seq for the given {@link Mailbox}. This method is called in a lazy fashion. So when the first mod-seq is needed for a {@link Mailbox}
-     * it will get called to get the higest used. After that it will stored in memory and just increment there on each {@link #nextModSeq(MailboxSession, Mailbox)} call.
-     * 
-     * @param mailbox
-     * @return lastUid
-     * @throws MailboxException
-     */
-    protected abstract long calculateHigestModSeq(Mailbox<Id> mailbox) throws MailboxException;
-    
-    /**
-     * Return the last used uid for the given {@link Mailbox}. This method is called in a lazy fashion. So when the first uid is needed for a {@link Mailbox}
-     * it will get called to get the last used. After that it will stored in memory and just increment there on each {@link #nextUid(MailboxSession, Mailbox)} call.
-     * 
-     * @param session
-     * @param mailbox
-     * @return lastUid
-     * @throws MailboxException
-     */
-    protected abstract long calculateLastUid(Mailbox<Id> mailbox) throws MailboxException;
     
     
     /**
@@ -285,25 +181,4 @@ public abstract class AbstractMessageMap
      */
     protected abstract MessageMetaData copy(Mailbox<Id> mailbox, long uid, long modSeq, Message<Id> original) throws MailboxException;
     
-    
-    /**
-     * Expunge all Messages which are marked for deletion
-     * 
-     * @param mailbox
-     * @param set
-     * @return
-     * @throws MailboxException
-     */
-    protected abstract Map<Long, MessageMetaData> expungeMarkedForDeletion(Mailbox<Id> mailbox, MessageRange set) throws MailboxException;
-
-    /**
-     * Save the sequence meta-data for the mailbox in a permanent way
-     * 
-     * @param mailbox
-     * @param lastUid
-     * @param highestModSeq
-     * @throws MailboxException
-     */
-    protected abstract void saveSequences(Mailbox<Id> mailbox, long lastUid, long highestModSeq) throws MailboxException;
-    
 }

Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java?rev=1139535&view=auto
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java (added)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/ModSeqProvider.java Sat Jun 25 12:29:24 2011
@@ -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.mail;
+
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+/**
+ * Take care of provide mod-seqences for a given {@link Mailbox}. Be aware that implementations
+ * need to be thread-safe!
+ * 
+ *
+ * @param <Id>
+ */
+public interface ModSeqProvider<Id> {
+
+    /**
+     * Return the next mod-sequence which can be used for the {@link Mailbox}.
+     * Its important that the returned mod-sequence is higher then the last used and that the next call of this method does return a higher
+     * one
+     * 
+     * @param session
+     * @param mailbox
+     * @return modSeq
+     * @throws MailboxException
+     */
+    public long nextModSeq(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException;
+    
+    /**
+     * Return the highest mod-sequence which were used for the {@link Mailbox}
+     * 
+     * @param session
+     * @param mailbox
+     * @return highest
+     * @throws MailboxException
+     */
+    public long highestModSeq(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException;
+}

Added: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java?rev=1139535&view=auto
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java (added)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/UidProvider.java Sat Jun 25 12:29:24 2011
@@ -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.mail;
+
+import org.apache.james.mailbox.MailboxException;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+
+/**
+ * Take care of provide uids for a given {@link Mailbox}. Be aware that implementations
+ * need to be thread-safe!
+ * 
+ *
+ * @param <Id>
+ */
+public interface UidProvider<Id> {
+
+    /**
+     * Return the next uid which can be used while append a Message to the {@link Mailbox}.
+     * Its important that the returned uid is higher then the last used and that the next call of this method does return a higher
+     * one
+     * 
+     * @param session
+     * @param mailbox
+     * @return nextUid
+     * @throws MailboxException
+     */
+    public long nextUid(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException;
+    
+    /**
+     * Return the last uid which were used for storing a Message in the {@link Mailbox}
+     * 
+     * @param session
+     * @param mailbox
+     * @return lastUid
+     * @throws MailboxException
+     */
+    public long lastUid(MailboxSession session, Mailbox<Id> mailbox) throws MailboxException;
+}

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java?rev=1139535&r1=1139534&r2=1139535&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/Mailbox.java Sat Jun 25 12:29:24 2011
@@ -70,22 +70,4 @@ public interface Mailbox<Id> {
      * @return uid validity
      */
     long getUidValidity();
-    
-    /**
-     * Return the last known uid for this mailbox which 
-     * was stored in a persist way. This does not guaranteer
-     * that there is no "higher" uid already allocated
-     * 
-     * @return lastKnownUid
-     */
-    long getLastKnownUid();
-    
-    /**
-     * Return the highest known mod-seq for this mailbox which 
-     * was stored in a persist way. This does not guaranteer
-     * that there is no "higher" mod-seq already allocated
-     * 
-     * @return highestKnownModSeq
-     */
-    long getHighestKnownModSeq();
 }
\ No newline at end of file

Modified: james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java?rev=1139535&r1=1139534&r2=1139535&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java (original)
+++ james/mailbox/trunk/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailbox.java Sat Jun 25 12:29:24 2011
@@ -28,16 +28,12 @@ public class SimpleMailbox<Id> implement
     private String user;
     private String name;
     private long uidValidity;
-    private long lastKnownUid;
-    private long highestKnownModSeq;
 
-    public SimpleMailbox(MailboxPath path, long uidValidity, long lastKnownUid, long highestKnownModSeq) {
+    public SimpleMailbox(MailboxPath path, long uidValidity) {
         this.namespace = path.getNamespace();
         this.user = path.getUser();
         this.name = path.getName();
         this.uidValidity = uidValidity;
-        this.lastKnownUid = lastKnownUid;
-        this.highestKnownModSeq = highestKnownModSeq;
     }
     
     public SimpleMailbox(Mailbox<Id> mailbox) {
@@ -46,8 +42,6 @@ public class SimpleMailbox<Id> implement
         this.user = mailbox.getUser();
         this.name = mailbox.getName();
         this.uidValidity = mailbox.getUidValidity();
-        this.lastKnownUid = mailbox.getLastKnownUid();
-        this.highestKnownModSeq = mailbox.getHighestKnownModSeq();
     }
 
     /*
@@ -165,21 +159,6 @@ public class SimpleMailbox<Id> implement
         return namespace + ":" + user + ":" + name;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see org.apache.james.mailbox.store.mail.model.Mailbox#getLastKnownUid()
-     */
-    public long getLastKnownUid() {
-        return lastKnownUid;
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see org.apache.james.mailbox.store.mail.model.Mailbox#getHighestKnownModSeq()
-     */
-    public long getHighestKnownModSeq() {
-        return highestKnownModSeq;
-    }
 
     public void setMailboxId(Id id) {
         this.id = id;

Modified: james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java
URL: http://svn.apache.org/viewvc/james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java?rev=1139535&r1=1139534&r2=1139535&view=diff
==============================================================================
--- james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java (original)
+++ james/mailbox/trunk/store/src/test/java/org/apache/james/mailbox/store/MailboxEventDispatcherFlagsTest.java Sat Jun 25 12:29:24 2011
@@ -102,16 +102,6 @@ public class MailboxEventDispatcherFlags
         public long getUidValidity() {
             return 0;
         }
-
-        @Override
-        public long getLastKnownUid() {
-            return 0;
-        }
-
-        @Override
-        public long getHighestKnownModSeq() {
-            return 0;
-        }
     };
     
     @Before



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