This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit ac56437cc4966ca7c20b8c4b067663f4acf68f44
Author: Benoit Tellier <btell...@linagora.com>
AuthorDate: Fri Apr 7 14:00:24 2023 +0700

    JAMES-3899 WithStorageDirective: Refactoring - introduce a StorageDirective 
POJO
---
 .../james/transport/mailets/RandomStoring.java     |   7 +-
 .../james/transport/mailets/ToSenderFolder.java    |   3 +-
 .../transport/mailets/WithStorageDirective.java    |  46 ++---
 .../transport/mailets/delivery/MailStore.java      |   5 -
 .../mailets/delivery/MailboxAppender.java          |   5 +-
 .../mailets/delivery/MailboxAppenderImpl.java      |   7 +-
 .../mailets/delivery/SimpleMailStore.java          |  74 ++------
 .../mailets/delivery/StorageDirective.java         | 196 +++++++++++++++++++++
 .../mailets/jsieve/delivery/SievePoster.java       |   7 +-
 .../mailets/delivery/MailboxAppenderImplTest.java  |  28 ++-
 .../mailets/delivery/SieveIntegrationTest.java     |   4 +-
 .../mailets/delivery/SimpleMailStoreTest.java      |   8 +-
 12 files changed, 265 insertions(+), 125 deletions(-)

diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RandomStoring.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RandomStoring.java
index 0465e68c54..36ba29d60f 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RandomStoring.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/RandomStoring.java
@@ -38,6 +38,7 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.model.search.MailboxQuery;
 import org.apache.james.transport.mailets.delivery.MailStore;
+import org.apache.james.transport.mailets.delivery.StorageDirective;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.mailet.Attribute;
 import org.apache.mailet.Mail;
@@ -83,7 +84,11 @@ public class RandomStoring extends GenericMailet {
 
         mail.setRecipients(mailAddresses);
         reroutingInfos.forEach(reroutingInfo ->
-            
mail.setAttribute(Attribute.convertToAttribute(MailStore.DELIVERY_PATH_PREFIX + 
reroutingInfo.getUser().asString(), reroutingInfo.getMailbox())));
+                StorageDirective.builder()
+                    .targetFolder(reroutingInfo.getMailbox())
+                    .build()
+                    .encodeAsAttributes(reroutingInfo.getUser())
+                    .forEach(mail::setAttribute));
     }
 
     @Override
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderFolder.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderFolder.java
index d808b81874..7c95a58955 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderFolder.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/ToSenderFolder.java
@@ -29,6 +29,7 @@ import org.apache.james.core.MailAddress;
 import org.apache.james.core.Username;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.transport.mailets.delivery.MailboxAppenderImpl;
+import org.apache.james.transport.mailets.delivery.StorageDirective;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.mailet.Experimental;
@@ -88,7 +89,7 @@ public class ToSenderFolder extends GenericMailet {
             MailAddress sender = mail.getMaybeSender().get();
             Username username = retrieveUser(sender);
 
-            mailboxAppender.append(mail.getMessage(), username, folder, 
NO_FLAGS).block();
+            mailboxAppender.append(mail.getMessage(), username, 
StorageDirective.builder().targetFolder(folder).build()).block();
 
             LOGGER.error("Local delivery with ToSenderFolder mailet for mail 
{} with sender {} in folder {}", mail.getName(), sender, folder);
         }
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WithStorageDirective.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WithStorageDirective.java
index 857f69b48e..c10bb7aafc 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WithStorageDirective.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/WithStorageDirective.java
@@ -26,20 +26,14 @@ import javax.inject.Inject;
 import javax.mail.MessagingException;
 
 import org.apache.james.core.MailAddress;
-import org.apache.james.core.Username;
-import org.apache.james.transport.mailets.delivery.MailStore;
+import org.apache.james.transport.mailets.delivery.StorageDirective;
 import org.apache.james.user.api.UsersRepository;
-import org.apache.mailet.Attribute;
-import org.apache.mailet.AttributeName;
-import org.apache.mailet.AttributeValue;
 import org.apache.mailet.Mail;
 import org.apache.mailet.base.GenericMailet;
 
 import com.github.fge.lambdas.consumers.ThrowingConsumer;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.primitives.Booleans;
 
 /**
  * WithStorageDirective position storage directive for the recipients of this 
email.
@@ -74,10 +68,7 @@ public class WithStorageDirective extends GenericMailet {
 
     private final UsersRepository usersRepository;
 
-    private Optional<AttributeValue<String>> targetFolderName;
-    private Optional<AttributeValue<Boolean>> seen;
-    private Optional<AttributeValue<Boolean>> important;
-    private Optional<AttributeValue<Collection<AttributeValue<?>>>> keywords;
+    private StorageDirective storageDirective;
 
     @Inject
     public WithStorageDirective(UsersRepository usersRepository) {
@@ -86,28 +77,20 @@ public class WithStorageDirective extends GenericMailet {
 
     @Override
     public void init() throws MessagingException {
-        Preconditions.checkState(
-            Booleans.countTrue(
-                getInitParameterAsOptional(TARGET_FOLDER_NAME).isPresent(),
-                getInitParameterAsOptional(SEEN).isPresent(),
-                getInitParameterAsOptional(IMPORTANT).isPresent(),
-                getInitParameterAsOptional(KEYWORDS).isPresent()) > 0,
-                "Expecting one of the storage directives to be specified: [%s, 
%s, %s, %s]",
-                TARGET_FOLDER_NAME, SEEN, IMPORTANT, KEYWORDS);
         
Preconditions.checkState(validBooleanParameter(getInitParameterAsOptional(SEEN)),
 "'%s' needs to be a boolean", SEEN);
         
Preconditions.checkState(validBooleanParameter(getInitParameterAsOptional(IMPORTANT)),
 "'%s' needs to be a boolean", IMPORTANT);
 
-        targetFolderName = 
getInitParameterAsOptional(TARGET_FOLDER_NAME).map(AttributeValue::of);
-        seen = 
getInitParameterAsOptional(SEEN).map(Boolean::parseBoolean).map(AttributeValue::of);
-        important = 
getInitParameterAsOptional(IMPORTANT).map(Boolean::parseBoolean).map(AttributeValue::of);
-        keywords = 
getInitParameterAsOptional(KEYWORDS).map(this::parseKeywords).map(AttributeValue::of);
+        storageDirective = StorageDirective.builder()
+            .targetFolder(getInitParameterAsOptional(TARGET_FOLDER_NAME))
+            .seen(getInitParameterAsOptional(SEEN).map(Boolean::parseBoolean))
+            
.important(getInitParameterAsOptional(IMPORTANT).map(Boolean::parseBoolean))
+            
.keywords(getInitParameterAsOptional(KEYWORDS).map(this::parseKeywords))
+            .build();
     }
 
-    private Collection<AttributeValue<?>> parseKeywords(String s) {
+    private Collection<String> parseKeywords(String s) {
         return KEYWORD_SPLITTER
-            .splitToStream(s)
-            .map(AttributeValue::of)
-            .collect(ImmutableSet.toImmutableSet());
+            .splitToList(s);
     }
 
     private boolean validBooleanParameter(Optional<String> parameter) {
@@ -122,12 +105,7 @@ public class WithStorageDirective extends GenericMailet {
     }
 
     public ThrowingConsumer<MailAddress> addStorageDirective(Mail mail) {
-        return recipient -> {
-            Username username = usersRepository.getUsername(recipient);
-            targetFolderName.ifPresent(value -> mail.setAttribute(new 
Attribute(AttributeName.of(MailStore.DELIVERY_PATH_PREFIX + 
username.asString()), value)));
-            seen.ifPresent(value -> mail.setAttribute(new 
Attribute(AttributeName.of(MailStore.SEEN_PREFIX + username.asString()), 
value)));
-            important.ifPresent(value -> mail.setAttribute(new 
Attribute(AttributeName.of(MailStore.IMPORTANT_PREFIX + username.asString()), 
value)));
-            keywords.ifPresent(value -> mail.setAttribute(new 
Attribute(AttributeName.of(MailStore.KEYWORDS_PREFIX + username.asString()), 
value)));
-        };
+        return recipient -> 
storageDirective.encodeAsAttributes(usersRepository.getUsername(recipient))
+            .forEach(mail::setAttribute);
     }
 }
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailStore.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailStore.java
index 22241067e9..04a42aa9f8 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailStore.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailStore.java
@@ -24,10 +24,5 @@ import org.apache.mailet.Mail;
 import org.reactivestreams.Publisher;
 
 public interface MailStore {
-    String DELIVERY_PATH_PREFIX = "DeliveryPath_";
-    String SEEN_PREFIX = "Seen_";
-    String IMPORTANT_PREFIX = "Important_";
-    String KEYWORDS_PREFIX = "Keywords_";
-
     Publisher<Void> storeMail(MailAddress recipient, Mail mail);
 }
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
index 0303f20976..d40e817315 100644
--- 
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
@@ -19,9 +19,6 @@
 
 package org.apache.james.transport.mailets.delivery;
 
-import java.util.Optional;
-
-import javax.mail.Flags;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
@@ -30,5 +27,5 @@ import org.apache.james.mailbox.model.ComposedMessageId;
 import org.reactivestreams.Publisher;
 
 public interface MailboxAppender {
-    Publisher<ComposedMessageId> append(MimeMessage mail, Username user, 
String folder, Optional<Flags> flags) throws MessagingException;
+    Publisher<ComposedMessageId> append(MimeMessage mail, Username user, 
StorageDirective storageDirective) throws MessagingException;
 }
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImpl.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImpl.java
index ab59df51a1..ca0d06f056 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImpl.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImpl.java
@@ -43,6 +43,7 @@ import org.apache.james.server.core.MimeMessageUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 
 import reactor.core.publisher.Mono;
@@ -56,9 +57,11 @@ public class MailboxAppenderImpl implements MailboxAppender {
         this.mailboxManager = mailboxManager;
     }
 
-    public Mono<ComposedMessageId> append(MimeMessage mail, Username user, 
String folder, Optional<Flags> flags) throws MessagingException {
+    public Mono<ComposedMessageId> append(MimeMessage mail, Username user, 
StorageDirective storageDirective) throws MessagingException {
+        
Preconditions.checkArgument(storageDirective.getTargetFolder().isPresent(), 
"'targetFolder' field is needed");
+
         MailboxSession session = createMailboxSession(user);
-        return append(mail, user, useSlashAsSeparator(folder, session), flags, 
session)
+        return append(mail, user, 
useSlashAsSeparator(storageDirective.getTargetFolder().get(), session), 
storageDirective.getFlags(), session)
             .map(AppendResult::getId);
     }
 
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java
index 44d2de771b..d63795f121 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/SimpleMailStore.java
@@ -101,16 +101,15 @@ public class SimpleMailStore implements MailStore {
     @Override
     public Mono<Void> storeMail(MailAddress recipient, Mail mail) {
         Username username = computeUsername(recipient);
-        String locatedFolder = locateFolder(username, mail);
+        StorageDirective storageDirective = 
StorageDirective.fromMail(computeUsername(recipient), mail)
+            .withDefaultFolder(folder);
 
         try {
-            return Mono.from(mailboxAppender.append(mail.getMessage(), 
username,
-                locateFolder(username, mail),
-                extractFlags(username, mail)))
+            return Mono.from(mailboxAppender.append(mail.getMessage(), 
username, storageDirective))
                 .doOnSuccess(ids -> {
                     metric.increment();
                     LOGGER.info("Local delivered mail {} with messageId {} 
successfully from {} to {} in folder {} with composedMessageId {}",
-                        mail.getName(), getMessageId(mail), 
mail.getMaybeSender().asString(), recipient.asPrettyString(), locatedFolder, 
ids);
+                        mail.getName(), getMessageId(mail), 
mail.getMaybeSender().asString(), recipient.asPrettyString(), 
storageDirective.getTargetFolder().get(), ids);
                 })
                 .then();
         } catch (MessagingException e) {
@@ -118,51 +117,13 @@ public class SimpleMailStore implements MailStore {
         }
     }
 
-    private Optional<Flags> extractFlags(Username username, Mail mail) {
-        Optional<Attribute> seen = 
mail.getAttribute(AttributeName.of(MailStore.SEEN_PREFIX + 
username.asString()));
-        Optional<Attribute> important = 
mail.getAttribute(AttributeName.of(MailStore.IMPORTANT_PREFIX + 
username.asString()));
-        Optional<Attribute> keywords = 
mail.getAttribute(AttributeName.of(MailStore.KEYWORDS_PREFIX + 
username.asString()));
-
-        if (seen.isEmpty() && important.isEmpty() && keywords.isEmpty()) {
-            return Optional.empty();
+    private Username computeUsername(MailAddress recipient) {
+        try {
+            return usersRepository.getUsername(recipient);
+        } catch (UsersRepositoryException e) {
+            LOGGER.warn("Unable to retrieve username for {}", 
recipient.asPrettyString(), e);
+            return Username.of(recipient.asString());
         }
-
-        Flags flags = new Flags();
-        flags.add(encodeFlag(seen, Flags.Flag.SEEN));
-        flags.add(encodeFlag(important, Flags.Flag.FLAGGED));
-        extractKeywords(keywords).forEach(flags::add);
-
-        return Optional.of(flags);
-    }
-
-    @SuppressWarnings("unchecked")
-    private Stream<String> extractKeywords(Optional<Attribute> keywords) {
-        return keywords
-            .map(Attribute::getValue)
-            .map(AttributeValue::getValue)
-            .filter(Collection.class::isInstance)
-            .map(Collection.class::cast)
-            .stream()
-            .flatMap(Collection::stream)
-            .filter(AttributeValue.class::isInstance)
-            .map(AttributeValue.class::cast)
-            .map(a -> ((AttributeValue<?>) a).getValue())
-            .filter(String.class::isInstance)
-            .map(String.class::cast);
-    }
-
-    private Flags encodeFlag(Optional<Attribute> attr, Flags.Flag flag) {
-        Flags flags = new Flags();
-        attr.map(Attribute::getValue)
-            .map(AttributeValue::getValue)
-            .filter(Boolean.class::isInstance)
-            .map(Boolean.class::cast)
-            .ifPresent(seenFlag -> {
-                if (seenFlag) {
-                    flags.add(flag);
-                }
-            });
-        return flags;
     }
 
     private String getMessageId(Mail mail) {
@@ -173,19 +134,4 @@ public class SimpleMailStore implements MailStore {
             return null;
         }
     }
-
-    private String locateFolder(Username username, Mail mail) {
-        return AttributeUtils
-            .getValueAndCastFromMail(mail, 
AttributeName.of(DELIVERY_PATH_PREFIX + username.asString()), String.class)
-            .orElse(folder);
-    }
-
-    private Username computeUsername(MailAddress recipient) {
-        try {
-            return usersRepository.getUsername(recipient);
-        } catch (UsersRepositoryException e) {
-            LOGGER.warn("Unable to retrieve username for {}", 
recipient.asPrettyString(), e);
-            return Username.of(recipient.asString());
-        }
-    }
 }
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/StorageDirective.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/StorageDirective.java
new file mode 100644
index 0000000000..0edb65659e
--- /dev/null
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/delivery/StorageDirective.java
@@ -0,0 +1,196 @@
+/****************************************************************
+ * 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.Collection;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import javax.mail.Flags;
+
+import org.apache.james.core.Username;
+import org.apache.mailet.Attribute;
+import org.apache.mailet.AttributeName;
+import org.apache.mailet.AttributeUtils;
+import org.apache.mailet.AttributeValue;
+import org.apache.mailet.Mail;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.primitives.Booleans;
+
+public class StorageDirective {
+    public static class Builder {
+        private Optional<String> targetFolder = Optional.empty();
+        private Optional<Boolean> seen = Optional.empty();
+        private Optional<Boolean> important = Optional.empty();
+        private Optional<Collection<String>> keywords = Optional.empty();
+
+        public Builder seen(Optional<Boolean> value) {
+            this.seen = value;
+            return this;
+        }
+
+        public Builder important(Optional<Boolean> value) {
+            this.important = value;
+            return this;
+        }
+
+        public Builder targetFolder(Optional<String> value) {
+            this.targetFolder = value;
+            return this;
+        }
+
+        public Builder targetFolder(String value) {
+            this.targetFolder = Optional.of(value);
+            return this;
+        }
+
+        public Builder keywords(Optional<Collection<String>> value) {
+            this.keywords = value;
+            return this;
+        }
+
+        public StorageDirective build() {
+            Preconditions.checkState(
+                Booleans.countTrue(
+                    seen.isPresent(),
+                    important.isPresent(),
+                    targetFolder.isPresent(),
+                    keywords.isPresent()) > 0,
+                "Expecting one of the storage directives to be specified: 
[targetFolder, seen, important, keywords]");
+
+            return new StorageDirective(targetFolder, seen, important, 
keywords);
+        }
+    }
+
+    private static final String DELIVERY_PATH_PREFIX = "DeliveryPath_";
+    private static final String SEEN_PREFIX = "Seen_";
+    private static final String IMPORTANT_PREFIX = "Important_";
+    private static final String KEYWORDS_PREFIX = "Keywords_";
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static StorageDirective fromMail(Username username, Mail mail) {
+        Optional<Attribute> seen = 
mail.getAttribute(AttributeName.of(SEEN_PREFIX + username.asString()));
+        Optional<Attribute> important = 
mail.getAttribute(AttributeName.of(IMPORTANT_PREFIX + username.asString()));
+        Optional<Attribute> keywords = 
mail.getAttribute(AttributeName.of(KEYWORDS_PREFIX + username.asString()));
+
+        return new StorageDirective(
+            locateFolder(username, mail),
+            asBooleanOptional(seen),
+            asBooleanOptional(important),
+            extractKeywords(keywords));
+    }
+
+    @SuppressWarnings("unchecked")
+    private static Optional<Collection<String>> 
extractKeywords(Optional<Attribute> keywords) {
+        Stream<String> stream = keywords
+            .map(Attribute::getValue)
+            .map(AttributeValue::getValue)
+            .filter(Collection.class::isInstance)
+            .map(Collection.class::cast)
+            .stream()
+            .flatMap(Collection::stream)
+            .filter(AttributeValue.class::isInstance)
+            .map(AttributeValue.class::cast)
+            .map(a -> ((AttributeValue<?>) a).getValue())
+            .filter(String.class::isInstance)
+            .map(String.class::cast);
+        Collection<String> result = 
stream.collect(ImmutableSet.toImmutableSet());
+
+        return Optional.of(result)
+            .filter(c -> !c.isEmpty());
+    }
+
+    private static Optional<Boolean> asBooleanOptional(Optional<Attribute> 
attr) {
+        return attr.map(Attribute::getValue)
+            .map(AttributeValue::getValue)
+            .filter(Boolean.class::isInstance)
+            .map(Boolean.class::cast);
+    }
+
+    private static Optional<String> locateFolder(Username username, Mail mail) 
{
+        return AttributeUtils
+            .getValueAndCastFromMail(mail, 
AttributeName.of(DELIVERY_PATH_PREFIX + username.asString()), String.class);
+    }
+
+    private final Optional<String> targetFolder;
+    private final Optional<Boolean> seen;
+    private final Optional<Boolean> important;
+    private final Optional<Collection<String>> keywords;
+
+    private StorageDirective(Optional<String> targetFolder,
+                            Optional<Boolean> seen,
+                            Optional<Boolean> important,
+                            Optional<Collection<String>> keywords) {
+        this.targetFolder = targetFolder;
+        this.seen = seen;
+        this.important = important;
+        this.keywords = keywords;
+    }
+
+    public Optional<Flags> getFlags() {
+        if (seen.isEmpty() && important.isEmpty() && keywords.isEmpty()) {
+            return Optional.empty();
+        }
+
+        Flags flags = new Flags();
+        seen.ifPresent(seenFlag -> {
+                if (seenFlag) {
+                    flags.add(Flags.Flag.SEEN);
+                }
+            });
+        important.ifPresent(seenFlag -> {
+                if (seenFlag) {
+                    flags.add(Flags.Flag.FLAGGED);
+                }
+            });
+        keywords.stream().flatMap(Collection::stream).forEach(flags::add);
+        return Optional.of(flags);
+    }
+
+    public Stream<Attribute> encodeAsAttributes(Username username) {
+        return Stream.of(
+            targetFolder.map(value -> new 
Attribute(AttributeName.of(DELIVERY_PATH_PREFIX + username.asString()), 
AttributeValue.of(value))),
+            seen.map(value -> new Attribute(AttributeName.of(SEEN_PREFIX + 
username.asString()), AttributeValue.of(value))),
+            important.map(value -> new 
Attribute(AttributeName.of(IMPORTANT_PREFIX + username.asString()), 
AttributeValue.of(value))),
+            keywords.map(value -> new 
Attribute(AttributeName.of(KEYWORDS_PREFIX + username.asString()), 
asAttributeValue(value))))
+            .flatMap(Optional::stream);
+    }
+
+    private AttributeValue asAttributeValue(Collection<String> value) {
+        return AttributeValue.of(value.stream()
+            .map(AttributeValue::of)
+            .collect(ImmutableSet.toImmutableSet()));
+    }
+
+    public StorageDirective withDefaultFolder(String folder) {
+        if (targetFolder.isEmpty()) {
+            return new StorageDirective(Optional.of(folder), seen, important, 
keywords);
+        }
+        return this;
+    }
+
+    public Optional<String> getTargetFolder() {
+        return targetFolder;
+    }
+}
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/delivery/SievePoster.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/delivery/SievePoster.java
index 7e19c2949d..a43aa33932 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/delivery/SievePoster.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/jsieve/delivery/SievePoster.java
@@ -26,6 +26,7 @@ import javax.mail.MessagingException;
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.Username;
 import org.apache.james.transport.mailets.delivery.MailStore;
+import org.apache.james.transport.mailets.delivery.StorageDirective;
 import org.apache.james.transport.mailets.jsieve.Poster;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
@@ -51,7 +52,11 @@ public class SievePoster implements Poster {
             if (scheme.equals("mailbox")) {
                 UserAndPath userAndPath = retrieveUserAndPath(url, 
endOfScheme);
 
-                
mail.setAttribute(Attribute.convertToAttribute(MailStore.DELIVERY_PATH_PREFIX + 
userAndPath.user, userAndPath.path));
+                StorageDirective.builder()
+                    .targetFolder(userAndPath.path)
+                    .build()
+                    .encodeAsAttributes(Username.of(userAndPath.user))
+                    .forEach(mail::setAttribute);
             } else {
                 throw new MessagingException("Unsupported protocol");
             }
diff --git 
a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImplTest.java
 
b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImplTest.java
index e9a007975e..46498ea7c6 100644
--- 
a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImplTest.java
+++ 
b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/MailboxAppenderImplTest.java
@@ -49,6 +49,9 @@ class MailboxAppenderImplTest {
 
     public static final Username USER = Username.of("user");
     public static final String FOLDER = "folder";
+    public static final StorageDirective STORAGE_DIRECTIVE = 
StorageDirective.builder()
+        .targetFolder(FOLDER)
+        .build();
     public static final String EMPTY_FOLDER = "";
     private static final Optional<Flags> NO_FLAGS = Optional.empty();
 
@@ -73,7 +76,7 @@ class MailboxAppenderImplTest {
 
     @Test
     void appendShouldAddMessageToDesiredMailbox() throws Exception {
-        Mono.from(testee.append(mimeMessage, USER, FOLDER, NO_FLAGS)).block();
+        Mono.from(testee.append(mimeMessage, USER, STORAGE_DIRECTIVE)).block();
 
         MessageResultIterator messages = 
mailboxManager.getMailbox(MailboxPath.forUser(USER, FOLDER), session)
             .getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session);
@@ -87,7 +90,7 @@ class MailboxAppenderImplTest {
         MailboxPath mailboxPath = MailboxPath.forUser(USER, FOLDER);
         mailboxManager.createMailbox(mailboxPath, session);
 
-        Mono.from(testee.append(mimeMessage, USER, FOLDER, NO_FLAGS)).block();
+        Mono.from(testee.append(mimeMessage, USER, STORAGE_DIRECTIVE)).block();
 
         MessageResultIterator messages = 
mailboxManager.getMailbox(mailboxPath, session)
             .getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session);
@@ -98,13 +101,17 @@ class MailboxAppenderImplTest {
 
     @Test
     void appendShouldNotAppendToEmptyFolder() {
-        assertThatThrownBy(() -> Mono.from(testee.append(mimeMessage, USER, 
EMPTY_FOLDER, NO_FLAGS)).block())
+        assertThatThrownBy(() -> Mono.from(testee.append(mimeMessage, USER, 
StorageDirective.builder()
+            .targetFolder(EMPTY_FOLDER)
+            .build())).block())
             .isInstanceOf(MessagingException.class);
     }
 
     @Test
     void appendShouldRemovePathSeparatorAsFirstChar() throws Exception {
-        Mono.from(testee.append(mimeMessage, USER, "." + FOLDER, 
NO_FLAGS)).block();
+        Mono.from(testee.append(mimeMessage, USER, StorageDirective.builder()
+            .targetFolder("." + FOLDER)
+            .build())).block();
 
         MessageResultIterator messages = 
mailboxManager.getMailbox(MailboxPath.forUser(USER, FOLDER), session)
             .getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session);
@@ -115,7 +122,10 @@ class MailboxAppenderImplTest {
 
     @Test
     void appendShouldSupportFlags() throws Exception {
-        Mono.from(testee.append(mimeMessage, USER, "." + FOLDER, 
Optional.of(new Flags(Flags.Flag.SEEN)))).block();
+        Mono.from(testee.append(mimeMessage, USER, StorageDirective.builder()
+            .targetFolder("." + FOLDER)
+            .seen(Optional.of(true))
+            .build())).block();
 
         MessageResultIterator messages = 
mailboxManager.getMailbox(MailboxPath.forUser(USER, FOLDER), session)
             .getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session);
@@ -125,7 +135,9 @@ class MailboxAppenderImplTest {
 
     @Test
     void appendShouldReplaceSlashBySeparator() throws Exception {
-        Mono.from(testee.append(mimeMessage, USER, FOLDER + "/any", 
NO_FLAGS)).block();
+        Mono.from(testee.append(mimeMessage, USER, StorageDirective.builder()
+            .targetFolder(FOLDER + "/any")
+            .build())).block();
 
         MessageResultIterator messages = 
mailboxManager.getMailbox(MailboxPath.forUser(USER, FOLDER + ".any"), session)
             .getMessages(MessageRange.all(), FetchGroup.FULL_CONTENT, session);
@@ -137,7 +149,9 @@ class MailboxAppenderImplTest {
     @RepeatedTest(20)
     void appendShouldNotFailInConcurrentEnvironment() throws Exception {
         ConcurrentTestRunner.builder()
-            .reactorOperation((a, b) -> Mono.from(testee.append(mimeMessage, 
USER, FOLDER + "/any", NO_FLAGS)).then())
+            .reactorOperation((a, b) -> Mono.from(testee.append(mimeMessage, 
USER, StorageDirective.builder()
+                .targetFolder(FOLDER + "/any")
+                .build())).then())
             .threadCount(100)
             .runSuccessfullyWithin(Duration.ofMinutes(1));
     }
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 a0ce6b08ca..c2eeffbb95 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
@@ -66,12 +66,12 @@ class SieveIntegrationTest {
     private static final MailboxPath INBOX = MailboxPath.inbox(LOCAL_USER);
     private static final MailboxPath INBOX_ANY = 
MailboxPath.forUser(LOCAL_USER, "INBOX.any");
 
-    private static final AttributeName ATTRIBUTE_NAME = 
AttributeName.of(MailStore.DELIVERY_PATH_PREFIX + LOCAL_PART);
+    private static final AttributeName ATTRIBUTE_NAME = 
AttributeName.of("DeliveryPath_" + LOCAL_PART);
     private static final Attribute ATTRIBUTE_INBOX = new 
Attribute(ATTRIBUTE_NAME, 
AttributeValue.of(expressMailboxNameWithSlash(INBOX.getName())));
     private static final Attribute ATTRIBUTE_INBOX_ANY = new 
Attribute(ATTRIBUTE_NAME, 
AttributeValue.of(expressMailboxNameWithSlash(INBOX_ANY.getName())));
     private static final Attribute ATTRIBUTE_SELECTED_MAILBOX = new 
Attribute(ATTRIBUTE_NAME, 
AttributeValue.of(expressMailboxNameWithSlash(SELECTED_MAILBOX.getName())));
     private static final Attribute ATTRIBUTE_NOT_SELECTED_MAILBOX = new 
Attribute(ATTRIBUTE_NAME, 
AttributeValue.of(expressMailboxNameWithSlash(NOT_SELECTED_MAILBOX.getName())));
-    private static final AttributeName ATTRIBUTE_NAME_DOMAIN = 
AttributeName.of(MailStore.DELIVERY_PATH_PREFIX + RECEIVER_DOMAIN_COM);
+    private static final AttributeName ATTRIBUTE_NAME_DOMAIN = 
AttributeName.of("DeliveryPath_" + RECEIVER_DOMAIN_COM);
     private static final Attribute ATTRIBUTE_INBOX_DOMAIN = new 
Attribute(ATTRIBUTE_NAME_DOMAIN, 
AttributeValue.of(expressMailboxNameWithSlash(INBOX.getName())));
 
     private Sieve testee;
diff --git 
a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStoreTest.java
 
b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStoreTest.java
index fabb57a14f..f57f936d89 100644
--- 
a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStoreTest.java
+++ 
b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/delivery/SimpleMailStoreTest.java
@@ -50,7 +50,7 @@ class SimpleMailStoreTest {
     @BeforeEach
     void setUp() throws Exception {
         mailboxAppender = mock(MailboxAppenderImpl.class);
-        when(mailboxAppender.append(any(), any(), any(), 
any())).thenReturn(Mono.empty());
+        when(mailboxAppender.append(any(), any(), 
any())).thenReturn(Mono.empty());
         usersRepository = mock(UsersRepository.class);
         testee = SimpleMailStore.builder()
             .usersRepository(usersRepository)
@@ -76,7 +76,7 @@ class SimpleMailStoreTest {
             .build();
         testee.storeMail(recipient, mail);
 
-        verify(mailboxAppender).append(any(MimeMessage.class), 
eq(Username.of(recipient.asString())), eq(FOLDER), any());
+        verify(mailboxAppender).append(any(MimeMessage.class), 
eq(Username.of(recipient.asString())), any());
     }
 
     @Test
@@ -89,7 +89,7 @@ class SimpleMailStoreTest {
             .build();
         testee.storeMail(recipient, mail);
 
-        verify(mailboxAppender).append(any(MimeMessage.class), 
eq(Username.of(recipient.getLocalPart())), eq(FOLDER), any());
+        verify(mailboxAppender).append(any(MimeMessage.class), 
eq(Username.of(recipient.getLocalPart())), any());
     }
 
     @Test
@@ -102,6 +102,6 @@ class SimpleMailStoreTest {
             .build();
         testee.storeMail(recipient, mail);
 
-        verify(mailboxAppender).append(any(MimeMessage.class), 
eq(Username.of(recipient.toString())), eq(FOLDER), any());
+        verify(mailboxAppender).append(any(MimeMessage.class), 
eq(Username.of(recipient.toString())), any());
     }
 }


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


Reply via email to