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 5afc1619b86b4e07612c716834a4da2f91e69d7a Author: Tran Tien Duc <[email protected]> AuthorDate: Tue Dec 3 14:49:30 2019 +0700 JAMES-2992 hasAttachment is a fast view property --- .../org/apache/james/jmap/draft/model/Emailer.java | 8 +++----- .../draft/model/message/view/MessageFastView.java | 21 ++++++++++++++++++--- .../model/message/view/MessageFastViewFactory.java | 6 +++--- .../draft/model/message/view/MessageFullView.java | 21 +++++++++++---------- .../draft/model/message/view/MessageHeaderView.java | 10 ++++++++-- .../jmap/draft/json/ParsingWritingObjects.java | 1 + .../apache/james/jmap/draft/model/EmailerTest.java | 6 +++--- .../jmap/draft/model/SetMessagesResponseTest.java | 2 ++ .../message/view/MessageFastViewFactoryTest.java | 6 ++++-- .../message/view/MessageFullViewFactoryTest.java | 3 +++ .../model/message/view/MessageFullViewTest.java | 19 +++++++++++++++---- 11 files changed, 71 insertions(+), 32 deletions(-) diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Emailer.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Emailer.java index 819831c..ffb037c 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Emailer.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/Emailer.java @@ -56,13 +56,11 @@ public class Emailer { .orElse(ImmutableList.of()); } - public static Emailer firstFromMailboxList(MailboxList list) { + public static Optional<Emailer> firstFromMailboxList(MailboxList list) { return Optional.ofNullable(list) - .map(mailboxes -> mailboxes.stream() + .flatMap(mailboxes -> mailboxes.stream() .map(Emailer::fromMailbox) - .findFirst() - .orElse(null)) - .orElse(null); + .findFirst()); } private static Emailer fromMailbox(Mailbox mailbox) { diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastView.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastView.java index 3143ba1..5c0eaae 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastView.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastView.java @@ -54,10 +54,12 @@ public class MessageFastView extends MessageHeaderView { @JsonPOJOBuilder(withPrefix = "") public static class Builder<S extends MessageFastView.Builder<S>> extends MessageHeaderView.Builder<S> { protected Optional<Preview> preview; + protected Optional<Boolean> hasAttachment; protected Builder() { super(); this.preview = Optional.empty(); + this.hasAttachment = Optional.empty(); } public S preview(Preview preview) { @@ -70,22 +72,29 @@ public class MessageFastView extends MessageHeaderView { return (S) this; } + public S hasAttachment(boolean hasAttachment) { + this.hasAttachment = Optional.of(hasAttachment); + return (S) this; + } + public MessageFastView build() { checkState(); return new MessageFastView(id, blobId, threadId, mailboxIds, Optional.ofNullable(inReplyToMessageId), - headers, Optional.ofNullable(from), + headers, from, to.build(), cc.build(), bcc.build(), replyTo.build(), subject, date, size, PreviewDTO.from(preview), - keywords.orElse(Keywords.DEFAULT_VALUE)); + keywords.orElse(Keywords.DEFAULT_VALUE), hasAttachment.get()); } @Override public void checkState() { super.checkState(); Preconditions.checkState(preview != null, "'preview' is mandatory"); + Preconditions.checkState(hasAttachment.isPresent(), "'hasAttachment' should be present"); } } private final PreviewDTO preview; + private final boolean hasAttachment; @VisibleForTesting MessageFastView(MessageId id, @@ -103,12 +112,18 @@ public class MessageFastView extends MessageHeaderView { Instant date, Number size, PreviewDTO preview, - Keywords keywords) { + Keywords keywords, + boolean hasAttachment) { super(id, blobId, threadId, mailboxIds, inReplyToMessageId, headers, from, to, cc, bcc, replyTo, subject, date, size, keywords); this.preview = preview; + this.hasAttachment = hasAttachment; } public PreviewDTO getPreview() { return preview; } + + public boolean isHasAttachment() { + return hasAttachment; + } } diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactory.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactory.java index edc43b7..e33993b 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactory.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactory.java @@ -42,7 +42,6 @@ import org.apache.james.mime4j.dom.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.github.steveash.guavate.Guavate; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.base.Strings; @@ -73,7 +72,7 @@ public class MessageFastViewFactory implements MessageViewFactory<MessageFastVie MessageResult firstMessageResult = messageResults.iterator().next(); Preconditions.checkArgument(fastProjections.containsKey(firstMessageResult.getMessageId()), "FromMessageResultAndPreview usage requires a precomputed preview"); - + MessageFastViewPrecomputedProperties messageProjection = fastProjections.get(firstMessageResult.getMessageId()); List<MailboxId> mailboxIds = Helpers.getMailboxIds(messageResults); Message mimeMessage = Helpers.parse(firstMessageResult.getFullContent().getInputStream()); @@ -94,7 +93,8 @@ public class MessageFastViewFactory implements MessageViewFactory<MessageFastVie .bcc(Emailer.fromAddressList(mimeMessage.getBcc())) .replyTo(Emailer.fromAddressList(mimeMessage.getReplyTo())) .date(Helpers.getDateFromHeaderOrInternalDateOtherwise(mimeMessage, firstMessageResult)) - .preview(fastProjections.get(firstMessageResult.getMessageId()).getPreview()) + .preview(messageProjection.getPreview()) + .hasAttachment(messageProjection.hasAttachment()) .build(); } } diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullView.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullView.java index fc809c8..528eda2 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullView.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageFullView.java @@ -76,7 +76,8 @@ public class MessageFullView extends MessageFastView { public Builder attachments(List<Attachment> attachments) { this.attachments.addAll(attachments); - return this; + boolean hasAttachments = this.hasAttachment(this.attachments.build()); + return super.hasAttachment(hasAttachments); } public Builder attachedMessages(Map<BlobId, SubMessage> attachedMessages) { @@ -88,18 +89,23 @@ public class MessageFullView extends MessageFastView { ImmutableList<Attachment> attachments = this.attachments.build(); ImmutableMap<BlobId, SubMessage> attachedMessages = this.attachedMessages.build(); checkState(attachments, attachedMessages); - boolean hasAttachment = hasAttachment(attachments); return new MessageFullView(id, blobId, threadId, mailboxIds, Optional.ofNullable(inReplyToMessageId), - hasAttachment, headers, Optional.ofNullable(from), + hasAttachment.get(), headers, from, to.build(), cc.build(), bcc.build(), replyTo.build(), subject, date, size, PreviewDTO.from(preview), textBody, htmlBody, attachments, attachedMessages, keywords.orElse(Keywords.DEFAULT_VALUE)); } - public void checkState(ImmutableList<Attachment> attachments, ImmutableMap<BlobId, SubMessage> attachedMessages) { + private void checkState(ImmutableList<Attachment> attachments, ImmutableMap<BlobId, SubMessage> attachedMessages) { super.checkState(); Preconditions.checkState(areAttachedMessagesKeysInAttachments(attachments, attachedMessages), "'attachedMessages' keys must be in 'attachements'"); } + + private boolean hasAttachment(List<Attachment> attachments) { + return attachments.stream() + .anyMatch(attachment -> !attachment.isInlinedWithCid()); + } + } protected static boolean areAttachedMessagesKeysInAttachments(ImmutableList<Attachment> attachments, ImmutableMap<BlobId, SubMessage> attachedMessages) { @@ -113,11 +119,6 @@ public class MessageFullView extends MessageFastView { .anyMatch(blobId -> blobId.equals(key)); } - private static boolean hasAttachment(List<Attachment> attachments) { - return attachments.stream() - .anyMatch(attachment -> !attachment.isInlinedWithCid()); - } - private final boolean hasAttachment; private final Optional<String> textBody; private final Optional<String> htmlBody; @@ -146,7 +147,7 @@ public class MessageFullView extends MessageFastView { ImmutableList<Attachment> attachments, ImmutableMap<BlobId, SubMessage> attachedMessages, Keywords keywords) { - super(id, blobId, threadId, mailboxIds, inReplyToMessageId, headers, from, to, cc, bcc, replyTo, subject, date, size, preview, keywords); + super(id, blobId, threadId, mailboxIds, inReplyToMessageId, headers, from, to, cc, bcc, replyTo, subject, date, size, preview, keywords, hasAttachment); this.hasAttachment = hasAttachment; this.textBody = textBody; this.htmlBody = htmlBody; diff --git a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderView.java b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderView.java index 9ad4610..c7eb122 100644 --- a/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderView.java +++ b/server/protocols/jmap-draft/src/main/java/org/apache/james/jmap/draft/model/message/view/MessageHeaderView.java @@ -46,7 +46,7 @@ public class MessageHeaderView extends MessageMetadataView { public static class Builder<S extends MessageHeaderView.Builder<S>> extends MessageMetadataView.Builder<S> { protected String inReplyToMessageId; protected ImmutableMap<String, String> headers; - protected Emailer from; + protected Optional<Emailer> from; protected final ImmutableList.Builder<Emailer> to; protected final ImmutableList.Builder<Emailer> cc; protected final ImmutableList.Builder<Emailer> bcc; @@ -56,6 +56,7 @@ public class MessageHeaderView extends MessageMetadataView { protected Builder() { super(); + from = Optional.empty(); to = ImmutableList.builder(); cc = ImmutableList.builder(); bcc = ImmutableList.builder(); @@ -73,6 +74,11 @@ public class MessageHeaderView extends MessageMetadataView { } public S from(Emailer from) { + this.from = Optional.of(from); + return (S) this; + } + + public S from(Optional<Emailer> from) { this.from = from; return (S) this; } @@ -111,7 +117,7 @@ public class MessageHeaderView extends MessageMetadataView { checkState(); return new MessageHeaderView(id, blobId, threadId, mailboxIds, Optional.ofNullable(inReplyToMessageId), - headers, Optional.ofNullable(from), + headers, from, to.build(), cc.build(), bcc.build(), replyTo.build(), subject, date, size, keywords.orElse(Keywords.DEFAULT_VALUE)); } diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/json/ParsingWritingObjects.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/json/ParsingWritingObjects.java index dab006b..d52c27a 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/json/ParsingWritingObjects.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/json/ParsingWritingObjects.java @@ -91,6 +91,7 @@ public interface ParsingWritingObjects { .preview(Common.PREVIEW) .textBody(Common.TEXT_BODY) .htmlBody(Common.HTML_BODY) + .hasAttachment(false) .build(); SubMessage SUB_MESSAGE = SubMessage.builder() diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/EmailerTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/EmailerTest.java index f056d0c..94cceca 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/EmailerTest.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/EmailerTest.java @@ -154,9 +154,9 @@ public class EmailerTest { } @Test - public void firstFromMailboxListShouldReturnNullWhenNullMailboxList() { + public void firstFromMailboxListShouldReturnEmptyWhenNullMailboxList() { assertThat(Emailer.firstFromMailboxList(null)) - .isNull(); + .isEmpty(); } @Test @@ -164,7 +164,7 @@ public class EmailerTest { assertThat(Emailer.firstFromMailboxList(new MailboxList( new Mailbox("user1Inbox", "user1", "james.org"), new Mailbox("user2Inbox", "user2", "james.org")))) - .isEqualTo(Emailer.builder() + .contains(Emailer.builder() .name("user1Inbox") .email("[email protected]") .build()); diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/SetMessagesResponseTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/SetMessagesResponseTest.java index b668490..49cc9de 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/SetMessagesResponseTest.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/SetMessagesResponseTest.java @@ -71,6 +71,7 @@ public class SetMessagesResponseTest { .size(123) .date(currentDate) .preview(PREVIEW) + .hasAttachment(false) .build()); ImmutableList<MessageId> updated = ImmutableList.of(TestMessageId.of(2)); ImmutableList<MessageId> destroyed = ImmutableList.of(TestMessageId.of(3)); @@ -125,6 +126,7 @@ public class SetMessagesResponseTest { .size(0) .date(Instant.now()) .preview(PREVIEW) + .hasAttachment(false) .build()); } diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java index 044bcaf..a254fb9 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFastViewFactoryTest.java @@ -149,7 +149,7 @@ class MessageFastViewFactoryTest { } @Test - void fromMessageIdsShouldReturnAMessageWithPreviewInThePreviewStore() throws Exception { + void fromMessageIdsShouldReturnAMessageWithComputedFastProperties() throws Exception { MessageFastView actual = messageFastViewFactory.fromMessageIds(ImmutableList.of(previewComputedMessage1.getMessageId()), session).get(0); SoftAssertions.assertSoftly(softly -> { softly.assertThat(actual.getId()).isEqualTo(previewComputedMessage1.getMessageId()); @@ -168,12 +168,13 @@ class MessageFastViewFactoryTest { softly.assertThat(actual.getSubject()).isEqualTo("Full message"); softly.assertThat(actual.getDate()).isEqualTo("2016-06-07T14:23:37Z"); + softly.assertThat(actual.isHasAttachment()).isTrue(); softly.assertThat(actual.getPreview()).isEqualTo(PreviewDTO.of(PREVIEW_1_STRING)); }); } @Test - void fromMessageIdsShouldReturnAMessageWithPreviewComputedFromFullMessageWhenNotInThePreviewStore() throws Exception { + void fromMessageIdsShouldReturnAMessageWithPropertiesComputedFromFullMessageWhenNotPreComputed() throws Exception { MessageFastView actual = messageFastViewFactory.fromMessageIds(ImmutableList.of(missingPreviewComputedMessage1.getMessageId()), session).get(0); SoftAssertions.assertSoftly(softly -> { softly.assertThat(actual.getId()).isEqualTo(missingPreviewComputedMessage1.getMessageId()); @@ -192,6 +193,7 @@ class MessageFastViewFactoryTest { softly.assertThat(actual.getSubject()).isEqualTo("Full message"); softly.assertThat(actual.getDate()).isEqualTo("2016-06-07T14:23:37Z"); + softly.assertThat(actual.isHasAttachment()).isTrue(); softly.assertThat(actual.getPreview()).isEqualTo(PreviewDTO.of(DEFAULT_PREVIEW_STRING)); }); } diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java index c717a41..38363c6 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewFactoryTest.java @@ -245,6 +245,7 @@ class MessageFullViewFactoryTest { .textBody(Optional.of("")) .htmlBody(Optional.empty()) .keywords(keywords) + .hasAttachment(false) .build(); assertThat(testee).isEqualToComparingFieldByField(expected); } @@ -296,6 +297,7 @@ class MessageFullViewFactoryTest { .textBody(Optional.of("")) .htmlBody(Optional.empty()) .keywords(keywords) + .hasAttachment(false) .build(); assertThat(testee).isEqualToComparingFieldByField(expected); @@ -345,6 +347,7 @@ class MessageFullViewFactoryTest { .textBody(Optional.of("")) .htmlBody(Optional.empty()) .keywords(keywords) + .hasAttachment(false) .build(); assertThat(testee).isEqualToComparingFieldByField(expected); diff --git a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewTest.java b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewTest.java index 2cdf070..b8756f8 100644 --- a/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewTest.java +++ b/server/protocols/jmap-draft/src/test/java/org/apache/james/jmap/draft/model/message/view/MessageFullViewTest.java @@ -19,6 +19,7 @@ package org.apache.james.jmap.draft.model.message.view; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.time.Instant; @@ -151,10 +152,19 @@ class MessageFullViewTest { } @Test - void buildShouldThrowWhenPreviewIsNull() { - assertThatThrownBy(() -> MessageFullView.builder().id(TestMessageId.of(1)).blobId(BlobId.of("blobId")).threadId("threadId").fluentMailboxIds().headers(ImmutableMap.of()) - .subject("subject").size(123).date(Instant.now()).build()) - .isInstanceOf(IllegalStateException.class); + void buildShouldNotThrowWhenPreviewIsNotPresent() { + assertThatCode(() -> MessageFullView.builder() + .id(TestMessageId.of(1)) + .blobId(BlobId.of("blobId")) + .threadId("threadId") + .fluentMailboxIds() + .headers(ImmutableMap.of()) + .subject("subject") + .size(123) + .date(Instant.now()) + .hasAttachment(false) + .build()) + .doesNotThrowAnyException(); } @Test @@ -178,6 +188,7 @@ class MessageFullViewTest { .size(123) .date(currentDate) .preview(PREVIEW) + .hasAttachment(false) .build(); assertThat(tested).isEqualToComparingFieldByField(expected); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
