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 ro...@apache.org on 2016/11/23 13:50:09 UTC

[06/46] james-project git commit: JAMES-1854 Sieve usage should be optional

JAMES-1854 Sieve usage should be optional

This is done threw extracting the "storing mail" capability, and includes a tested SimpleMailStorer


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

Branch: refs/heads/master
Commit: 989d60e676bec7d17a26157d2d55ca4d89998b3a
Parents: 58ef3d2
Author: Benoit Tellier <bt...@linagora.com>
Authored: Fri Oct 28 14:31:52 2016 +0200
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Fri Nov 18 18:46:46 2016 +0700

----------------------------------------------------------------------
 server/mailet/mailets/pom.xml                   |  22 +++
 .../mailets/delivery/DeliveryUtils.java         |   4 -
 .../mailets/delivery/LocalDelivery.java         |  17 +-
 .../mailets/delivery/MailboxAppender.java       | 113 +++++++++++
 .../mailets/delivery/SieveLocalDelivery.java    | 118 ++++++++++++
 .../transport/mailets/delivery/SievePoster.java |  73 +------
 .../delivery/SieveToRecipientFolder.java        | 111 +++++++++++
 .../mailets/delivery/SimpleMailStorer.java      |  93 +++++++++
 .../mailets/delivery/ToRecipientFolder.java     |  17 +-
 .../mailets/delivery/LocalDeliveryTest.java     | 187 ------------------
 .../mailets/delivery/MailboxAppenderTest.java   | 176 +++++++++++++++++
 .../mailets/delivery/SieveIntegrationTest.java  |   9 +-
 .../delivery/SieveLocalDeliveryTest.java        | 152 +++++++++++++++
 .../delivery/SieveToRecipientFolderTest.java    | 187 ++++++++++++++++++
 .../mailets/delivery/SimpleMailStorerTest.java  | 121 ++++++++++++
 .../mailets/delivery/ToRecipientFolderTest.java | 189 -------------------
 16 files changed, 1109 insertions(+), 480 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/pom.xml
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml
index 97f88fd..6b4394a 100644
--- a/server/mailet/mailets/pom.xml
+++ b/server/mailet/mailets/pom.xml
@@ -167,6 +167,28 @@
             <type>test-jar</type>
         </dependency>
         <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-store</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-store</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.james</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <version>${assertj-1.version}</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/DeliveryUtils.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/DeliveryUtils.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/DeliveryUtils.java
index 9c1abef..72fb609 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/DeliveryUtils.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/DeliveryUtils.java
@@ -17,12 +17,8 @@
  * under the License.                                           *
  ****************************************************************/
 
-
 package org.apache.james.transport.mailets.delivery;
 
-import org.apache.commons.logging.Log;
-import org.apache.james.user.api.UsersRepository;
-import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.mailet.MailAddress;
 
 public class DeliveryUtils {

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/LocalDelivery.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/LocalDelivery.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/LocalDelivery.java
index 08fce5d..b90a8ed 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/LocalDelivery.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/LocalDelivery.java
@@ -26,9 +26,7 @@ import javax.mail.MessagingException;
 import org.apache.commons.logging.Log;
 import org.apache.james.domainlist.api.DomainList;
 import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.sieverepository.api.SieveRepository;
 import org.apache.james.transport.mailets.RecipientRewriteTable;
-import org.apache.james.transport.mailets.ResourceLocatorImpl;
 import org.apache.james.transport.mailets.jsieve.CommonsLoggingAdapter;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.mailet.Mail;
@@ -48,12 +46,6 @@ public class LocalDelivery extends GenericMailet {
     private UsersRepository usersRepository;
     private MailboxManager mailboxManager;
     private DomainList domainList;
-    private SieveRepository sieveRepository;
-
-    @Inject
-    public void setSieveRepository(SieveRepository sieveRepository) {
-        this.sieveRepository = sieveRepository;
-    }
 
     @Inject
     public void setRrt(org.apache.james.rrt.api.RecipientRewriteTable rrt) {
@@ -99,14 +91,11 @@ public class LocalDelivery extends GenericMailet {
             .quiet(getInitParameter("quiet", false))
             .verbose(getInitParameter("verbose", false))
             .build();
-        String folder = "INBOX";
         mailDispatcher = MailDispatcher.builder()
-            .mailStorer(SieveMailStorer.builder()
-                .sievePoster(new SievePoster(mailboxManager, folder, usersRepository, getMailetContext()))
+            .mailStorer(SimpleMailStorer.builder()
+                .mailboxAppender(new MailboxAppender(mailboxManager, getMailetContext()))
                 .usersRepository(usersRepository)
-                .resourceLocator(ResourceLocatorImpl.instanciate(usersRepository, sieveRepository))
-                .mailetContext(getMailetContext())
-                .folder(folder)
+                .folder("INBOX")
                 .log(log)
                 .build())
             .consume(getInitParameter("consume", true))

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
new file mode 100644
index 0000000..ac5bdf1
--- /dev/null
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppender.java
@@ -0,0 +1,113 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import java.util.Date;
+
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.james.core.MimeMessageInputStream;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.exception.BadCredentialsException;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.transport.util.MailetContextLog;
+import org.apache.mailet.MailetContext;
+
+import com.google.common.base.Strings;
+
+public class MailboxAppender {
+    private static final boolean IS_RECENT = true;
+    private static final Flags FLAGS = null;
+
+    private final MailboxManager mailboxManager;
+    private final MailetContext mailetContext;
+
+    public MailboxAppender(MailboxManager mailboxManager, MailetContext mailetContext) {
+        this.mailboxManager = mailboxManager;
+        this.mailetContext = mailetContext;
+    }
+
+    public void append(MimeMessage mail, String user, String folder) throws MessagingException {
+        MailboxSession session = createMailboxSession(user);
+        append(mail, user, folder, session);
+    }
+
+    public void appendAndUseSlashAsSeparator(MimeMessage mail, String user, String folder, String fallbackFolder) throws MessagingException {
+        MailboxSession session = createMailboxSession(user);
+        append(mail, user, useSlashAsSeparator(folder, session, fallbackFolder));
+    }
+
+    private String useSlashAsSeparator(String urlPath, MailboxSession session, String fallbackFolder) {
+        String destination = urlPath.replace('/', session.getPathDelimiter());
+        if (Strings.isNullOrEmpty(destination)) {
+            destination = fallbackFolder;
+        }
+        if (destination.charAt(0) == session.getPathDelimiter()) {
+            destination = destination.substring(1);
+        }
+        return destination;
+    }
+
+    private void append(MimeMessage mail, String user, String folder, MailboxSession session) throws MessagingException {
+        mailboxManager.startProcessingRequest(session);
+        try {
+            MailboxPath mailboxPath = new MailboxPath(session.getPersonalSpace(), user, folder);
+            appendMessageToMailbox(mail, session, mailboxPath);
+        } catch (MailboxException e) {
+            throw new MessagingException("Unable to access mailbox.", e);
+        } finally {
+            session.close();
+            try {
+                mailboxManager.logout(session, true);
+            } catch (MailboxException e) {
+                throw new MessagingException("Can logout from mailbox", e);
+            }
+            mailboxManager.endProcessingRequest(session);
+        }
+    }
+
+    private void appendMessageToMailbox(MimeMessage mail, MailboxSession session, MailboxPath path) throws MailboxException, MessagingException {
+        if (!mailboxManager.mailboxExists(path, session)) {
+            mailboxManager.createMailbox(path, session);
+        }
+        final MessageManager mailbox = mailboxManager.getMailbox(path, session);
+        if (mailbox == null) {
+            throw new MessagingException("Mailbox for user " + session.getUser().getUserName() + " was not found on this server.");
+        }
+        mailbox.appendMessage(new MimeMessageInputStream(mail), new Date(), session, IS_RECENT, FLAGS);
+    }
+
+    public MailboxSession createMailboxSession(String user) throws MessagingException {
+        try {
+            return mailboxManager.createSystemSession(user, new MailetContextLog(mailetContext));
+        } catch (BadCredentialsException e) {
+            throw new MessagingException("Unable to authenticate to mailbox", e);
+        } catch (MailboxException e) {
+            throw new MessagingException("Can not access mailbox", e);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveLocalDelivery.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveLocalDelivery.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveLocalDelivery.java
new file mode 100644
index 0000000..eeba376
--- /dev/null
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveLocalDelivery.java
@@ -0,0 +1,118 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.mail.MessagingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.transport.mailets.RecipientRewriteTable;
+import org.apache.james.transport.mailets.ResourceLocatorImpl;
+import org.apache.james.transport.mailets.jsieve.CommonsLoggingAdapter;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+
+/**
+ * Receives a Mail from the Queue and takes care of delivery of the
+ * message to local inboxes applying SIEVE rules.
+ * 
+ * This mailet is a composition of RecipientRewriteTable, SieveMailet 
+ * and MailboxManager configured to mimic the old "LocalDelivery"
+ * James 2.3 behavior.
+ */
+public class SieveLocalDelivery extends GenericMailet {
+    
+    private org.apache.james.rrt.api.RecipientRewriteTable rrt;
+    private UsersRepository usersRepository;
+    private MailboxManager mailboxManager;
+    private DomainList domainList;
+    private SieveRepository sieveRepository;
+
+    @Inject
+    public void setSieveRepository(SieveRepository sieveRepository) {
+        this.sieveRepository = sieveRepository;
+    }
+
+    @Inject
+    public void setRrt(org.apache.james.rrt.api.RecipientRewriteTable rrt) {
+        this.rrt = rrt;
+    }
+
+    @Inject
+    public void setUsersRepository(UsersRepository usersRepository) {
+        this.usersRepository = usersRepository;
+    }
+    
+    @Inject
+    public void setMailboxManager(@Named("mailboxmanager") MailboxManager mailboxManager) {
+        this.mailboxManager = mailboxManager;
+    }
+    
+    @Inject
+    public void setDomainList(DomainList domainList) {
+        this.domainList = domainList;
+    }
+
+    private MailDispatcher mailDispatcher;  // Mailet that actually stores the message
+    private RecipientRewriteTable recipientRewriteTable;  // Mailet that applies RecipientRewriteTable
+
+    public void service(Mail mail) throws MessagingException {
+        recipientRewriteTable.service(mail);
+        if (!mail.getState().equals(Mail.GHOST)) {
+            mailDispatcher.dispatch(mail);
+        }
+    }
+
+    public String getMailetInfo() {
+        return "Local Delivery Mailet";
+    }
+
+    public void init() throws MessagingException {
+        recipientRewriteTable = new RecipientRewriteTable();
+        recipientRewriteTable.setDomainList(domainList);
+        recipientRewriteTable.setRecipientRewriteTable(rrt);
+        recipientRewriteTable.init(getMailetConfig());
+        Log log = CommonsLoggingAdapter.builder()
+            .mailet(this)
+            .quiet(getInitParameter("quiet", false))
+            .verbose(getInitParameter("verbose", false))
+            .build();
+        String folder = "INBOX";
+        mailDispatcher = MailDispatcher.builder()
+            .mailStorer(SieveMailStorer.builder()
+                .sievePoster(new SievePoster(new MailboxAppender(mailboxManager, getMailetContext()), folder, usersRepository, getMailetContext()))
+                .usersRepository(usersRepository)
+                .resourceLocator(ResourceLocatorImpl.instanciate(usersRepository, sieveRepository))
+                .mailetContext(getMailetContext())
+                .folder(folder)
+                .log(log)
+                .build())
+            .consume(getInitParameter("consume", true))
+            .mailetContext(getMailetContext())
+            .log(log)
+            .build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SievePoster.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SievePoster.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SievePoster.java
index c287689..ce6ba76 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SievePoster.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SievePoster.java
@@ -19,22 +19,13 @@
 
 package org.apache.james.transport.mailets.delivery;
 
-import java.util.Date;
-
-import javax.mail.Flags;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
-import org.apache.james.core.MimeMessageInputStream;
-import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.exception.BadCredentialsException;
-import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxConstants;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.transport.mailets.jsieve.Poster;
-import org.apache.james.transport.util.MailetContextLog;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.mailet.MailetContext;
@@ -43,16 +34,13 @@ import com.google.common.base.Strings;
 
 public class SievePoster implements Poster {
 
-    private static final boolean IS_RECENT = true;
-    private static final Flags FLAGS = null;
-
-    private final MailboxManager mailboxManager;
+    private final MailboxAppender mailboxAppender;
     private final String folder;
     private final UsersRepository usersRepos;
     private final MailetContext mailetContext;
 
-    public SievePoster(MailboxManager mailboxManager, String folder, UsersRepository usersRepos, MailetContext mailetContext) {
-        this.mailboxManager = mailboxManager;
+    public SievePoster(MailboxAppender mailboxAppender, String folder, UsersRepository usersRepos, MailetContext mailetContext) {
+        this.mailboxAppender = mailboxAppender;
         this.folder = folder;
         this.usersRepos = usersRepos;
         this.mailetContext = mailetContext;
@@ -86,8 +74,7 @@ public class SievePoster implements Poster {
             String user = parseUser(url, startOfUser, endOfUser, host);
             String urlPath = parseUrlPath(url, endOfHost);
 
-            MailboxSession session = createMailboxSession(user);
-            appendMessageToMailboxWithSession(mail, user, session, parseDestinationMailboxPath(user, urlPath, session));
+            mailboxAppender.appendAndUseSlashAsSeparator(mail, user, urlPath, folder);
         }
     }
 
@@ -116,56 +103,4 @@ public class SievePoster implements Poster {
             throw new MessagingException("Unable to accessUsersRepository", e);
         }
     }
-
-    private void appendMessageToMailboxWithSession(MimeMessage mail, String user, MailboxSession session, MailboxPath path) throws MessagingException {
-        mailboxManager.startProcessingRequest(session);
-        try {
-            appendMessageToMailbox(mail, user, session, path);
-        } catch (MailboxException e) {
-            throw new MessagingException("Unable to access mailbox.", e);
-        } finally {
-            session.close();
-            try {
-                mailboxManager.logout(session, true);
-            } catch (MailboxException e) {
-                throw new MessagingException("Can logout from mailbox", e);
-            }
-            mailboxManager.endProcessingRequest(session);
-        }
-    }
-
-    private void appendMessageToMailbox(MimeMessage mail, String user, MailboxSession session, MailboxPath path) throws MailboxException, MessagingException {
-        if (this.folder.equalsIgnoreCase(path.getName()) && !(mailboxManager.mailboxExists(path, session))) {
-            mailboxManager.createMailbox(path, session);
-        }
-        final MessageManager mailbox = mailboxManager.getMailbox(path, session);
-        if (mailbox == null) {
-            throw new MessagingException("Mailbox for user " + user + " was not found on this server.");
-        }
-        mailbox.appendMessage(new MimeMessageInputStream(mail), new Date(), session, IS_RECENT, FLAGS);
-    }
-
-    private MailboxPath parseDestinationMailboxPath(String user, String urlPath, MailboxSession session) {
-        // This allows Sieve scripts to use a standard delimiter
-        // regardless of mailbox implementation
-        String destination = urlPath.replace('/', session.getPathDelimiter());
-        if (Strings.isNullOrEmpty(destination)) {
-            destination = this.folder;
-        }
-        if (destination.charAt(0) == session.getPathDelimiter()) {
-            destination = destination.substring(1);
-        }
-        // Use the MailboxSession to construct the MailboxPath - See JAMES-1326
-        return new MailboxPath(MailboxConstants.USER_NAMESPACE, user, destination);
-    }
-
-    private MailboxSession createMailboxSession(String user) throws MessagingException {
-        try {
-            return mailboxManager.createSystemSession(user, new MailetContextLog(mailetContext));
-        } catch (BadCredentialsException e) {
-            throw new MessagingException("Unable to authenticate to mailbox", e);
-        } catch (MailboxException e) {
-            throw new MessagingException("Can not access mailbox", e);
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolder.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolder.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolder.java
new file mode 100644
index 0000000..634f653
--- /dev/null
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolder.java
@@ -0,0 +1,111 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.mail.MessagingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.transport.mailets.ResourceLocatorImpl;
+import org.apache.james.transport.mailets.jsieve.CommonsLoggingAdapter;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.mailet.Mail;
+import org.apache.mailet.base.GenericMailet;
+
+/**
+ * Receives a Mail from the Queue and takes care to deliver the message
+ * to a defined folder of the recipient(s) applying SIEVE rules.
+ * 
+ * You have to define the folder name of the recipient(s).
+ * The flag 'consume' will tell is the mail will be further
+ * processed by the upcoming processor mailets, or not.
+ * 
+ * <pre>
+ * &lt;mailet match="RecipientIsLocal" class="ToRecipientFolder"&gt;
+ *    &lt;folder&gt; <i>Junk</i> &lt;/folder&gt;
+ *    &lt;consume&gt; <i>false</i> &lt;/consume&gt;
+ * &lt;/mailet&gt;
+ * </pre>
+ * 
+ */
+public class SieveToRecipientFolder extends GenericMailet {
+
+    public static final String FOLDER_PARAMETER = "folder";
+    public static final String CONSUME_PARAMETER = "consume";
+
+    private MailboxManager mailboxManager;
+    private SieveRepository sieveRepository;
+    private UsersRepository usersRepository;
+
+    @Inject
+    public void setMailboxManager(@Named("mailboxmanager")MailboxManager mailboxManager) {
+        this.mailboxManager = mailboxManager;
+    }
+
+    @Inject
+    public void setSieveRepository(SieveRepository sieveRepository) {
+        this.sieveRepository = sieveRepository;
+    }
+
+    @Inject
+    public void setUsersRepository(UsersRepository usersRepository) {
+        this.usersRepository = usersRepository;
+    }
+
+    private MailDispatcher mailDispatcher;
+
+    @Override
+    public void service(Mail mail) throws MessagingException {
+        if (!mail.getState().equals(Mail.GHOST)) {
+            mailDispatcher.dispatch(mail);
+        }
+    }
+
+    @Override
+    public void init() throws MessagingException {
+        Log log = CommonsLoggingAdapter.builder()
+            .mailet(this)
+            .quiet(getInitParameter("quiet", true))
+            .verbose(getInitParameter("verbose", false))
+            .build();
+        String folder = getInitParameter(FOLDER_PARAMETER, "INBOX");
+        mailDispatcher = MailDispatcher.builder()
+            .mailStorer(SieveMailStorer.builder()
+                .sievePoster(new SievePoster(new MailboxAppender(mailboxManager, getMailetContext()), folder, usersRepository, getMailetContext()))
+                .usersRepository(usersRepository)
+                .resourceLocator(ResourceLocatorImpl.instanciate(usersRepository, sieveRepository))
+                .mailetContext(getMailetContext())
+                .folder(folder)
+                .log(log)
+                .build())
+            .consume(getInitParameter(CONSUME_PARAMETER, false))
+            .mailetContext(getMailetContext())
+            .log(log)
+            .build();
+    }
+
+    @Override
+    public String getMailetInfo() {
+        return SieveToRecipientFolder.class.getName() + " Mailet";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStorer.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStorer.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStorer.java
new file mode 100644
index 0000000..31f3251
--- /dev/null
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStorer.java
@@ -0,0 +1,93 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import javax.mail.MessagingException;
+
+import org.apache.commons.logging.Log;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+
+import com.google.common.base.Preconditions;
+
+public class SimpleMailStorer implements MailStorer {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        private UsersRepository usersRepos;
+        private MailboxAppender mailboxAppender;
+        private String folder;
+        private Log log;
+
+        public Builder folder(String folder) {
+            this.folder = folder;
+            return this;
+        }
+
+        public Builder usersRepository(UsersRepository usersRepository) {
+            this.usersRepos = usersRepository;
+            return this;
+        }
+
+        public Builder mailboxAppender(MailboxAppender mailboxAppender) {
+            this.mailboxAppender = mailboxAppender;
+            return this;
+        }
+
+        public Builder log(Log log) {
+            this.log = log;
+            return this;
+        }
+
+        public SimpleMailStorer build() throws MessagingException {
+            Preconditions.checkNotNull(usersRepos);
+            Preconditions.checkNotNull(folder);
+            Preconditions.checkNotNull(log);
+            Preconditions.checkNotNull(mailboxAppender);
+            return new SimpleMailStorer(mailboxAppender, usersRepos, log, folder);
+        }
+    }
+
+    private final MailboxAppender mailboxAppender;
+    private final UsersRepository usersRepository;
+    private final Log log;
+    private final String folder;
+
+    private SimpleMailStorer(MailboxAppender mailboxAppender, UsersRepository usersRepository, Log log, String folder) {
+        this.mailboxAppender = mailboxAppender;
+        this.usersRepository = usersRepository;
+        this.log = log;
+        this.folder = folder;
+    }
+
+    @Override
+    public void storeMail(MailAddress sender, MailAddress recipient, Mail mail) throws MessagingException {
+        String username = DeliveryUtils.getUsername(recipient, usersRepository, log);
+
+        mailboxAppender.append(mail.getMessage(), username, folder);
+
+        log.info("Local delivered mail " + mail.getName() + " sucessfully from " + DeliveryUtils.prettyPrint(sender)
+            + " to " + DeliveryUtils.prettyPrint(recipient) + " in folder " + this.folder);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/ToRecipientFolder.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/ToRecipientFolder.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/ToRecipientFolder.java
index 9e8ba2d..1167c28 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/ToRecipientFolder.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/ToRecipientFolder.java
@@ -24,8 +24,6 @@ import javax.mail.MessagingException;
 
 import org.apache.commons.logging.Log;
 import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.sieverepository.api.SieveRepository;
-import org.apache.james.transport.mailets.ResourceLocatorImpl;
 import org.apache.james.transport.mailets.jsieve.CommonsLoggingAdapter;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.mailet.Mail;
@@ -53,7 +51,6 @@ public class ToRecipientFolder extends GenericMailet {
     public static final String CONSUME_PARAMETER = "consume";
 
     private MailboxManager mailboxManager;
-    private SieveRepository sieveRepository;
     private UsersRepository usersRepository;
 
     @Inject
@@ -62,11 +59,6 @@ public class ToRecipientFolder extends GenericMailet {
     }
 
     @Inject
-    public void setSieveRepository(SieveRepository sieveRepository) {
-        this.sieveRepository = sieveRepository;
-    }
-
-    @Inject
     public void setUsersRepository(UsersRepository usersRepository) {
         this.usersRepository = usersRepository;
     }
@@ -87,14 +79,11 @@ public class ToRecipientFolder extends GenericMailet {
             .quiet(getInitParameter("quiet", true))
             .verbose(getInitParameter("verbose", false))
             .build();
-        String folder = getInitParameter(FOLDER_PARAMETER, "INBOX");
         mailDispatcher = MailDispatcher.builder()
-            .mailStorer(SieveMailStorer.builder()
-                .sievePoster(new SievePoster(mailboxManager, folder, usersRepository, getMailetContext()))
+            .mailStorer(SimpleMailStorer.builder()
+                .mailboxAppender(new MailboxAppender(mailboxManager, getMailetContext()))
                 .usersRepository(usersRepository)
-                .resourceLocator(ResourceLocatorImpl.instanciate(usersRepository, sieveRepository))
-                .mailetContext(getMailetContext())
-                .folder(folder)
+                .folder(getInitParameter(FOLDER_PARAMETER, "INBOX"))
                 .log(log)
                 .build())
             .consume(getInitParameter(CONSUME_PARAMETER, false))

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java
deleted file mode 100644
index 9a188ff..0000000
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/LocalDeliveryTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************
- * 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.transport.mailets.delivery;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-import java.util.Properties;
-
-import javax.activation.DataHandler;
-import javax.mail.Flags;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-import javax.mail.util.ByteArrayDataSource;
-
-import org.apache.james.domainlist.api.DomainList;
-import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.rrt.api.RecipientRewriteTable;
-import org.apache.james.sieverepository.api.SieveRepository;
-import org.apache.james.sieverepository.api.exception.ScriptNotFoundException;
-import org.apache.james.user.api.UsersRepository;
-import org.apache.mailet.Mail;
-import org.apache.mailet.MailAddress;
-import org.apache.mailet.base.test.FakeMail;
-import org.apache.mailet.base.test.FakeMailetConfig;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.slf4j.Logger;
-
-public class LocalDeliveryTest {
-
-    private UsersRepository usersRepository;
-    private RecipientRewriteTable recipientRewriteTable;
-    private MailboxManager mailboxManager;
-    private DomainList domainList;
-    private SieveRepository sieveRepository;
-    private LocalDelivery localDelivery;
-
-    @Before
-    public void setUp() throws Exception {
-        sieveRepository = mock(SieveRepository.class);
-        usersRepository = mock(UsersRepository.class);
-        recipientRewriteTable = mock(RecipientRewriteTable.class);
-        mailboxManager = mock(MailboxManager.class);
-        domainList = mock(DomainList.class);
-
-        localDelivery = new LocalDelivery();
-        localDelivery.setDomainList(domainList);
-        localDelivery.setMailboxManager(mailboxManager);
-        localDelivery.setRrt(recipientRewriteTable);
-        localDelivery.setUsersRepository(usersRepository);
-        localDelivery.setSieveRepository(sieveRepository);
-    }
-
-    @Test
-    public void mailShouldBeWellDeliveredByDefaultToUserWhenvirtualHostingIsTurnedOn() throws Exception {
-        when(usersRepository.supportVirtualHosting()).thenAnswer(new Answer<Boolean>() {
-            public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return true;
-            }
-        });
-        when(sieveRepository.getActive("receiver@domain.com")).thenThrow(new ScriptNotFoundException());
-        MailboxPath inbox = new MailboxPath("#private", "receiver@domain.com", "INBOX");
-        final MessageManager messageManager = mock(MessageManager.class);
-        when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenAnswer(new Answer<MessageManager>() {
-            public MessageManager answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return messageManager;
-            }
-        });
-        final MailboxSession session = mock(MailboxSession.class);
-        when(session.getPathDelimiter()).thenAnswer(new Answer<Character>() {
-            @Override
-            public Character answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return '.';
-            }
-        });
-        when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenAnswer(new Answer<MailboxSession>() {
-            @Override
-            public MailboxSession answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return session;
-            }
-        });
-
-        Mail mail = createMail();
-
-        localDelivery.init(new FakeMailetConfig());
-        localDelivery.service(mail);
-
-        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
-    }
-
-    @Test
-    public void mailShouldBeWellDeliveredByDefaultToUserWhenvirtualHostingIsTurnedOff() throws Exception {
-        when(usersRepository.supportVirtualHosting()).thenAnswer(new Answer<Boolean>() {
-            public Boolean answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return false;
-            }
-        });
-        when(sieveRepository.getActive("receiver")).thenThrow(new ScriptNotFoundException());
-        MailboxPath inbox = new MailboxPath("#private", "receiver", "INBOX");
-        final MessageManager messageManager = mock(MessageManager.class);
-        when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenAnswer(new Answer<MessageManager>() {
-            public MessageManager answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return messageManager;
-            }
-        });
-        final MailboxSession session = mock(MailboxSession.class);
-        when(session.getPathDelimiter()).thenAnswer(new Answer<Character>() {
-            @Override
-            public Character answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return '.';
-            }
-        });
-        when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenAnswer(new Answer<MailboxSession>() {
-            @Override
-            public MailboxSession answer(InvocationOnMock invocationOnMock) throws Throwable {
-                return session;
-            }
-        });
-
-        Mail mail = createMail();
-
-        localDelivery.init(new FakeMailetConfig());
-        localDelivery.service(mail);
-
-        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
-    }
-
-    private Mail createMail() throws MessagingException, IOException {
-        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
-        message.setSubject("Subject");
-        message.setSender(new InternetAddress("sender@any.com"));
-        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("receiver@domain.com"));
-        MimeMultipart multipart = new MimeMultipart();
-        MimeBodyPart scriptPart = new MimeBodyPart();
-        scriptPart.setDataHandler(
-            new DataHandler(
-                new ByteArrayDataSource(
-                    "toto",
-                    "application/sieve; charset=UTF-8")
-            ));
-        scriptPart.setDisposition(MimeBodyPart.ATTACHMENT);
-        scriptPart.setHeader("Content-Type", "application/sieve; charset=UTF-8");
-        scriptPart.setFileName("file.txt");
-        multipart.addBodyPart(scriptPart);
-        message.setContent(multipart);
-        message.saveChanges();
-        return FakeMail.builder()
-                .mimeMessage(message)
-                .state(Mail.DEFAULT)
-                .recipient(new MailAddress("receiver@domain.com"))
-                .build();
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderTest.java
new file mode 100644
index 0000000..2a76fec
--- /dev/null
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderTest.java
@@ -0,0 +1,176 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+
+import java.util.Properties;
+
+import javax.activation.DataHandler;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
+
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxNotFoundException;
+import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.mailbox.manager.ManagerTestResources;
+import org.apache.james.mailbox.model.FetchGroupImpl;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageRange;
+import org.apache.james.mailbox.model.MessageResult;
+import org.apache.james.mailbox.model.MessageResultIterator;
+import org.apache.mailet.MailetContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MailboxAppenderTest {
+    private static final Logger LOGGER = LoggerFactory.getLogger(MailboxAppenderTest.class);
+
+    public static final String USER = "user";
+    public static final String FOLDER = "folder";
+    public static final String FALLBACK_FOLDER = "fallback_folder";
+    public static final String EMPTY_FOLDER = "";
+
+    @Rule public ExpectedException expectedException = ExpectedException.none();
+
+    private MailboxAppender testee;
+    private MailboxManager mailboxManager;
+    private MimeMessage mimeMessage;
+    private InMemoryIntegrationResources integrationResources;
+    private MailboxSession session;
+
+    @Before
+    public void setUp() throws Exception {
+        mimeMessage = new MimeMessage(Session.getDefaultInstance(new Properties()));
+        Multipart multipart = new MimeMultipart();
+        MimeBodyPart bodyPart = new MimeBodyPart();
+        bodyPart.setDataHandler(
+            new DataHandler(
+                new ByteArrayDataSource(
+                    "toto",
+                    "text/plain; charset=UTF-8")
+            ));
+        multipart.addBodyPart(bodyPart);
+        mimeMessage.setContent(multipart);
+        mimeMessage.saveChanges();
+
+        integrationResources = new InMemoryIntegrationResources();
+        integrationResources.init();
+        mailboxManager = new ManagerTestResources(integrationResources).getMailboxManager();
+        MailetContext mailetContext = mock(MailetContext.class);
+        testee = new MailboxAppender(mailboxManager, mailetContext);
+
+        session = mailboxManager.createSystemSession("TEST", LOGGER);
+    }
+
+    @After
+    public void cleanUp() throws Exception {
+        integrationResources.clean();
+    }
+
+    @Test
+    public void appendShouldAddMessageToDesiredMailbox() throws Exception {
+        testee.append(mimeMessage, USER, FOLDER);
+
+        MessageResultIterator messages = mailboxManager.getMailbox(new MailboxPath("#private", USER, FOLDER), session)
+            .getMessages(MessageRange.all(), new FetchGroupImpl(MessageResult.FetchGroup.FULL_CONTENT), session);
+
+        assertThat(messages).hasSize(1);
+    }
+
+    @Test
+    public void appendAndUseSlashAsSeparatorShouldAddMessageToDesiredMailbox() throws Exception {
+        testee.appendAndUseSlashAsSeparator(mimeMessage, USER, FOLDER, FALLBACK_FOLDER);
+
+        MessageResultIterator messages = mailboxManager.getMailbox(new MailboxPath("#private", USER, FOLDER), session)
+            .getMessages(MessageRange.all(), new FetchGroupImpl(MessageResult.FetchGroup.FULL_CONTENT), session);
+
+        assertThat(messages).hasSize(1);
+    }
+
+
+    @Test
+    public void appendShouldAddMessageToDesiredMailboxWhenMailboxExists() throws Exception {
+        MailboxPath mailboxPath = new MailboxPath("#private", USER, FOLDER);
+        mailboxManager.createMailbox(mailboxPath, session);
+
+        testee.append(mimeMessage, USER, FOLDER);
+
+        MessageResultIterator messages = mailboxManager.getMailbox(mailboxPath, session)
+            .getMessages(MessageRange.all(), new FetchGroupImpl(MessageResult.FetchGroup.FULL_CONTENT), session);
+
+        assertThat(messages).hasSize(1);
+    }
+
+    @Test
+    public void appendAndUseSlashAsSeparatorShouldAddMessageToDesiredMailboxWhenMailboxExists() throws Exception {
+        MailboxPath mailboxPath = new MailboxPath("#private", USER, FOLDER);
+        mailboxManager.createMailbox(mailboxPath, session);
+
+        testee.appendAndUseSlashAsSeparator(mimeMessage, USER, FOLDER, FALLBACK_FOLDER);
+
+        MessageResultIterator messages = mailboxManager.getMailbox(mailboxPath, session)
+            .getMessages(MessageRange.all(), new FetchGroupImpl(MessageResult.FetchGroup.FULL_CONTENT), session);
+
+        assertThat(messages).hasSize(1);
+    }
+
+    @Test
+    public void appendAndUseSlashAsSeparatorShouldNotAppendToEmptyFolder() throws Exception {
+        testee.appendAndUseSlashAsSeparator(mimeMessage, USER, EMPTY_FOLDER, FALLBACK_FOLDER);
+
+        expectedException.expect(MailboxNotFoundException.class);
+
+        mailboxManager.getMailbox(new MailboxPath("#private", USER, EMPTY_FOLDER), session);
+    }
+
+
+    @Test
+    public void appendAndUseSlashAsSeparatorShouldAppendToFallback() throws Exception {
+        testee.appendAndUseSlashAsSeparator(mimeMessage, USER, EMPTY_FOLDER, FALLBACK_FOLDER);
+
+        MessageResultIterator messages = mailboxManager.getMailbox(new MailboxPath("#private", USER, FALLBACK_FOLDER), session)
+            .getMessages(MessageRange.all(), new FetchGroupImpl(MessageResult.FetchGroup.FULL_CONTENT), session);
+
+        assertThat(messages).hasSize(1);
+    }
+
+    @Test
+    public void appendAndUseSlashAsSeparatorShouldRemovePathSeparatorAsFirstChar() throws Exception {
+        testee.appendAndUseSlashAsSeparator(mimeMessage, USER, "." + FOLDER, FALLBACK_FOLDER);
+
+        MessageResultIterator messages = mailboxManager.getMailbox(new MailboxPath("#private", USER, FOLDER), session)
+            .getMessages(MessageRange.all(), new FetchGroupImpl(MessageResult.FetchGroup.FULL_CONTENT), session);
+
+        assertThat(messages).hasSize(1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveIntegrationTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveIntegrationTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveIntegrationTest.java
index d7470a1..4158231 100644
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveIntegrationTest.java
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveIntegrationTest.java
@@ -107,7 +107,7 @@ public class SieveIntegrationTest {
             .resourceLocator(resourceLocator)
             .usersRepository(usersRepository)
             .folder("INBOX")
-            .sievePoster(new SievePoster(mailboxManager, "INBOX", usersRepository, fakeMailContext))
+            .sievePoster(new SievePoster(new MailboxAppender(mailboxManager, fakeMailContext), "INBOX", usersRepository, fakeMailContext))
             .log(mock(Log.class))
             .mailetContext(fakeMailContext)
             .build();
@@ -943,12 +943,15 @@ public class SieveIntegrationTest {
             ClassLoader.getSystemResourceAsStream(script)));
     }
 
-    private MessageManager prepareMessageManagerOn(MailboxPath inbox) throws MailboxException {
+    private MessageManager prepareMessageManagerOn(MailboxPath mailboxPath) throws MailboxException {
         final MessageManager messageManager = mock(MessageManager.class);
-        when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenReturn(messageManager);
+        when(mailboxManager.getMailbox(eq(mailboxPath), any(MailboxSession.class))).thenReturn(messageManager);
         final MailboxSession session = mock(MailboxSession.class);
         when(session.getPathDelimiter()).thenReturn('.');
         when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenReturn(session);
+        MailboxSession.User user = mock(MailboxSession.User.class);
+        when(session.getUser()).thenReturn(user);
+        when(user.getUserName()).thenReturn(mailboxPath.getUser());
         return messageManager;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveLocalDeliveryTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveLocalDeliveryTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveLocalDeliveryTest.java
new file mode 100644
index 0000000..6cb9781
--- /dev/null
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveLocalDeliveryTest.java
@@ -0,0 +1,152 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.activation.DataHandler;
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
+
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.sieverepository.api.exception.ScriptNotFoundException;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.FakeMailetConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+public class SieveLocalDeliveryTest {
+
+    private UsersRepository usersRepository;
+    private MailboxManager mailboxManager;
+    private SieveRepository sieveRepository;
+    private SieveLocalDelivery sieveLocalDelivery;
+    private MailboxSession.User user;
+
+    @Before
+    public void setUp() throws Exception {
+        sieveRepository = mock(SieveRepository.class);
+        usersRepository = mock(UsersRepository.class);
+        mailboxManager = mock(MailboxManager.class);
+        RecipientRewriteTable recipientRewriteTable = mock(RecipientRewriteTable.class);
+        DomainList domainList = mock(DomainList.class);
+        user = mock(MailboxSession.User.class);
+        MailboxSession session = mock(MailboxSession.class);
+
+        sieveLocalDelivery = new SieveLocalDelivery();
+        sieveLocalDelivery.setDomainList(domainList);
+        sieveLocalDelivery.setMailboxManager(mailboxManager);
+        sieveLocalDelivery.setRrt(recipientRewriteTable);
+        sieveLocalDelivery.setUsersRepository(usersRepository);
+        sieveLocalDelivery.setSieveRepository(sieveRepository);
+
+        when(session.getPathDelimiter()).thenReturn('.');
+        when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenReturn(session);
+        when(session.getUser()).thenReturn(user);
+    }
+
+    @Test
+    public void mailShouldBeWellDeliveredByDefaultToUserWhenVirtualHostingIsTurnedOn() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenReturn(true);
+        String username = "receiver@domain.com";
+        when(sieveRepository.getActive(username)).thenThrow(new ScriptNotFoundException());
+        MailboxPath inbox = new MailboxPath("#private", username, "INBOX");
+        MessageManager messageManager = mock(MessageManager.class);
+        when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenReturn(messageManager);
+        when(user.getUserName()).thenReturn(username);
+
+        Mail mail = createMail();
+
+        sieveLocalDelivery.init(new FakeMailetConfig());
+        sieveLocalDelivery.service(mail);
+
+        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
+    }
+
+    @Test
+    public void mailShouldBeWellDeliveredByDefaultToUserWhenVirtualHostingIsTurnedOff() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenReturn(false);
+        String username = "receiver";
+        when(sieveRepository.getActive(username)).thenThrow(new ScriptNotFoundException());
+        MailboxPath inbox = new MailboxPath("#private", username, "INBOX");
+        final MessageManager messageManager = mock(MessageManager.class);
+        when(mailboxManager.getMailbox(eq(inbox), any(MailboxSession.class))).thenReturn(messageManager);
+        when(user.getUserName()).thenReturn(username);
+
+        Mail mail = createMail();
+
+        sieveLocalDelivery.init(new FakeMailetConfig());
+        sieveLocalDelivery.service(mail);
+
+        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
+    }
+
+    private Mail createMail() throws MessagingException, IOException {
+        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
+        message.setSubject("Subject");
+        message.setSender(new InternetAddress("sender@any.com"));
+        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("receiver@domain.com"));
+        MimeMultipart multipart = new MimeMultipart();
+        MimeBodyPart scriptPart = new MimeBodyPart();
+        scriptPart.setDataHandler(
+            new DataHandler(
+                new ByteArrayDataSource(
+                    "toto",
+                    "application/sieve; charset=UTF-8")
+            ));
+        scriptPart.setDisposition(MimeBodyPart.ATTACHMENT);
+        scriptPart.setHeader("Content-Type", "application/sieve; charset=UTF-8");
+        scriptPart.setFileName("file.txt");
+        multipart.addBodyPart(scriptPart);
+        message.setContent(multipart);
+        message.saveChanges();
+        return FakeMail.builder()
+                .mimeMessage(message)
+                .state(Mail.DEFAULT)
+                .recipient(new MailAddress("receiver@domain.com"))
+                .build();
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolderTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolderTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolderTest.java
new file mode 100644
index 0000000..5de9ab0
--- /dev/null
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SieveToRecipientFolderTest.java
@@ -0,0 +1,187 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Properties;
+
+import javax.activation.DataHandler;
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
+
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.sieverepository.api.SieveRepository;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailAddress;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.FakeMailContext;
+import org.apache.mailet.base.test.FakeMailetConfig;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+public class SieveToRecipientFolderTest {
+
+    public static final String USER_LOCAL_PART = "receiver";
+    public static final String USER = USER_LOCAL_PART + "@domain.com";
+    public static final MailboxPath INBOX = new MailboxPath("#private", USER, "INBOX");
+    public static final MailboxPath JUNK = new MailboxPath("#private", USER_LOCAL_PART, "Junk");
+    public static final MailboxPath JUNK_VIRTUAL_HOSTING = new MailboxPath("#private", USER, "Junk");
+    private UsersRepository usersRepository;
+    private MailboxManager mailboxManager;
+    private SieveToRecipientFolder recipientFolder;
+    private FakeMailetConfig mailetConfig;
+    private MailboxSession.User user;
+    private MessageManager messageManager;
+
+    @Before
+    public void setUp() throws Exception {
+        usersRepository = mock(UsersRepository.class);
+        mailboxManager = mock(MailboxManager.class);
+
+        mailetConfig = new FakeMailetConfig("RecipientFolderTest", FakeMailContext.defaultContext());
+
+        recipientFolder = new SieveToRecipientFolder();
+        recipientFolder.setMailboxManager(mailboxManager);
+        recipientFolder.setUsersRepository(usersRepository);
+        recipientFolder.setSieveRepository(mock(SieveRepository.class));
+
+        messageManager = mock(MessageManager.class);
+        MailboxSession session = mock(MailboxSession.class);
+        when(session.getPathDelimiter()).thenReturn('.');
+        when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenReturn(session);
+        user = mock(MailboxSession.User.class);
+        when(session.getUser()).thenReturn(user);
+    }
+
+    @Test
+    public void initParameterTesting() throws Exception {
+        mailetConfig.setProperty(ToRecipientFolder.FOLDER_PARAMETER, "Junk");
+        recipientFolder.init(mailetConfig);
+
+        Assert.assertEquals("Junk", recipientFolder.getInitParameter(ToRecipientFolder.FOLDER_PARAMETER));
+    }
+
+    @Test
+    public void consumeOptionShouldGhostTheMail() throws Exception {
+        mailetConfig.setProperty(ToRecipientFolder.CONSUME_PARAMETER, "true");
+        recipientFolder.init(mailetConfig);
+
+        Mail mail = createMail();
+        recipientFolder.service(mail);
+
+        assertThat(mail.getState()).isEqualTo(Mail.GHOST);
+    }
+
+    @Test
+    public void consumeOptionShouldNotGhostTheMailByDefault() throws Exception {
+        recipientFolder.init(mailetConfig);
+
+        Mail mail = createMail();
+        recipientFolder.service(mail);
+
+        assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
+    }
+
+    @Test
+    public void folderParameterShouldIndicateDestinationFolder() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenReturn(true);
+        when(mailboxManager.getMailbox(eq(JUNK_VIRTUAL_HOSTING), any(MailboxSession.class))).thenReturn(messageManager);
+        when(user.getUserName()).thenReturn(USER);
+
+        mailetConfig.setProperty(ToRecipientFolder.FOLDER_PARAMETER, "Junk");
+        recipientFolder.init(mailetConfig);
+        recipientFolder.service(createMail());
+
+        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
+    }
+
+    @Test
+    public void folderParameterShouldBeInboxByDefault() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenReturn(true);
+        when(mailboxManager.getMailbox(eq(INBOX), any(MailboxSession.class))).thenReturn(messageManager);
+        when(user.getUserName()).thenReturn(USER);
+
+        recipientFolder.init(mailetConfig);
+        recipientFolder.service(createMail());
+
+        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
+    }
+
+    @Test
+    public void folderParameterShouldWorkWhenVirtualHostingIsTurnedOff() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenReturn(false);
+        when(mailboxManager.getMailbox(eq(JUNK), any(MailboxSession.class))).thenReturn(messageManager);
+        when(user.getUserName()).thenReturn(USER_LOCAL_PART);
+
+        mailetConfig.setProperty(ToRecipientFolder.FOLDER_PARAMETER, "Junk");
+        recipientFolder.init(mailetConfig);
+        recipientFolder.service(createMail());
+
+        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
+    }
+
+    private Mail createMail() throws MessagingException, IOException {
+        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
+        message.setSubject("Subject");
+        message.setSender(new InternetAddress("sender@any.com"));
+        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(USER));
+        MimeMultipart multipart = new MimeMultipart();
+        MimeBodyPart scriptPart = new MimeBodyPart();
+        scriptPart.setDataHandler(
+                new DataHandler(
+                        new ByteArrayDataSource(
+                                "toto",
+                                "application/sieve; charset=UTF-8")
+                ));
+        scriptPart.setDisposition(MimeBodyPart.ATTACHMENT);
+        scriptPart.setHeader("Content-Type", "application/sieve; charset=UTF-8");
+        scriptPart.setFileName("file.txt");
+        multipart.addBodyPart(scriptPart);
+        message.setContent(multipart);
+        message.saveChanges();
+        return FakeMail.builder()
+                .mimeMessage(message)
+                .state(Mail.DEFAULT)
+                .recipient(new MailAddress(USER))
+                .build();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStorerTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStorerTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStorerTest.java
new file mode 100644
index 0000000..1f25190
--- /dev/null
+++ b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStorerTest.java
@@ -0,0 +1,121 @@
+/****************************************************************
+ * 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.transport.mailets.delivery;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Properties;
+
+import javax.activation.DataHandler;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.util.ByteArrayDataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.mailet.MailAddress;
+import org.apache.mailet.base.MailAddressFixture;
+import org.apache.mailet.base.test.FakeMail;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SimpleMailStorerTest {
+
+    public static final String FOLDER = "FOLDER";
+    private SimpleMailStorer testee;
+    private MailboxAppender mailboxAppender;
+    private UsersRepository usersRepository;
+    private MimeMessage mimeMessage;
+
+    @Before
+    public void setUp() throws Exception {
+        mailboxAppender = mock(MailboxAppender.class);
+        usersRepository = mock(UsersRepository.class);
+        testee = SimpleMailStorer.builder()
+            .usersRepository(usersRepository)
+            .mailboxAppender(mailboxAppender)
+            .folder(FOLDER)
+            .log(mock(Log.class))
+            .build();
+
+        mimeMessage = new MimeMessage(Session.getDefaultInstance(new Properties()));
+        Multipart multipart = new MimeMultipart();
+        MimeBodyPart bodyPart = new MimeBodyPart();
+        bodyPart.setDataHandler(
+            new DataHandler(
+                new ByteArrayDataSource(
+                    "toto",
+                    "text/plain; charset=UTF-8")
+            ));
+        multipart.addBodyPart(bodyPart);
+        mimeMessage.setContent(multipart);
+        mimeMessage.saveChanges();
+    }
+
+    @Test
+    public void storeMailShouldUseFullMailAddressWhenSupportsVirtualHosting() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenReturn(true);
+
+        MailAddress sender = MailAddressFixture.ANY_AT_JAMES;
+        MailAddress recipient = MailAddressFixture.OTHER_AT_JAMES;
+        FakeMail mail = FakeMail.builder()
+            .mimeMessage(mimeMessage)
+            .build();
+        testee.storeMail(sender, recipient, mail);
+
+        verify(mailboxAppender).append(any(MimeMessage.class), eq(recipient.toString()), eq(FOLDER));
+    }
+
+    @Test
+    public void storeMailShouldUseLocalPartWhenSupportsVirtualHosting() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenReturn(false);
+
+        MailAddress sender = MailAddressFixture.ANY_AT_JAMES;
+        MailAddress recipient = MailAddressFixture.OTHER_AT_JAMES;
+        FakeMail mail = FakeMail.builder()
+            .mimeMessage(mimeMessage)
+            .build();
+        testee.storeMail(sender, recipient, mail);
+
+        verify(mailboxAppender).append(any(MimeMessage.class), eq(recipient.getLocalPart()), eq(FOLDER));
+    }
+
+    @Test
+    public void storeMailShouldUseFullMailAddressWhenErrorReadingUsersRepository() throws Exception {
+        when(usersRepository.supportVirtualHosting()).thenThrow(new UsersRepositoryException("Any message"));
+
+        MailAddress sender = MailAddressFixture.ANY_AT_JAMES;
+        MailAddress recipient = MailAddressFixture.OTHER_AT_JAMES;
+        FakeMail mail = FakeMail.builder()
+            .mimeMessage(mimeMessage)
+            .build();
+        testee.storeMail(sender, recipient, mail);
+
+        verify(mailboxAppender).append(any(MimeMessage.class), eq(recipient.toString()), eq(FOLDER));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/989d60e6/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/ToRecipientFolderTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/ToRecipientFolderTest.java b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/ToRecipientFolderTest.java
deleted file mode 100644
index 7123b80..0000000
--- a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/ToRecipientFolderTest.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/****************************************************************
- * 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.transport.mailets.delivery;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Date;
-import java.util.Properties;
-
-import javax.activation.DataHandler;
-import javax.mail.Flags;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
-import javax.mail.util.ByteArrayDataSource;
-
-import org.apache.james.mailbox.MailboxManager;
-import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.model.MailboxPath;
-import org.apache.james.sieverepository.api.SieveRepository;
-import org.apache.james.user.api.UsersRepository;
-import org.apache.mailet.Mail;
-import org.apache.mailet.MailAddress;
-import org.apache.mailet.base.test.FakeMail;
-import org.apache.mailet.base.test.FakeMailContext;
-import org.apache.mailet.base.test.FakeMailetConfig;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.slf4j.Logger;
-
-public class ToRecipientFolderTest {
-
-    public static final String USER = "receiver@domain.com";
-    public static final MailboxPath INBOX = new MailboxPath("#private", USER, "INBOX");
-    public static final MailboxPath JUNK = new MailboxPath("#private", "receiver", "Junk");
-    public static final MailboxPath JUNK_VIRTUAL_HOSTING = new MailboxPath("#private", USER, "Junk");
-    private UsersRepository usersRepository;
-    private MailboxManager mailboxManager;
-    private ToRecipientFolder recipientFolder;
-    private FakeMailetConfig mailetConfig;
-
-    @Before
-    public void setUp() throws Exception {
-        usersRepository = mock(UsersRepository.class);
-        mailboxManager = mock(MailboxManager.class);
-
-        mailetConfig = new FakeMailetConfig("RecipientFolderTest", FakeMailContext.defaultContext());
-
-        recipientFolder = new ToRecipientFolder();
-        recipientFolder.setMailboxManager(mailboxManager);
-        recipientFolder.setUsersRepository(usersRepository);
-        recipientFolder.setSieveRepository(mock(SieveRepository.class));
-    }
-
-    @Test
-    public void initParameterTesting() throws Exception {
-        mailetConfig.setProperty(ToRecipientFolder.FOLDER_PARAMETER, "Junk");
-        recipientFolder.init(mailetConfig);
-
-        Assert.assertEquals("Junk", recipientFolder.getInitParameter(ToRecipientFolder.FOLDER_PARAMETER));
-    }
-
-    @Test
-    public void consumeOptionShouldGhostTheMail() throws Exception {
-        mailetConfig.setProperty(ToRecipientFolder.CONSUME_PARAMETER, "true");
-        recipientFolder.init(mailetConfig);
-
-        Mail mail = createMail();
-        recipientFolder.service(mail);
-
-        assertThat(mail.getState()).isEqualTo(Mail.GHOST);
-    }
-
-    @Test
-    public void consumeOptionShouldNotGhostTheMailByDefault() throws Exception {
-        recipientFolder.init(mailetConfig);
-
-        Mail mail = createMail();
-        recipientFolder.service(mail);
-
-        assertThat(mail.getState()).isEqualTo(Mail.DEFAULT);
-    }
-
-    @Test
-    public void folderParameterShouldIndicateDestinationFolder() throws Exception {
-        MessageManager messageManager = mock(MessageManager.class);
-        MailboxSession session = mock(MailboxSession.class);
-
-        when(usersRepository.supportVirtualHosting()).thenReturn(true);
-        when(mailboxManager.getMailbox(eq(JUNK_VIRTUAL_HOSTING), any(MailboxSession.class))).thenReturn(messageManager);
-        when(session.getPathDelimiter()).thenReturn('.');
-        when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenReturn(session);
-
-        mailetConfig.setProperty(ToRecipientFolder.FOLDER_PARAMETER, "Junk");
-        recipientFolder.init(mailetConfig);
-        recipientFolder.service(createMail());
-
-        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
-    }
-
-    @Test
-    public void folderParameterShouldBeInboxByDefault() throws Exception {
-        MessageManager messageManager = mock(MessageManager.class);
-        MailboxSession session = mock(MailboxSession.class);
-
-        when(usersRepository.supportVirtualHosting()).thenReturn(true);
-        when(mailboxManager.getMailbox(eq(INBOX), any(MailboxSession.class))).thenReturn(messageManager);
-        when(session.getPathDelimiter()).thenReturn('.');
-        when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenReturn(session);
-
-        recipientFolder.init(mailetConfig);
-        recipientFolder.service(createMail());
-
-        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
-    }
-
-    @Test
-    public void folderParameterShouldWorkWhenVirtualHostingIsTurnedOff() throws Exception {
-        MessageManager messageManager = mock(MessageManager.class);
-        MailboxSession session = mock(MailboxSession.class);
-
-        when(usersRepository.supportVirtualHosting()).thenReturn(false);
-        when(mailboxManager.getMailbox(eq(JUNK), any(MailboxSession.class))).thenReturn(messageManager);
-        when(session.getPathDelimiter()).thenReturn('.');
-        when(mailboxManager.createSystemSession(any(String.class), any(Logger.class))).thenReturn(session);
-
-        mailetConfig.setProperty(ToRecipientFolder.FOLDER_PARAMETER, "Junk");
-        recipientFolder.init(mailetConfig);
-        recipientFolder.service(createMail());
-
-        verify(messageManager).appendMessage(any(InputStream.class), any(Date.class), any(MailboxSession.class), eq(true), any(Flags.class));
-    }
-
-    private Mail createMail() throws MessagingException, IOException {
-        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
-        message.setSubject("Subject");
-        message.setSender(new InternetAddress("sender@any.com"));
-        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(USER));
-        MimeMultipart multipart = new MimeMultipart();
-        MimeBodyPart scriptPart = new MimeBodyPart();
-        scriptPart.setDataHandler(
-                new DataHandler(
-                        new ByteArrayDataSource(
-                                "toto",
-                                "application/sieve; charset=UTF-8")
-                ));
-        scriptPart.setDisposition(MimeBodyPart.ATTACHMENT);
-        scriptPart.setHeader("Content-Type", "application/sieve; charset=UTF-8");
-        scriptPart.setFileName("file.txt");
-        multipart.addBodyPart(scriptPart);
-        message.setContent(multipart);
-        message.saveChanges();
-        return FakeMail.builder()
-                .mimeMessage(message)
-                .state(Mail.DEFAULT)
-                .recipient(new MailAddress(USER))
-                .build();
-    }
-
-}


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