Author: norman
Date: Tue Apr 27 19:43:40 2010
New Revision: 938618

URL: http://svn.apache.org/viewvc?rev=938618&view=rev
Log:
Don't cache Mailboxes so we don't get problems with GC (IMAP-131). Not all 
tests passing yet, so work in progress

Added:
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/MailboxSessionEntityManagerFactory.java
    
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/DelegatingMailboxListener.java
Removed:
    james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAUtils.java
Modified:
    
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/inmemory/InMemoryHostSystem.java
    
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jpa/JPAHostSystem.java
    
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRGlobalUserMailboxManager.java
    james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPASubscriptionManager.java
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/openjpa/OpenJPAMailboxMapper.java
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java
    
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java
    
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java
    
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java
    
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
    
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailboxManager.java

Modified: 
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/inmemory/InMemoryHostSystem.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/inmemory/InMemoryHostSystem.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/inmemory/InMemoryHostSystem.java
 (original)
+++ 
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/inmemory/InMemoryHostSystem.java
 Tue Apr 27 19:43:40 2010
@@ -31,7 +31,7 @@ import org.apache.james.test.functional.
 
 public class InMemoryHostSystem extends ImapHostSystem {
 
-    private final StoreMailboxManager mailboxManager;
+    private final InMemoryMailboxManager mailboxManager;
     private final InMemoryUserManager userManager; 
     
     static HostSystem build() throws Exception {        
@@ -57,7 +57,7 @@ public class InMemoryHostSystem extends 
 
     @Override
     protected void resetData() throws Exception {
-        //mailboxManager.deleteEverything();
+        mailboxManager.deleteEverything();
     }
 
 }

Modified: 
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jpa/JPAHostSystem.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jpa/JPAHostSystem.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jpa/JPAHostSystem.java
 (original)
+++ 
james/imap/trunk/deployment/src/test/java/org/apache/james/imap/functional/jpa/JPAHostSystem.java
 Tue Apr 27 19:43:40 2010
@@ -30,6 +30,7 @@ import org.apache.james.imap.encode.main
 import org.apache.james.imap.functional.ImapHostSystem;
 import org.apache.james.imap.functional.InMemoryUserManager;
 import org.apache.james.imap.jpa.JPASubscriptionManager;
+import org.apache.james.imap.jpa.MailboxSessionEntityManagerFactory;
 import org.apache.james.imap.jpa.openjpa.OpenJPAMailboxManager;
 import org.apache.james.imap.mailbox.MailboxSession;
 import org.apache.james.imap.main.DefaultImapDecoderFactory;
@@ -68,7 +69,8 @@ public class JPAHostSystem extends ImapH
         
         userManager = new InMemoryUserManager();
         entityManagerFactory = 
OpenJPAPersistence.getEntityManagerFactory(properties);
-        mailboxManager = new OpenJPAMailboxManager(userManager, new 
JPASubscriptionManager(entityManagerFactory), entityManagerFactory);
+        MailboxSessionEntityManagerFactory factory = new 
MailboxSessionEntityManagerFactory(entityManagerFactory);
+        mailboxManager = new OpenJPAMailboxManager(userManager, new 
JPASubscriptionManager(factory), factory);
         
         final DefaultImapProcessorFactory defaultImapProcessorFactory = new 
DefaultImapProcessorFactory();
         resetUserMetaData();

Modified: 
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRGlobalUserMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRGlobalUserMailboxManager.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRGlobalUserMailboxManager.java
 (original)
+++ 
james/imap/trunk/jcr/src/main/java/org/apache/james/imap/jcr/JCRGlobalUserMailboxManager.java
 Tue Apr 27 19:43:40 2010
@@ -71,7 +71,6 @@ public class JCRGlobalUserMailboxManager
 
             public void run() throws MailboxException {
                 mapper.deleteAll(); 
-                mailboxes.clear();
             }
             
         });

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java 
(original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java 
Tue Apr 27 19:43:40 2010
@@ -25,7 +25,6 @@ import java.util.List;
 
 import javax.mail.Flags;
 import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
 
 import org.apache.james.imap.jpa.mail.JPAMailboxMapper;
 import org.apache.james.imap.jpa.mail.JPAMessageMapper;
@@ -50,9 +49,9 @@ import org.apache.james.imap.store.mail.
  */
 public abstract class JPAMailbox extends StoreMailbox<Long> {
 
-    protected final EntityManagerFactory entityManagerFactory;
+    protected final MailboxSessionEntityManagerFactory entityManagerFactory;
     
-    public JPAMailbox(final MailboxEventDispatcher dispatcher, final 
Mailbox<Long> mailbox, final EntityManagerFactory entityManagerfactory) {
+    public JPAMailbox(final MailboxEventDispatcher dispatcher, final 
Mailbox<Long> mailbox, final MailboxSessionEntityManagerFactory 
entityManagerfactory) {
         super(dispatcher, mailbox);
         this.entityManagerFactory = entityManagerfactory;        
     }  
@@ -73,10 +72,8 @@ public abstract class JPAMailbox extends
     
     @Override
     protected MessageMapper<Long> createMessageMapper(MailboxSession session) {
-        EntityManager manager = entityManagerFactory.createEntityManager();
-        
-        JPAUtils.addEntityManager(session, manager);
-        
+        EntityManager manager = entityManagerFactory.getEntityManager(session);
+                
         JPAMessageMapper mapper = new JPAMessageMapper(manager, 
getMailboxId());
        
         return mapper;
@@ -111,7 +108,7 @@ public abstract class JPAMailbox extends
      * Reserve next Uid in mailbox and return the mailbox. This method needs 
to be synchronized 
      * to be sure we don't get any race-condition
      */
-    protected synchronized Mailbox<Long> reserveNextUid(MailboxSession 
session) throws MailboxException {
+    protected Mailbox<Long> reserveNextUid(MailboxSession session) throws 
MailboxException {
         final JPAMailboxMapper mapper = createMailboxMapper(session);
         final Mailbox<Long> mailbox = mapper.consumeNextUid(getMailboxId());
         return mailbox;

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java
 (original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailboxManager.java
 Tue Apr 27 19:43:40 2010
@@ -18,10 +18,6 @@
  ****************************************************************/
 package org.apache.james.imap.jpa;
 
-import java.util.List;
-
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
 
 import org.apache.james.imap.mailbox.MailboxException;
 import org.apache.james.imap.mailbox.MailboxSession;
@@ -40,10 +36,10 @@ import org.apache.james.imap.store.trans
  */
 public abstract class JPAMailboxManager extends StoreMailboxManager<Long> {
 
-    protected final EntityManagerFactory entityManagerFactory;
+    protected final MailboxSessionEntityManagerFactory entityManagerFactory;
 
     public JPAMailboxManager(final Authenticator authenticator, final 
Subscriber subscriber, 
-            final EntityManagerFactory entityManagerFactory) {
+            final MailboxSessionEntityManagerFactory entityManagerFactory) {
         super(authenticator, subscriber);
         this.entityManagerFactory = entityManagerFactory;
     }
@@ -68,25 +64,17 @@ public abstract class JPAMailboxManager 
 
             public void run() throws MailboxException {
                 mapper.deleteAll(); 
-                mailboxes.clear();
             }
             
         });
     }
 
+    
     @Override
     public void endProcessingRequest(MailboxSession session) {
-        List<EntityManager> managers = JPAUtils.getEntityManagers(session);
-        for (int i = 0 ; i < managers.size(); i++) {
-            EntityManager manager = managers.get(i);
-            if (manager.isOpen()) {
-                try {
-                    manager.close();
-                } catch (Exception e) {
-                    // just catch exceptions on logout
-                }
-            }
-        }
+        // close the entityManager after each request so we are sure 
everything is flushed
+        entityManagerFactory.closeEntityManager(session);
+       
     }
     
     

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPASubscriptionManager.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPASubscriptionManager.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPASubscriptionManager.java
 (original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPASubscriptionManager.java
 Tue Apr 27 19:43:40 2010
@@ -19,7 +19,6 @@
 package org.apache.james.imap.jpa;
 
 import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
 
 import org.apache.james.imap.jpa.user.JPASubscriptionMapper;
 import org.apache.james.imap.jpa.user.model.JPASubscription;
@@ -34,9 +33,9 @@ import org.apache.james.imap.store.user.
  *
  */
 public class JPASubscriptionManager extends StoreSubscriptionManager {
-    private final EntityManagerFactory factory;
+    private final MailboxSessionEntityManagerFactory factory;
     
-    public JPASubscriptionManager(final EntityManagerFactory factory) {
+    public JPASubscriptionManager(final MailboxSessionEntityManagerFactory 
factory) {
         super();
         this.factory = factory;
     }
@@ -46,10 +45,8 @@ public class JPASubscriptionManager exte
      * @see 
org.apache.james.imap.store.StoreSubscriptionManager#createMapper(org.apache.james.imap.mailbox.MailboxSession)
      */
     protected SubscriptionMapper createMapper(MailboxSession session) {
-        EntityManager manager = factory.createEntityManager();
-        
-        JPAUtils.addEntityManager(session, manager);
-        
+        EntityManager manager = factory.getEntityManager(session);
+                
         JPASubscriptionMapper  mapper = new JPASubscriptionMapper(manager);
         
         return mapper;

Added: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/MailboxSessionEntityManagerFactory.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/MailboxSessionEntityManagerFactory.java?rev=938618&view=auto
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/MailboxSessionEntityManagerFactory.java
 (added)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/MailboxSessionEntityManagerFactory.java
 Tue Apr 27 19:43:40 2010
@@ -0,0 +1,35 @@
+package org.apache.james.imap.jpa;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+import org.apache.james.imap.mailbox.MailboxSession;
+
+public class MailboxSessionEntityManagerFactory {
+
+    private EntityManagerFactory factory;
+    private final static String ENTITYMANAGER = "ENTITYMANAGER";
+    
+    public MailboxSessionEntityManagerFactory(EntityManagerFactory factory) {
+        this.factory = factory;
+    }
+    
+    public EntityManager getEntityManager(MailboxSession session) {
+        EntityManager manager = (EntityManager) 
session.getAttributes().get(ENTITYMANAGER);
+        if (manager == null || manager.isOpen() == false) {
+            manager = factory.createEntityManager();
+            session.getAttributes().put(ENTITYMANAGER, manager);
+        } 
+        
+        return manager;
+    }
+    
+    public void closeEntityManager(MailboxSession session) {
+        if (session != null) {
+            EntityManager manager = (EntityManager) 
session.getAttributes().remove(ENTITYMANAGER);
+            if ( manager != null && manager.isOpen()) {
+                manager.close();
+            }
+        } 
+    }
+}

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java
 (original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/JPAMailboxMapper.java
 Tue Apr 27 19:43:40 2010
@@ -150,6 +150,7 @@ public abstract class JPAMailboxMapper e
         } catch (NoResultException e) {
             throw new MailboxNotFoundException(mailboxId);
         } catch (PersistenceException e) {
+            e.printStackTrace();
             throw new StorageException(HumanReadableText.COMSUME_UID_FAILED, 
e);
         } 
     }

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/openjpa/OpenJPAMailboxMapper.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/openjpa/OpenJPAMailboxMapper.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/openjpa/OpenJPAMailboxMapper.java
 (original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/openjpa/OpenJPAMailboxMapper.java
 Tue Apr 27 19:43:40 2010
@@ -23,11 +23,9 @@ import javax.persistence.EntityManager;
 
 import org.apache.james.imap.jpa.mail.JPAMailboxMapper;
 import org.apache.james.imap.jpa.mail.model.JPAMailbox;
-import org.apache.openjpa.persistence.OpenJPAEntityManager;
-import org.apache.openjpa.persistence.OpenJPAPersistence;
 
 /**
- * OpenJPA implemetnation of MailboxMapper.
+ * OpenJPA implementation of MailboxMapper.
  */
 public class OpenJPAMailboxMapper extends JPAMailboxMapper {
     
@@ -40,18 +38,10 @@ public class OpenJPAMailboxMapper extend
      * @see 
org.apache.james.imap.jpa.mail.JPAMailboxMapper#doConsumeNextUid(long)
      */
     public JPAMailbox doConsumeNextUid(long mailboxId) {
-        OpenJPAEntityManager oem = OpenJPAPersistence.cast(entityManager);
-        final boolean originalLocking = oem.getOptimistic();
-        oem.setOptimistic(false);
-        oem.getTransaction().begin();
-        try {
-            JPAMailbox mailbox = (JPAMailbox) 
entityManager.createNamedQuery("findMailboxById").setParameter("idParam", 
mailboxId).getSingleResult();
-            mailbox.consumeUid();
-            oem.persist(mailbox);
-            oem.getTransaction().commit();
-            return mailbox;
-        } finally {
-            oem.setOptimistic(originalLocking);
-        }
+        JPAMailbox mailbox = (JPAMailbox) 
entityManager.createNamedQuery("findMailboxById").setParameter("idParam", 
mailboxId).getSingleResult();
+        mailbox.consumeUid();
+        entityManager.persist(mailbox);
+        return mailbox;
+        
     }
 }

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java
 (original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailbox.java
 Tue Apr 27 19:43:40 2010
@@ -26,10 +26,9 @@ import java.util.List;
 
 import javax.mail.Flags;
 import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
 
 import org.apache.james.imap.jpa.JPAMailbox;
-import org.apache.james.imap.jpa.JPAUtils;
+import org.apache.james.imap.jpa.MailboxSessionEntityManagerFactory;
 import org.apache.james.imap.jpa.mail.JPAMailboxMapper;
 import org.apache.james.imap.jpa.mail.model.AbstractJPAMailboxMembership;
 import org.apache.james.imap.jpa.mail.model.JPAHeader;
@@ -49,13 +48,12 @@ import org.apache.james.imap.store.mail.
  */
 public class OpenJPAMailbox extends JPAMailbox{
 
-    public final static String MAILBOX_MAPPER = "MAILBOX_MAPPER";
     private final boolean useStreaming;
-    public OpenJPAMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> 
mailbox,  EntityManagerFactory entityManagerfactory) {
+    public OpenJPAMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> 
mailbox,  MailboxSessionEntityManagerFactory entityManagerfactory) {
                this(dispatcher, mailbox, entityManagerfactory, false);
        }
 
-    public OpenJPAMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> 
mailbox, EntityManagerFactory entityManagerfactory, final boolean useStreaming) 
{
+    public OpenJPAMailbox(MailboxEventDispatcher dispatcher, Mailbox<Long> 
mailbox, MailboxSessionEntityManagerFactory entityManagerfactory, final boolean 
useStreaming) {
         super(dispatcher, mailbox, entityManagerfactory);
         this.useStreaming = useStreaming;
     }
@@ -65,10 +63,8 @@ public class OpenJPAMailbox extends JPAM
      * @see 
org.apache.james.imap.jpa.JPAMailbox#createMailboxMapper(org.apache.james.imap.mailbox.MailboxSession)
      */
        protected JPAMailboxMapper createMailboxMapper(MailboxSession session) {
-           EntityManager manager = entityManagerFactory.createEntityManager();
-           
-           JPAUtils.addEntityManager(session, manager);
-           
+           EntityManager manager = 
entityManagerFactory.getEntityManager(session);
+                   
         JPAMailboxMapper mapper = new OpenJPAMailboxMapper(manager);
 
         return mapper;

Modified: 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java
 (original)
+++ 
james/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/openjpa/OpenJPAMailboxManager.java
 Tue Apr 27 19:43:40 2010
@@ -20,10 +20,9 @@
 package org.apache.james.imap.jpa.openjpa;
 
 import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
 
 import org.apache.james.imap.jpa.JPAMailboxManager;
-import org.apache.james.imap.jpa.JPAUtils;
+import org.apache.james.imap.jpa.MailboxSessionEntityManagerFactory;
 import org.apache.james.imap.jpa.mail.openjpa.OpenJPAMailboxMapper;
 import org.apache.james.imap.mailbox.MailboxSession;
 import org.apache.james.imap.mailbox.util.MailboxEventDispatcher;
@@ -41,19 +40,18 @@ public class OpenJPAMailboxManager exten
 
     private boolean useStreaming;
 
-    public OpenJPAMailboxManager(Authenticator authenticator, Subscriber 
subscriber, EntityManagerFactory entityManagerFactory, boolean useStreaming) {
+    public OpenJPAMailboxManager(Authenticator authenticator, Subscriber 
subscriber, MailboxSessionEntityManagerFactory entityManagerFactory, boolean 
useStreaming) {
         super(authenticator, subscriber, entityManagerFactory);
         this.useStreaming = useStreaming;
     }
 
-    public OpenJPAMailboxManager(Authenticator authenticator, Subscriber 
subscriber, EntityManagerFactory entityManagerFactory) {
+    public OpenJPAMailboxManager(Authenticator authenticator, Subscriber 
subscriber, MailboxSessionEntityManagerFactory entityManagerFactory) {
         this(authenticator, subscriber, entityManagerFactory, false);
     }
 
     @Override
     protected MailboxMapper<Long> createMailboxMapper(MailboxSession session) {
-        EntityManager manager = entityManagerFactory.createEntityManager();
-        JPAUtils.addEntityManager(session, manager);
+        EntityManager manager = entityManagerFactory.getEntityManager(session);
         return new OpenJPAMailboxMapper(manager);
     }
 

Modified: 
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java
 (original)
+++ 
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryMailboxManager.java
 Tue Apr 27 19:43:40 2010
@@ -69,7 +69,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see 
org.apache.james.imap.store.mail.MailboxMapper#countMailboxesWithName(java.lang.String)
      */
-    public long countMailboxesWithName(String name) throws StorageException {
+    public synchronized long countMailboxesWithName(String name) throws 
StorageException {
         int total = 0;
         for (final InMemoryMailbox mailbox:mailboxesById.values()) {
             if (mailbox.getName().equals(name)) {
@@ -83,7 +83,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see 
org.apache.james.imap.store.mail.MailboxMapper#delete(org.apache.james.imap.store.mail.model.Mailbox)
      */
-    public void delete(Mailbox<Long> mailbox) throws StorageException {
+    public synchronized void delete(Mailbox<Long> mailbox) throws 
StorageException {
         mailboxesById.remove(mailbox.getMailboxId());
     }
 
@@ -91,7 +91,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see org.apache.james.imap.store.mail.MailboxMapper#deleteAll()
      */
-    public void deleteAll() throws StorageException {
+    public synchronized void deleteAll() throws StorageException {
         mailboxesById.clear();
     }
 
@@ -100,7 +100,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see 
org.apache.james.imap.store.mail.MailboxMapper#findMailboxById(java.lang.Object)
      */
-    public Mailbox<Long> findMailboxById(Long mailboxId) throws 
StorageException, MailboxNotFoundException {
+    public synchronized Mailbox<Long> findMailboxById(Long mailboxId) throws 
StorageException, MailboxNotFoundException {
         return mailboxesById.get(mailboxesById);
     }
 
@@ -108,7 +108,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see 
org.apache.james.imap.store.mail.MailboxMapper#findMailboxByName(java.lang.String)
      */
-    public Mailbox<Long> findMailboxByName(String name) throws 
StorageException, MailboxNotFoundException {
+    public synchronized Mailbox<Long> findMailboxByName(String name) throws 
StorageException, MailboxNotFoundException {
         Mailbox<Long> result = null;
         for (final InMemoryMailbox mailbox:mailboxesById.values()) {
             if (mailbox.getName().equals(name)) {
@@ -123,7 +123,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see 
org.apache.james.imap.store.mail.MailboxMapper#findMailboxWithNameLike(java.lang.String)
      */
-    public List<Mailbox<Long>> findMailboxWithNameLike(String name) throws 
StorageException {
+    public synchronized List<Mailbox<Long>> findMailboxWithNameLike(String 
name) throws StorageException {
         final String regex = name.replace("%", ".*");
         List<Mailbox<Long>> results = new ArrayList<Mailbox<Long>>();
         for (final InMemoryMailbox mailbox:mailboxesById.values()) {
@@ -138,7 +138,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see 
org.apache.james.imap.store.mail.MailboxMapper#existsMailboxStartingWith(java.lang.String)
      */
-    public boolean existsMailboxStartingWith(String mailboxName) throws 
StorageException {
+    public synchronized boolean existsMailboxStartingWith(String mailboxName) 
throws StorageException {
         boolean result = false;
         for (final InMemoryMailbox mailbox:mailboxesById.values()) {
             if (mailbox.getName().startsWith(mailboxName)) {
@@ -153,7 +153,7 @@ public class InMemoryMailboxManager exte
      * (non-Javadoc)
      * @see 
org.apache.james.imap.store.mail.MailboxMapper#save(org.apache.james.imap.store.mail.model.Mailbox)
      */
-    public void save(Mailbox<Long> mailbox) throws StorageException {
+    public synchronized void save(Mailbox<Long> mailbox) throws 
StorageException {
         mailboxesById.put(mailbox.getMailboxId(), (InMemoryMailbox) mailbox);
     }
 
@@ -171,13 +171,12 @@ public class InMemoryMailboxManager exte
      * @throws MailboxException
      */
 
-    public void deleteEverything() throws MailboxException {
+    public synchronized void deleteEverything() throws MailboxException {
         final MailboxMapper<Long> mapper = createMailboxMapper(null);
         mapper.execute(new TransactionalMapper.Transaction() {
 
             public void run() throws MailboxException {
                 mapper.deleteAll(); 
-                mailboxes.clear();
             }
             
         });

Modified: 
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java
 (original)
+++ 
james/imap/trunk/memory/src/main/java/org/apache/james/imap/inmemory/InMemoryStoreMailbox.java
 Tue Apr 27 19:43:40 2010
@@ -56,6 +56,7 @@ public class InMemoryStoreMailbox extend
         this.mailbox = mailbox;
         this.membershipByUid = new ConcurrentHashMap<Long, 
MailboxMembership<Long>>(INITIAL_SIZE);
     }
+    
 
     @Override
     protected MailboxMembership<Long> copyMessage(MailboxMembership<Long> 
originalMessage, long uid, MailboxSession session) {

Added: 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/DelegatingMailboxListener.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/DelegatingMailboxListener.java?rev=938618&view=auto
==============================================================================
--- 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/DelegatingMailboxListener.java
 (added)
+++ 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/DelegatingMailboxListener.java
 Tue Apr 27 19:43:40 2010
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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.imap.store;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.james.imap.mailbox.MailboxListener;
+
+/**
+ * Receive a {...@link Event} and delegate it to an other {...@link 
MailboxListener} depending on the registered name
+ *
+ */
+public class DelegatingMailboxListener implements MailboxListener{
+
+    private Map<String,List<MailboxListener>> listeners = new HashMap<String, 
List<MailboxListener>>();
+
+    public synchronized void addListener(String name, MailboxListener 
listener) {
+        List<MailboxListener> mListeners = listeners.get(name);
+        if (mListeners == null) {
+            mListeners = new ArrayList<MailboxListener>();
+            listeners.put(name, mListeners);
+        }
+        if (mListeners.contains(listener) == false) {
+            mListeners.add(listener);
+        }
+    }
+    
+    
+    /*
+     * (non-Javadoc)
+     * @see 
org.apache.james.imap.mailbox.MailboxListener#event(org.apache.james.imap.mailbox.MailboxListener.Event)
+     */
+    public synchronized void event(Event event) {
+        List<MailboxListener> mListeners = 
listeners.get(event.getMailboxName());
+        if (mListeners != null && mListeners.isEmpty() == false) {
+            for (int i = 0; i < mListeners.size(); i++) {
+                MailboxListener l = mListeners.get(i);
+                if (l.isClosed()) {
+                    mListeners.remove(l);
+                } else {
+                    l.event(event);
+                }
+            }
+        }
+    }
+
+    /**
+     * Is never closed
+     */
+    public boolean isClosed() {
+        return false;
+    }
+    
+}

Modified: 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
 (original)
+++ 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
 Tue Apr 27 19:43:40 2010
@@ -145,166 +145,165 @@ public abstract class StoreMailbox<Id> i
      * (non-Javadoc)
      * @see org.apache.james.imap.mailbox.Mailbox#appendMessage(byte[], 
java.util.Date, org.apache.james.imap.mailbox.MailboxSession, boolean, 
javax.mail.Flags)
      */
-    public long appendMessage(InputStream msgIn, Date internalDate,
-            MailboxSession mailboxSession, boolean isRecent, Flags 
flagsToBeSet)
+    public long appendMessage(final InputStream msgIn, final Date internalDate,
+            final MailboxSession mailboxSession,final boolean isRecent, final 
Flags flagsToBeSet)
     throws MailboxException {
-
-        final Mailbox<Id> mailbox = reserveNextUid(mailboxSession);
-        if (mailbox == null) {
-            throw new MailboxNotFoundException("Mailbox has been deleted");
-        } else {
-           
-            
-            File file = null;
-            try {
-                // Create a temporary file and copy the message to it. We will 
work with the file as
-                // source for the InputStream
-                file = File.createTempFile("imap", ".msg");
-                FileOutputStream out = new FileOutputStream(file);
-                
-                byte[] buf = new byte[1024];
-                int i = 0;
-                while ((i = msgIn.read(buf)) != -1) {
-                    out.write(buf, 0, i);
-                }
-                out.flush();
-                out.close();
-                
-                FileInputStream tmpMsgIn = new FileInputStream(file);
-                // To be thread safe, we first get our own copy and the
-                // exclusive
-                // Uid
-                // TODO create own message_id and assign uid later
-                // at the moment it could lead to the situation that uid 5
-                // is
-                // inserted long before 4, when
-                // mail 4 is big and comes over a slow connection.
-
-                final long uid = mailbox.getLastUid();
-                final int size = tmpMsgIn.available();
-                final int bodyStartOctet = bodyStartOctet(new 
FileInputStream(file));
-
-                // Disable line length... This should be handled by the smtp 
server component and not the parser itself
-                // https://issues.apache.org/jira/browse/IMAP-122
-                MimeEntityConfig config = new MimeEntityConfig();
-                config.setMaximalBodyDescriptor(true);
-                config.setMaxLineLen(-1);
-                final ConfigurableMimeTokenStream parser = new 
ConfigurableMimeTokenStream(config);
-               
-                parser.setRecursionMode(MimeTokenStream.M_NO_RECURSE);
-                parser.parse(new FileInputStream(file));
-                final List<Header> headers = new 
ArrayList<Header>(INITIAL_SIZE_HEADERS);
+        // this will hold the uid after the transaction was complete
+        final List<Long> uidHolder = new ArrayList<Long>();
+        final MessageMapper<Id> mapper = createMessageMapper(mailboxSession);
+        mapper.execute(new TransactionalMapper.Transaction() {
+          
+            public void run() throws MailboxException {
+                final Mailbox<Id> mailbox = reserveNextUid(mailboxSession);
                 
-                int lineNumber = 0;
-                int next = parser.next();
-                while (next != MimeTokenStream.T_BODY
-                        && next != MimeTokenStream.T_END_OF_STREAM
-                        && next != MimeTokenStream.T_START_MULTIPART) {
-                    if (next == MimeTokenStream.T_FIELD) {
-                        String fieldValue = parser.getField().getBody();
-                        if (fieldValue.endsWith("\r\f")) {
-                            fieldValue = 
fieldValue.substring(0,fieldValue.length() - 2);
+                File file = null;
+                try {
+                    // Create a temporary file and copy the message to it. We 
will work with the file as
+                    // source for the InputStream
+                    file = File.createTempFile("imap", ".msg");
+                    FileOutputStream out = new FileOutputStream(file);
+                    
+                    byte[] buf = new byte[1024];
+                    int i = 0;
+                    while ((i = msgIn.read(buf)) != -1) {
+                        out.write(buf, 0, i);
+                    }
+                    out.flush();
+                    out.close();
+                    
+                    FileInputStream tmpMsgIn = new FileInputStream(file);
+                    // To be thread safe, we first get our own copy and the
+                    // exclusive
+                    // Uid
+                    // TODO create own message_id and assign uid later
+                    // at the moment it could lead to the situation that uid 5
+                    // is
+                    // inserted long before 4, when
+                    // mail 4 is big and comes over a slow connection.
+
+                    final long uid = mailbox.getLastUid();
+                    final int size = tmpMsgIn.available();
+                    final int bodyStartOctet = bodyStartOctet(new 
FileInputStream(file));
+
+                    // Disable line length... This should be handled by the 
smtp server component and not the parser itself
+                    // https://issues.apache.org/jira/browse/IMAP-122
+                    MimeEntityConfig config = new MimeEntityConfig();
+                    config.setMaximalBodyDescriptor(true);
+                    config.setMaxLineLen(-1);
+                    final ConfigurableMimeTokenStream parser = new 
ConfigurableMimeTokenStream(config);
+                   
+                    parser.setRecursionMode(MimeTokenStream.M_NO_RECURSE);
+                    parser.parse(new FileInputStream(file));
+                    final List<Header> headers = new 
ArrayList<Header>(INITIAL_SIZE_HEADERS);
+                    
+                    int lineNumber = 0;
+                    int next = parser.next();
+                    while (next != MimeTokenStream.T_BODY
+                            && next != MimeTokenStream.T_END_OF_STREAM
+                            && next != MimeTokenStream.T_START_MULTIPART) {
+                        if (next == MimeTokenStream.T_FIELD) {
+                            String fieldValue = parser.getField().getBody();
+                            if (fieldValue.endsWith("\r\f")) {
+                                fieldValue = 
fieldValue.substring(0,fieldValue.length() - 2);
+                            }
+                            if (fieldValue.startsWith(" ")) {
+                                fieldValue = fieldValue.substring(1);
+                            }
+                            final Header header 
+                                = createHeader(++lineNumber, 
parser.getField().getName(), 
+                                    fieldValue);
+                            headers.add(header);
                         }
-                        if (fieldValue.startsWith(" ")) {
-                            fieldValue = fieldValue.substring(1);
+                        next = parser.next();
+                    }
+                    final MaximalBodyDescriptor descriptor = 
(MaximalBodyDescriptor) parser.getBodyDescriptor();
+                    final PropertyBuilder propertyBuilder = new 
PropertyBuilder();
+                    final String mediaType;
+                    final String mediaTypeFromHeader = 
descriptor.getMediaType();
+                    final String subType;
+                    if (mediaTypeFromHeader == null) {
+                        mediaType = "text";
+                        subType = "plain";
+                    } else {
+                        mediaType = mediaTypeFromHeader;
+                        subType = descriptor.getSubType();
+                    }
+                    propertyBuilder.setMediaType(mediaType);
+                    propertyBuilder.setSubType(subType);
+                    propertyBuilder.setContentID(descriptor.getContentId());
+                    
propertyBuilder.setContentDescription(descriptor.getContentDescription());
+                    
propertyBuilder.setContentLocation(descriptor.getContentLocation());
+                    
propertyBuilder.setContentMD5(descriptor.getContentMD5Raw());
+                    
propertyBuilder.setContentTransferEncoding(descriptor.getTransferEncoding());
+                    
propertyBuilder.setContentLanguage(descriptor.getContentLanguage());
+                    
propertyBuilder.setContentDispositionType(descriptor.getContentDispositionType());
+                    
propertyBuilder.setContentDispositionParameters(descriptor.getContentDispositionParameters());
+                    
propertyBuilder.setContentTypeParameters(descriptor.getContentTypeParameters());
+                    // Add missing types
+                    final String codeset = descriptor.getCharset();
+                    if (codeset == null) {
+                        if ("TEXT".equalsIgnoreCase(mediaType)) {
+                            propertyBuilder.setCharset("us-ascii");
                         }
-                        final Header header 
-                            = createHeader(++lineNumber, 
parser.getField().getName(), 
-                                fieldValue);
-                        headers.add(header);
+                    } else {
+                        propertyBuilder.setCharset(codeset);
                     }
-                    next = parser.next();
-                }
-                final MaximalBodyDescriptor descriptor = 
(MaximalBodyDescriptor) parser.getBodyDescriptor();
-                final PropertyBuilder propertyBuilder = new PropertyBuilder();
-                final String mediaType;
-                final String mediaTypeFromHeader = descriptor.getMediaType();
-                final String subType;
-                if (mediaTypeFromHeader == null) {
-                    mediaType = "text";
-                    subType = "plain";
-                } else {
-                    mediaType = mediaTypeFromHeader;
-                    subType = descriptor.getSubType();
-                }
-                propertyBuilder.setMediaType(mediaType);
-                propertyBuilder.setSubType(subType);
-                propertyBuilder.setContentID(descriptor.getContentId());
-                
propertyBuilder.setContentDescription(descriptor.getContentDescription());
-                
propertyBuilder.setContentLocation(descriptor.getContentLocation());
-                propertyBuilder.setContentMD5(descriptor.getContentMD5Raw());
-                
propertyBuilder.setContentTransferEncoding(descriptor.getTransferEncoding());
-                
propertyBuilder.setContentLanguage(descriptor.getContentLanguage());
-                
propertyBuilder.setContentDispositionType(descriptor.getContentDispositionType());
-                
propertyBuilder.setContentDispositionParameters(descriptor.getContentDispositionParameters());
-                
propertyBuilder.setContentTypeParameters(descriptor.getContentTypeParameters());
-                // Add missing types
-                final String codeset = descriptor.getCharset();
-                if (codeset == null) {
-                    if ("TEXT".equalsIgnoreCase(mediaType)) {
-                        propertyBuilder.setCharset("us-ascii");
+                    
+                    final String boundary = descriptor.getBoundary();
+                    if (boundary != null) {
+                        propertyBuilder.setBoundary(boundary);
+                    }   
+                    if ("text".equalsIgnoreCase(mediaType)) {
+                        final CountingInputStream bodyStream = new 
CountingInputStream(parser.getInputStream());
+                        bodyStream.readAll();
+                        long lines = bodyStream.getLineCount();
+                        
+                        next = parser.next();
+                        if (next == MimeTokenStream.T_EPILOGUE)  {
+                            final CountingInputStream epilogueStream = new 
CountingInputStream(parser.getInputStream());
+                            epilogueStream.readAll();
+                            lines+=epilogueStream.getLineCount();
+                        }
+                        propertyBuilder.setTextualLineCount(lines);
                     }
-                } else {
-                    propertyBuilder.setCharset(codeset);
-                }
-                
-                final String boundary = descriptor.getBoundary();
-                if (boundary != null) {
-                    propertyBuilder.setBoundary(boundary);
-                }   
-                if ("text".equalsIgnoreCase(mediaType)) {
-                    final CountingInputStream bodyStream = new 
CountingInputStream(parser.getInputStream());
-                    bodyStream.readAll();
-                    long lines = bodyStream.getLineCount();
                     
-                    next = parser.next();
-                    if (next == MimeTokenStream.T_EPILOGUE)  {
-                        final CountingInputStream epilogueStream = new 
CountingInputStream(parser.getInputStream());
-                        epilogueStream.readAll();
-                        lines+=epilogueStream.getLineCount();
+                    final Flags flags;
+                    if (flagsToBeSet == null) {
+                        flags = new Flags();
+                    } else {
+                        flags = flagsToBeSet;
                     }
-                    propertyBuilder.setTextualLineCount(lines);
-                }
-                
-                final Flags flags;
-                if (flagsToBeSet == null) {
-                    flags = new Flags();
-                } else {
-                    flags = flagsToBeSet;
-                }
-                if (isRecent) {
-                    flags.add(Flags.Flag.RECENT);
-                }
-                
-                final MailboxMembership<Id> message = 
createMessage(internalDate, uid, size, bodyStartOctet, new 
FileInputStream(file), flags, headers, propertyBuilder);
-                final MessageMapper<Id> mapper = 
createMessageMapper(mailboxSession);
-
-                mapper.execute(new TransactionalMapper.Transaction() {
-
-                    public void run() throws MailboxException {
-                        mapper.save(message);
+                    if (isRecent) {
+                        flags.add(Flags.Flag.RECENT);
                     }
                     
-                });
-                dispatcher.added(uid, mailboxSession.getSessionId(), 
getMailboxRow(mailboxSession).getName());
-                //tracker.found(uid, message.createFlags());
-                return uid;
-            } catch (IOException e) {
-                e.printStackTrace();
-                throw new 
MailboxException(HumanReadableText.FAILURE_MAIL_PARSE, e);
-            } catch (MessagingException e) {
-                e.printStackTrace();
-                throw new 
MailboxException(HumanReadableText.FAILURE_MAIL_PARSE, e);
-            } catch (MimeException e) {
-                e.printStackTrace();
-                throw new 
MailboxException(HumanReadableText.FAILURE_MAIL_PARSE, e);
-            } finally {
-                // delete the temporary file if one was specified
-                if (file != null) {
-                    file.delete();
+                    final MailboxMembership<Id> message = 
createMessage(internalDate, uid, size, bodyStartOctet, new 
FileInputStream(file), flags, headers, propertyBuilder);
+                    mapper.save(message);
+                       
+                        
+                   
+                    dispatcher.added(uid, mailboxSession.getSessionId(), 
getMailboxRow(mailboxSession).getName());
+                    //tracker.found(uid, message.createFlags());
+                    uidHolder.add(uid);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    throw new 
MailboxException(HumanReadableText.FAILURE_MAIL_PARSE, e);
+                } catch (MessagingException e) {
+                    e.printStackTrace();
+                    throw new 
MailboxException(HumanReadableText.FAILURE_MAIL_PARSE, e);
+                } catch (MimeException e) {
+                    e.printStackTrace();
+                    throw new 
MailboxException(HumanReadableText.FAILURE_MAIL_PARSE, e);
+                } finally {
+                    // delete the temporary file if one was specified
+                    if (file != null) {
+                        file.delete();
+                    }
                 }
             }
-        }
+        });
+       
+        return uidHolder.get(0);
     }
 
     /**

Modified: 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailboxManager.java?rev=938618&r1=938617&r2=938618&view=diff
==============================================================================
--- 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailboxManager.java
 (original)
+++ 
james/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailboxManager.java
 Tue Apr 27 19:43:40 2010
@@ -22,10 +22,8 @@ package org.apache.james.imap.store;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Random;
 
 import org.apache.commons.logging.Log;
@@ -65,17 +63,16 @@ public abstract class StoreMailboxManage
     
     public static final char SQL_WILDCARD_CHAR = '%';
 
+    private final Object mutex = new Object();
+    
     private final static Random random = new Random();
 
-    protected final Map<String, StoreMailbox<Id>> mailboxes;
     private final MailboxEventDispatcher dispatcher = new 
MailboxEventDispatcher();
-    
+    private final DelegatingMailboxListener delegatingListener = new 
DelegatingMailboxListener();
     private final Authenticator authenticator;    
     private final Subscriber subscriber;    
     
     private final char delimiter;
-
-    public final static String MAILBOX = "MAILBOX";
     
     public StoreMailboxManager(final Authenticator authenticator, final 
Subscriber subscriber) {
         this(authenticator, subscriber, '.');
@@ -83,7 +80,6 @@ public abstract class StoreMailboxManage
 
     
     public StoreMailboxManager(final Authenticator authenticator, final 
Subscriber subscriber, final char delimiter) {
-        mailboxes = new HashMap<String, StoreMailbox<Id>>();
         this.authenticator = authenticator;
         this.subscriber = subscriber;
         this.delimiter = delimiter;
@@ -130,7 +126,7 @@ public abstract class StoreMailboxManage
      * @throws MailboxException get thrown if no Mailbox could be found for 
the given name
      */
     private StoreMailbox<Id> doGetMailbox(String mailboxName, MailboxSession 
session) throws MailboxException {
-        synchronized (mailboxes) {
+        synchronized (mutex) {
             final MailboxMapper<Id> mapper = createMailboxMapper(session);
             Mailbox<Id> mailboxRow = mapper.findMailboxByName(mailboxName);
             
@@ -141,14 +137,8 @@ public abstract class StoreMailboxManage
             } else {
                 getLog().debug("Loaded mailbox " + mailboxName);
 
-                StoreMailbox<Id> result = (StoreMailbox<Id>) 
mailboxes.get(mailboxName);
-                if (result == null) {
-                    result = createMailbox(dispatcher, mailboxRow);
-                    mailboxes.put(mailboxName, result);
-                    
-                    // store the mailbox in the session so we can cleanup 
things later
-                    //session.getAttributes().put(MAILBOX, result);
-                }
+                StoreMailbox<Id> result = createMailbox(dispatcher, 
mailboxRow);
+                result.addListener(delegatingListener);
                 return result;
             }
         }
@@ -167,7 +157,7 @@ public abstract class StoreMailboxManage
         } else if (namespaceName.charAt(length - 1) == delimiter) {
             createMailbox(namespaceName.substring(0, length - 1), 
mailboxSession);
         } else {
-            synchronized (mailboxes) {
+            synchronized (mutex) {
                 // Create root first
                 // If any creation fails then mailbox will not be created
                 // TODO: transaction
@@ -203,7 +193,7 @@ public abstract class StoreMailboxManage
     public void deleteMailbox(final String mailboxName, final MailboxSession 
session)
     throws MailboxException {
         session.getLog().info("deleteMailbox " + mailboxName);
-        synchronized (mailboxes) {
+        synchronized (mutex) {
             // TODO put this into a serilizable transaction
             
             final MailboxMapper<Id> mapper = createMailboxMapper(session);
@@ -220,10 +210,6 @@ public abstract class StoreMailboxManage
                 
             });
             
-            final StoreMailbox<Id> storeMailbox = 
mailboxes.remove(mailboxName);
-            if (storeMailbox != null) {
-                //storeMailbox.deleted(session);
-            }
             dispatcher.mailboxDeleted(session.getSessionId(), mailboxName);
         }
     }
@@ -236,7 +222,7 @@ public abstract class StoreMailboxManage
     throws MailboxException {
         final Log log = getLog();
         if (log.isDebugEnabled()) log.debug("renameMailbox " + from + " to " + 
to);
-        synchronized (mailboxes) {
+        synchronized (mutex) {
             if (mailboxExists(to, session)) {
                 throw new MailboxExistsException(to);
             }
@@ -290,11 +276,6 @@ public abstract class StoreMailboxManage
      * @param to not null
      */
     private void changeMailboxName(String from, String to, MailboxSession 
session) {
-        final StoreMailbox<Id> jpaMailbox = mailboxes.remove(from);
-        if (jpaMailbox != null) {
-            //jpaMailbox.reportRenamed(to);
-        }
-        mailboxes.put(to, jpaMailbox);
         dispatcher.mailboxRenamed(from, to, session.getSessionId());
     }
 
@@ -304,9 +285,12 @@ public abstract class StoreMailboxManage
      */
     public void copyMessages(MessageRange set, String from, String to,
             MailboxSession session) throws MailboxException {
+        synchronized (mutex) {
+
         StoreMailbox<Id> toMailbox = doGetMailbox(to, session);
         StoreMailbox<Id> fromMailbox = doGetMailbox(from, session);
-        fromMailbox.copyTo(set, toMailbox, session);
+            fromMailbox.copyTo(set, toMailbox, session);
+        }
     }
 
     /*
@@ -368,11 +352,10 @@ public abstract class StoreMailboxManage
      * @see 
org.apache.james.imap.mailbox.MailboxManager#mailboxExists(java.lang.String, 
org.apache.james.imap.mailbox.MailboxSession)
      */
     public boolean mailboxExists(String mailboxName, MailboxSession session) 
throws MailboxException {
-        synchronized (mailboxes) {
+        synchronized (mutex) {
             final MailboxMapper<Id> mapper = createMailboxMapper(session);
             final long count = mapper.countMailboxesWithName(mailboxName);
             if (count == 0) {
-                mailboxes.remove(mailboxName);
                 return false;
             } else {
                 if (count == 1) {
@@ -472,8 +455,7 @@ public abstract class StoreMailboxManage
      * @see 
org.apache.james.imap.mailbox.MailboxManager#addListener(java.lang.String, 
org.apache.james.imap.mailbox.MailboxListener, 
org.apache.james.imap.mailbox.MailboxSession)
      */
     public void addListener(String mailboxName, MailboxListener listener, 
MailboxSession session) throws MailboxException {
-        final StoreMailbox<Id> mailbox = doGetMailbox(mailboxName,session);
-        mailbox.addListener(listener);
+        delegatingListener.addListener(mailboxName, listener);
     }
 
 



---------------------------------------------------------------------
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