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

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

commit f1ca51e39dca8d92e171023a20fb1b2171dada89
Author: Benoit Tellier <[email protected]>
AuthorDate: Thu Nov 21 17:20:11 2019 +0700

    JAMES-2904 MessageResult::hasAttachment
    
    This method is callable at Metadata level on top of Cassandra but needs some
    message content parsing for JPA or MailDir
---
 .../apache/james/mailbox/model/MessageResult.java  | 12 +++-
 .../apache/james/mailbox/MailboxManagerTest.java   | 45 +++++++++++++++
 .../src/test/resources/eml/twoAttachmentsApi.eml   | 64 ++++++++++++++++++++++
 .../cassandra/mail/CassandraMessageDAO.java        | 21 ++++---
 .../cassandra/mail/MessageWithoutAttachment.java   |  7 ++-
 .../cassandra/table/CassandraMessageV2Table.java   |  4 +-
 .../model/openjpa/AbstractJPAMailboxMessage.java   |  5 ++
 .../mailbox/maildir/mail/model/MaildirMessage.java |  5 ++
 .../james/mailbox/store/MessageResultImpl.java     |  7 ++-
 .../mailbox/store/StoreMessageResultIterator.java  |  7 ++-
 .../store/mail/model/DelegatingMailboxMessage.java |  5 ++
 .../james/mailbox/store/mail/model/Message.java    |  2 +
 .../mail/model/impl/SimpleMailboxMessage.java      | 31 +++++++++--
 .../store/mail/model/impl/SimpleMessage.java       |  9 ++-
 .../store/AbstractMessageIdManagerStorageTest.java | 31 +++++++++++
 .../mailbox/store/MessageIdManagerTestSystem.java  |  3 +
 16 files changed, 236 insertions(+), 22 deletions(-)

diff --git 
a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java 
b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
index 35a9329..7393e7d 100644
--- 
a/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
+++ 
b/mailbox/api/src/main/java/org/apache/james/mailbox/model/MessageResult.java
@@ -253,8 +253,18 @@ public interface MessageResult extends 
Comparable<MessageResult> {
 
     
     Headers getHeaders() throws MailboxException;
-    
+
+    /**
+     * Returns the list of loaded attachments depending on the fetchType.
+     *
+     * These attachments will be loaded only for Full
+     */
     List<MessageAttachment> getAttachments() throws MailboxException;
+
+    /**
+     * Indicates if the message have attachments, regardless of loaded 
attachments.
+     */
+    boolean hasAttachments() throws MailboxException;
     
     /**
      * Describes a path within a multipart MIME message. All implementations
diff --git 
a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java 
b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
index 6293e57..fac59ae 100644
--- a/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
+++ b/mailbox/api/src/test/java/org/apache/james/mailbox/MailboxManagerTest.java
@@ -70,6 +70,7 @@ import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
 import org.apache.james.mailbox.model.MessageResult;
+import org.apache.james.mailbox.model.MessageResultIterator;
 import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
 import org.apache.james.mailbox.model.Quota;
 import org.apache.james.mailbox.model.QuotaRoot;
@@ -77,6 +78,7 @@ import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.search.MailboxQuery;
 import org.apache.james.mailbox.util.EventCollector;
 import org.apache.james.mime4j.dom.Message;
+import org.apache.james.util.ClassLoaderUtils;
 import org.apache.james.util.concurrency.ConcurrentTestRunner;
 import org.assertj.core.api.SoftAssertions;
 import org.junit.jupiter.api.AfterEach;
@@ -85,9 +87,11 @@ import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
 
+import com.github.fge.lambdas.Throwing;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+
 import reactor.core.publisher.Mono;
 
 /**
@@ -1804,4 +1808,45 @@ public abstract class MailboxManagerTest<T extends 
MailboxManager> {
             }
         }
     }
+
+    @Nested
+    class MessageTests {
+        private MessageManager inboxManager;
+
+        @BeforeEach
+        void setUp() throws Exception {
+            session = mailboxManager.createSystemSession(USER_1);
+            MailboxPath inbox = MailboxPath.inbox(session);
+            mailboxManager.createMailbox(inbox, session).get();
+            inboxManager = mailboxManager.getMailbox(inbox, session);
+        }
+
+        @Test
+        void getMessagesShouldIncludeHasAttachmentInformation() throws 
Exception {
+            ComposedMessageId composeId = 
inboxManager.appendMessage(AppendCommand.builder()
+                .withFlags(new Flags(Flags.Flag.DELETED))
+                
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")),
 session);
+
+            MessageResultIterator messages = 
inboxManager.getMessages(MessageRange.one(composeId.getUid()), 
FetchGroupImpl.MINIMAL, session);
+
+            assertThat(messages).toIterable()
+                .hasSize(1)
+                .first()
+                .satisfies(Throwing.consumer(messageResult -> 
assertThat(messageResult.hasAttachments()).isTrue()));
+        }
+
+        @Test
+        void getMessagesShouldNotIncludeAttachmentInformationWhenNone() throws 
Exception {
+            ComposedMessageId composeId = 
inboxManager.appendMessage(AppendCommand.builder()
+                .withFlags(new Flags(Flags.Flag.DELETED))
+                .build(message), session);
+
+            MessageResultIterator messages = 
inboxManager.getMessages(MessageRange.one(composeId.getUid()), 
FetchGroupImpl.MINIMAL, session);
+
+            assertThat(messages).toIterable()
+                .hasSize(1)
+                .first()
+                .satisfies(Throwing.consumer(messageResult -> 
assertThat(messageResult.hasAttachments()).isFalse()));
+        }
+    }
 }
diff --git a/mailbox/api/src/test/resources/eml/twoAttachmentsApi.eml 
b/mailbox/api/src/test/resources/eml/twoAttachmentsApi.eml
new file mode 100644
index 0000000..c93a59d
--- /dev/null
+++ b/mailbox/api/src/test/resources/eml/twoAttachmentsApi.eml
@@ -0,0 +1,64 @@
+Return-Path: <[email protected]>
+X-Priority: 3 (Normal)
+From: "From"
+ <[email protected]>
+To: "To"
+ <[email protected]>
+Subject: [8/10]Attached Image light with text
+Date: Fri, 27 Mar 2015 21:48:38 +0100
+Message-Id: <[email protected]>
+Mime-Version: 1.0
+Content-Type: multipart/mixed;
+ boundary="AHNPACBLDCDIDAGGGDDFAABECGCA"
+
+--AHNPACBLDCDIDAGGGDDFAABECGCA
+Content-Type: text/html; charset=utf-8; format=flowed
+Content-Transfer-Encoding: 8bit
+
+<b>html</b>
+
+--AHNPACBLDCDIDAGGGDDFAABECGCA
+Content-Type: image/jpeg;
+ name="4037_014.jpg"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+ filename="4037_014.jpg"
+
+/9j/4X2cRXhpZgAASUkqAAgAAAANAA8BAgAKAAAAqgAAABABAgAJAAAAtAAAABIBAwABAAAA
+AQAAABoBBQABAAAAvgAAABsBBQABAAAAxgAAACgBAwABAAAAAgAAADEBAgAKAAAAzgAAADIB
+AgAUAAAA2AAAABMCAwABAAAAAgAAAGmHBAABAAAAfAIAAKXEBwDQAAAA7AAAANLGBwBAAAAA
+vAEAANPGBwCAAAAA/AEAAEwqAABQYW5hc29uaWMARE1DLUZaNDUAALQAAAABAAAAtAAAAAEA
+AABWZXIuMS4wICAAMjAxNDowMjoyNSAxMDozMjowOQBQcmludElNADAyNTAAAA4AAQAWABYA
+AgAAAAAAAwBkAAAABwAAAAAACAAAAAAACQAAAAAACgAAAAAACwCsAAAADAAAAAAADQAAAAAA
+DgDEAAAAAAEFAAAAAQEBAAAAEAGAAAAACREAABAnAAALDwAAECcAAJcFAAAQJwAAsAgAABAn
+AAABHAAAECcAAF4CAAAQJwAAiwAAABAnAADLAwAAECcAAOUbAAAQJwAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+--AHNPACBLDCDIDAGGGDDFAABECGCA
+Content-Type: image/jpeg;
+ name="4037_015.jpg"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+ filename="4037_015.jpg"
+
+iVBORw0KGgoAAAANSUhEUgAABYUAAAL4CAIAAACrzA8fAAAACXBIWXMAAAsTAAALEwEAmpwY
+AAAAB3RJTUUH3wMNDiUMca0XkQAAIABJREFUeNq8vWm0bdlVHja/tc+99zX13qv2VSeVmlIv
+FSqEOhA2AoEhxMRBg8QOyEkG6WMDSZzhMQTGDDcwiJPhBBMby4SMDJthgmOMAYvGMcF0QgIU
+WRKobymp+qpX9fp779nry4+9mjnnWuuc80qMvCpdvXrv3nP22Xutueb85je/D1/3+q+ipF9z
+nGfGdZznGCMjKaSIkJQwBYSAEMI0Tatptdrb21utVqvVtJKAAAABEAAiUP+IiECYfsfyJf1B
+10+cOHH48OGVlZVSypaWlv379zc2Nr722msNDQ2u+y9zaYQeAQAAAACCHgEAAAB0y969e+ON
+KnpOe3v7JZdccj6fwPXr10+aNKnAB956663Zs2fjTgMAAADOKzhOAQAAAFCYs+yO0XfNNQAA
+AAAA/nNBfgQAAADQDVddddW6detSqdQZ7JvL5W655RZIEgAAAAAAEayKigqcBQAAAKAAhw8f
+3rZt25AhQwYNGpTJZHq4V2tr6/bt25csWbJjxw6cQwAAAACACMiPAAAAAAAAAAAAQH8D/wgA
+AAAAAAAAAAD0N9AjAAAAAAAAAAAA0N9AjwAAAAAAAAAAAEB/Az0CAAAAAAAAAAAA/Q30CAAA
+AAAAAAAAAPQ30CMAAAAAAAAAAADQ30CPAAAAAAAAAAAAQH/z/0IKJwmNQbpqAAAAAElFTkSu
+QmCC
+
+--AHNPACBLDCDIDAGGGDDFAABECGCA--
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
index 37976ab..b29e7e8 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageDAO.java
@@ -270,8 +270,9 @@ public class CassandraMessageDAO {
                     getPropertyBuilder(row),
                     messageId.getMailboxId(),
                     messageId.getUid(),
-                    messageIdWithMetaData.getModSeq());
-            return found(Pair.of(messageWithoutAttachment, getAttachments(row, 
fetchType)));
+                    messageIdWithMetaData.getModSeq(),
+                    hasAttachment(row));
+            return found(Pair.of(messageWithoutAttachment, 
getAttachments(row)));
         });
     }
 
@@ -288,16 +289,14 @@ public class CassandraMessageDAO {
         return new Property(udtValue.getString(Properties.NAMESPACE), 
udtValue.getString(Properties.NAME), udtValue.getString(Properties.VALUE));
     }
 
-    private Stream<MessageAttachmentRepresentation> getAttachments(Row row, 
FetchType fetchType) {
-        switch (fetchType) {
-            case Full:
-            case Body:
-                List<UDTValue> udtValues = row.getList(ATTACHMENTS, 
UDTValue.class);
+    private Stream<MessageAttachmentRepresentation> getAttachments(Row row) {
+        List<UDTValue> udtValues = row.getList(ATTACHMENTS, UDTValue.class);
+        return attachmentByIds(udtValues);
+    }
 
-                return attachmentByIds(udtValues);
-            default:
-                return Stream.of();
-        }
+    private boolean hasAttachment(Row row) {
+        List<UDTValue> udtValues = row.getList(ATTACHMENTS, UDTValue.class);
+        return !udtValues.isEmpty();
     }
 
     private Stream<MessageAttachmentRepresentation> 
attachmentByIds(List<UDTValue> udtValues) {
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
index 89f57b2..226e8bc 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/MessageWithoutAttachment.java
@@ -21,6 +21,7 @@ package org.apache.james.mailbox.cassandra.mail;
 
 import java.util.Date;
 import java.util.List;
+
 import javax.mail.Flags;
 import javax.mail.util.SharedByteArrayInputStream;
 
@@ -44,9 +45,11 @@ public class MessageWithoutAttachment {
     private final MailboxId mailboxId;
     private final MessageUid messageUid;
     private final long modSeq;
+    private final boolean hasAttachment;
 
     public MessageWithoutAttachment(MessageId messageId, Date internalDate, 
Long size, Integer bodySize, SharedByteArrayInputStream content,
-                                    Flags flags, PropertyBuilder 
propertyBuilder, MailboxId mailboxId, MessageUid messageUid, long modSeq) {
+                                    Flags flags, PropertyBuilder 
propertyBuilder, MailboxId mailboxId, MessageUid messageUid, long modSeq,
+                                    boolean hasAttachment) {
         this.messageId = messageId;
         this.internalDate = internalDate;
         this.size = size;
@@ -57,6 +60,7 @@ public class MessageWithoutAttachment {
         this.mailboxId = mailboxId;
         this.messageUid = messageUid;
         this.modSeq = modSeq;
+        this.hasAttachment = hasAttachment;
     }
 
     public SimpleMailboxMessage toMailboxMessage(List<MessageAttachment> 
attachments) {
@@ -72,6 +76,7 @@ public class MessageWithoutAttachment {
             .flags(flags)
             .propertyBuilder(propertyBuilder)
             .addAttachments(attachments)
+            .hasAttachment(hasAttachment)
             .build();
     }
 
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageV2Table.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageV2Table.java
index c2421f3..2d41173 100644
--- 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageV2Table.java
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/table/CassandraMessageV2Table.java
@@ -35,8 +35,8 @@ public interface CassandraMessageV2Table {
     String ATTACHMENTS = "attachments";
 
     String[] FIELDS = { MESSAGE_ID, INTERNAL_DATE, BODY_START_OCTET, 
FULL_CONTENT_OCTETS, BODY_OCTECTS, BODY_CONTENT, HEADER_CONTENT, 
TEXTUAL_LINE_COUNT, PROPERTIES, ATTACHMENTS };
-    String[] METADATA = { MESSAGE_ID, INTERNAL_DATE, BODY_START_OCTET, 
FULL_CONTENT_OCTETS, BODY_OCTECTS, TEXTUAL_LINE_COUNT, PROPERTIES };
-    String[] HEADERS = { MESSAGE_ID, INTERNAL_DATE, BODY_START_OCTET, 
FULL_CONTENT_OCTETS, BODY_OCTECTS, HEADER_CONTENT, TEXTUAL_LINE_COUNT, 
PROPERTIES };
+    String[] METADATA = { MESSAGE_ID, INTERNAL_DATE, BODY_START_OCTET, 
FULL_CONTENT_OCTETS, BODY_OCTECTS, TEXTUAL_LINE_COUNT, PROPERTIES, ATTACHMENTS 
};
+    String[] HEADERS = { MESSAGE_ID, INTERNAL_DATE, BODY_START_OCTET, 
FULL_CONTENT_OCTETS, BODY_OCTECTS, HEADER_CONTENT, TEXTUAL_LINE_COUNT, 
PROPERTIES, ATTACHMENTS };
     String[] BODY = { MESSAGE_ID, INTERNAL_DATE, BODY_START_OCTET, 
FULL_CONTENT_OCTETS, BODY_OCTECTS, BODY_CONTENT, TEXTUAL_LINE_COUNT, 
PROPERTIES, ATTACHMENTS };
 
     interface Properties {
diff --git 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
index 6277c72..55986fc 100644
--- 
a/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
+++ 
b/mailbox/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/AbstractJPAMailboxMessage.java
@@ -510,4 +510,9 @@ public abstract class AbstractJPAMailboxMessage implements 
MailboxMessage {
         }
     }
 
+    @Override
+    public boolean hasAttachment() {
+        return !getAttachments().isEmpty();
+    }
+
 }
diff --git 
a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
 
b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
index a9e37b6..5826657 100644
--- 
a/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
+++ 
b/mailbox/maildir/src/main/java/org/apache/james/mailbox/maildir/mail/model/MaildirMessage.java
@@ -275,4 +275,9 @@ public class MaildirMessage implements Message {
         }
     }
 
+    @Override
+    public boolean hasAttachment() {
+        return !getAttachments().isEmpty();
+    }
+
 }
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
index 18cb8ea..308873c 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/MessageResultImpl.java
@@ -312,7 +312,12 @@ public class MessageResultImpl implements MessageResult {
     public List<MessageAttachment> getAttachments() {
         return message.getAttachments();
     }
-    
+
+    @Override
+    public boolean hasAttachments() {
+        return message.hasAttachment();
+    }
+
     private static final class HeadersImpl implements Headers {
 
         private final MailboxMessage msg;
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
index 8bc1f43..707e671 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMessageResultIterator.java
@@ -265,7 +265,12 @@ public class StoreMessageResultIterator implements 
MessageResultIterator {
         public Content getBody() throws MailboxException {
             throw exception;
         }
-        
+
+        @Override
+        public boolean hasAttachments() throws MailboxException {
+            throw exception;
+        }
+
         @Override
         public int compareTo(MessageResult that) {
             return getUid().compareTo(that.getUid());
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java
index 46e5a94..4f09b14 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/DelegatingMailboxMessage.java
@@ -119,4 +119,9 @@ public abstract class DelegatingMailboxMessage implements 
MailboxMessage {
     public List<MessageAttachment> getAttachments() {
         return message.getAttachments();
     }
+
+    @Override
+    public boolean hasAttachment() {
+        return message.hasAttachment();
+    }
 }
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java
index 3f46ad4..e732d21 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Message.java
@@ -109,4 +109,6 @@ public interface Message {
      */
     List<MessageAttachment> getAttachments();
 
+    boolean hasAttachment();
+
 }
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
index 4adfb49..c947f25 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMailboxMessage.java
@@ -64,6 +64,7 @@ public class SimpleMailboxMessage extends 
DelegatingMailboxMessage {
         private Optional<MessageUid> uid = Optional.empty();
         private Optional<Long> modseq = Optional.empty();
         private ImmutableList.Builder<MessageAttachment> attachments = 
ImmutableList.builder();
+        private Optional<Boolean> hasAttachment = Optional.empty();
 
         public Builder messageId(MessageId messageId) {
             this.messageId = messageId;
@@ -103,6 +104,16 @@ public class SimpleMailboxMessage extends 
DelegatingMailboxMessage {
             return this;
         }
 
+        public Builder hasAttachment() {
+            this.hasAttachment = Optional.of(true);
+            return this;
+        }
+
+        public Builder hasAttachment(boolean hasAttachment) {
+            this.hasAttachment = Optional.of(hasAttachment);
+            return this;
+        }
+
         public Builder flags(Flags flags) {
             this.flags = flags;
             return this;
@@ -133,8 +144,10 @@ public class SimpleMailboxMessage extends 
DelegatingMailboxMessage {
             Preconditions.checkNotNull(propertyBuilder, "propertyBuilder is 
required");
             Preconditions.checkNotNull(mailboxId, "mailboxId is required");
 
+            ImmutableList<MessageAttachment> attachments = 
this.attachments.build();
+            boolean hasAttachment = 
this.hasAttachment.orElse(!attachments.isEmpty());
             SimpleMailboxMessage simpleMailboxMessage = new 
SimpleMailboxMessage(messageId, internalDate, size,
-                bodyStartOctet, content, flags, propertyBuilder, mailboxId, 
attachments.build());
+                bodyStartOctet, content, flags, propertyBuilder, mailboxId, 
attachments, hasAttachment);
 
             uid.ifPresent(simpleMailboxMessage::setUid);
             modseq.ifPresent(simpleMailboxMessage::setModSeq);
@@ -162,6 +175,7 @@ public class SimpleMailboxMessage extends 
DelegatingMailboxMessage {
             .internalDate(original.getInternalDate())
             .size(original.getFullContentOctets())
             .flags(original.createFlags())
+            .hasAttachment(original.hasAttachment())
             .propertyBuilder(propertyBuilder);
     }
 
@@ -191,7 +205,8 @@ public class SimpleMailboxMessage extends 
DelegatingMailboxMessage {
 
     public SimpleMailboxMessage(MessageId messageId, Date internalDate, long 
size, int bodyStartOctet,
             SharedInputStream content, Flags flags,
-            PropertyBuilder propertyBuilder, MailboxId mailboxId, 
List<MessageAttachment> attachments) {
+            PropertyBuilder propertyBuilder, MailboxId mailboxId, 
List<MessageAttachment> attachments,
+            boolean hasAttachment) {
         super(new SimpleMessage(
                 messageId,
                 content, size, internalDate, propertyBuilder.getSubType(),
@@ -199,8 +214,8 @@ public class SimpleMailboxMessage extends 
DelegatingMailboxMessage {
                 bodyStartOctet,
                 propertyBuilder.getTextualLineCount(),
                 propertyBuilder.toProperties(),
-                attachments
-                ));
+                attachments,
+                hasAttachment));
 
             setFlags(flags);
             this.mailboxId = mailboxId;
@@ -208,6 +223,14 @@ public class SimpleMailboxMessage extends 
DelegatingMailboxMessage {
     }
 
     public SimpleMailboxMessage(MessageId messageId, Date internalDate, long 
size, int bodyStartOctet,
+            SharedInputStream content, Flags flags,
+            PropertyBuilder propertyBuilder, MailboxId mailboxId, 
List<MessageAttachment> attachments) {
+        this(messageId, internalDate, size, bodyStartOctet,
+            content, flags,
+            propertyBuilder, mailboxId, attachments, !attachments.isEmpty());
+    }
+
+    public SimpleMailboxMessage(MessageId messageId, Date internalDate, long 
size, int bodyStartOctet,
                                 SharedInputStream content, Flags flags,
                                 PropertyBuilder propertyBuilder, MailboxId 
mailboxId) {
         this(messageId, internalDate, size, bodyStartOctet,
diff --git 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java
 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java
index 69d3d85..0302fe5 100644
--- 
a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java
+++ 
b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/SimpleMessage.java
@@ -42,8 +42,9 @@ public class SimpleMessage implements Message {
     private final Long textualLineCount;
     private final List<Property> properties;
     private final List<MessageAttachment> attachments;
+    private final boolean hasAttachments;
 
-    public SimpleMessage(MessageId messageId, SharedInputStream content, long 
size, Date internalDate, String subType, String mediaType, int bodyStartOctet, 
Long textualLineCount, List<Property> properties, List<MessageAttachment> 
attachments) {
+    public SimpleMessage(MessageId messageId, SharedInputStream content, long 
size, Date internalDate, String subType, String mediaType, int bodyStartOctet, 
Long textualLineCount, List<Property> properties, List<MessageAttachment> 
attachments, boolean hasAttachments) {
         this.messageId = messageId;
         this.subType = subType;
         this.mediaType = mediaType;
@@ -54,6 +55,7 @@ public class SimpleMessage implements Message {
         this.textualLineCount = textualLineCount;
         this.properties = properties;
         this.attachments = attachments;
+        this.hasAttachments = hasAttachments;
     }
 
     @Override
@@ -124,4 +126,9 @@ public class SimpleMessage implements Message {
     public List<MessageAttachment> getAttachments() {
         return attachments;
     }
+
+    @Override
+    public boolean hasAttachment() {
+        return hasAttachments;
+    }
 }
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
index 966ff22..9099406 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMessageIdManagerStorageTest.java
@@ -47,9 +47,11 @@ import org.apache.james.mailbox.model.MailboxACL.Right;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageResult;
+import org.apache.james.util.ClassLoaderUtils;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 
@@ -980,4 +982,33 @@ public abstract class AbstractMessageIdManagerStorageTest {
             .extracting(MessageResult::getFlags)
             .containsOnly(flags);
     }
+
+    @Test
+    void getMessagesShouldIncludeAttachmentInformation() throws Exception {
+        MessageId messageId = 
testingData.getMailboxManager().getMailbox(bobMailbox1.getMailboxId(), 
bobSession)
+            .appendMessage(MessageManager.AppendCommand.builder()
+            .withFlags(new Flags(Flags.Flag.DELETED))
+            
.build(ClassLoaderUtils.getSystemResourceAsSharedStream("eml/twoAttachmentsApi.eml")),
 bobSession)
+            .getMessageId();
+
+        List<MessageResult> messages = 
messageIdManager.getMessages(ImmutableList.of(messageId), 
FetchGroupImpl.MINIMAL, bobSession);
+
+        assertThat(messages)
+            .hasSize(1)
+            .first()
+            .satisfies(Throwing.consumer(messageResult -> 
assertThat(messageResult.hasAttachments()).isTrue()));
+    }
+
+    @Test
+    void getMessagesShouldNotIncludeAttachmentInformationWhenNone() throws 
Exception {
+        Flags flags = new Flags(Flags.Flag.FLAGGED);
+        MessageId messageId = testingData.persist(bobMailbox1.getMailboxId(), 
messageUid1, flags, bobSession);
+
+        List<MessageResult> messages = 
messageIdManager.getMessages(ImmutableList.of(messageId), 
FetchGroupImpl.MINIMAL, bobSession);
+
+        assertThat(messages)
+            .hasSize(1)
+            .first()
+            .satisfies(Throwing.consumer(messageResult -> 
assertThat(messageResult.hasAttachments()).isFalse()));
+    }
 }
diff --git 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
index a0f56d2..30a4817 100644
--- 
a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
+++ 
b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageIdManagerTestSystem.java
@@ -67,6 +67,9 @@ public class MessageIdManagerTestSystem {
         this.mailboxManager = mailboxManager;
     }
 
+    public StoreMailboxManager getMailboxManager() {
+        return mailboxManager;
+    }
 
     public MessageIdManager getMessageIdManager() {
         return messageIdManager;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to