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]
