JAMES-1794 Generate correct multipart/alternative when htmlBody and textBody
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c5714ed6 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c5714ed6 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c5714ed6 Branch: refs/heads/master Commit: c5714ed6d839967097da075143e97de8e13fd647 Parents: 0be33d7 Author: Raphael Ouazana <raphael.ouaz...@linagora.com> Authored: Fri Jul 8 16:28:29 2016 +0200 Committer: Raphael Ouazana <raphael.ouaz...@linagora.com> Committed: Fri Jul 8 16:47:53 2016 +0200 ---------------------------------------------------------------------- .../jmap/methods/MIMEMessageConverter.java | 51 ++++++++++++---- .../jmap/methods/MIMEMessageConverterTest.java | 62 +++++++++++++++++++- 2 files changed, 98 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/c5714ed6/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MIMEMessageConverter.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MIMEMessageConverter.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MIMEMessageConverter.java index 2eb52e7..4be01ee 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MIMEMessageConverter.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/MIMEMessageConverter.java @@ -72,6 +72,7 @@ public class MIMEMessageConverter { private static final String PLAIN_TEXT_MEDIA_TYPE = MediaType.PLAIN_TEXT_UTF_8.withoutParameters().toString(); private static final String HTML_MEDIA_TYPE = MediaType.HTML_UTF_8.withoutParameters().toString(); private static final NameValuePair UTF_8_CHARSET = new NameValuePair("charset", Charsets.UTF_8.name()); + private static final String ALTERNATIVE_SUB_TYPE = "alternative"; private static final String MIXED_SUB_TYPE = "mixed"; private static final String FIELD_PARAMETERS_SEPARATOR = ";"; @@ -100,7 +101,7 @@ public class MIMEMessageConverter { MessageBuilder messageBuilder = MessageBuilder.create(); if (isMultipart(creationMessageEntry.getValue(), messageAttachments)) { - messageBuilder.setBody(createMultipartBody(creationMessageEntry.getValue(), messageAttachments)); + messageBuilder.setBody(createMultipart(creationMessageEntry.getValue(), messageAttachments)); } else { messageBuilder.setBody(createTextBody(creationMessageEntry.getValue())); } @@ -149,7 +150,11 @@ public class MIMEMessageConverter { private boolean isMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) { return (newMessage.getTextBody().isPresent() && newMessage.getHtmlBody().isPresent()) - || !messageAttachments.isEmpty(); + || hasAttachment(messageAttachments); + } + + private boolean hasAttachment(ImmutableList<MessageAttachment> messageAttachments) { + return !messageAttachments.isEmpty(); } private TextBody createTextBody(CreationMessage newMessage) { @@ -159,23 +164,45 @@ public class MIMEMessageConverter { return bodyFactory.textBody(body, Charsets.UTF_8); } - private Multipart createMultipartBody(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) { + private Multipart createMultipart(CreationMessage newMessage, ImmutableList<MessageAttachment> messageAttachments) { try { - MultipartBuilder builder = MultipartBuilder.create(MIXED_SUB_TYPE); - addText(builder, newMessage.getTextBody()); - addHtml(builder, newMessage.getHtmlBody()); - - Consumer<MessageAttachment> addAttachment = addAttachment(builder); - messageAttachments.stream() - .forEach(addAttachment); - - return builder.build(); + if (hasAttachment(messageAttachments)) { + MultipartBuilder builder = MultipartBuilder.create(MIXED_SUB_TYPE); + addBody(newMessage, builder); + + Consumer<MessageAttachment> addAttachment = addAttachment(builder); + messageAttachments.stream() + .forEach(addAttachment); + + return builder.build(); + } else { + return createMultipartAlternativeBody(newMessage); + } } catch (IOException e) { LOGGER.error("Error while creating textBody \n"+ newMessage.getTextBody().get() +"\n or htmlBody \n" + newMessage.getHtmlBody().get(), e); throw Throwables.propagate(e); } } + private void addBody(CreationMessage newMessage, MultipartBuilder builder) throws IOException { + if (newMessage.getHtmlBody().isPresent() && newMessage.getTextBody().isPresent()) { + Multipart body = createMultipartAlternativeBody(newMessage); + builder.addBodyPart(BodyPartBuilder.create().setBody(body).build()); + } + else { + addText(builder, newMessage.getTextBody()); + addHtml(builder, newMessage.getHtmlBody()); + } + } + + private Multipart createMultipartAlternativeBody(CreationMessage newMessage) throws IOException { + MultipartBuilder bodyBuilder = MultipartBuilder.create(ALTERNATIVE_SUB_TYPE); + addText(bodyBuilder, newMessage.getTextBody()); + addHtml(bodyBuilder, newMessage.getHtmlBody()); + Multipart body = bodyBuilder.build(); + return body; + } + private void addText(MultipartBuilder builder, Optional<String> textBody) throws IOException { if (textBody.isPresent()) { builder.addBodyPart(BodyPartBuilder.create() http://git-wip-us.apache.org/repos/asf/james-project/blob/c5714ed6/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/MIMEMessageConverterTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/MIMEMessageConverterTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/MIMEMessageConverterTest.java index 6f9b3d3..08e8625 100644 --- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/MIMEMessageConverterTest.java +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/MIMEMessageConverterTest.java @@ -200,6 +200,7 @@ public class MIMEMessageConverterTest { // Then assertThat(result.getBody()).isInstanceOf(Multipart.class); assertThat(result.isMultipart()).isTrue(); + assertThat(result.getMimeType()).isEqualTo("multipart/alternative"); Multipart typedResult = (Multipart)result.getBody(); assertThat(typedResult.getBodyParts()).hasSize(2); } @@ -218,7 +219,7 @@ public class MIMEMessageConverterTest { .build(); String expectedHeaders = "MIME-Version: 1.0\r\n" + - "Content-Type: multipart/mixed;\r\n" + + "Content-Type: multipart/alternative;\r\n" + " boundary=\"-=Part.1."; String expectedPart1 = "Content-Type: text/plain; charset=UTF-8\r\n" + "\r\n" + @@ -337,7 +338,7 @@ public class MIMEMessageConverterTest { String expectedCID = "<cid>"; String expectedMimeType = "image/png"; String text = "123456"; - TextBody expectedBody = new BasicBodyFactory().textBody(text, Charsets.UTF_8); + TextBody expectedBody = new BasicBodyFactory().textBody(text.getBytes(), Charsets.UTF_8); MessageAttachment attachment = MessageAttachment.builder() .attachment(org.apache.james.mailbox.store.mail.model.Attachment.builder() .attachmentId(AttachmentId.from("blodId")) @@ -358,7 +359,62 @@ public class MIMEMessageConverterTest { Multipart typedResult = (Multipart)result.getBody(); assertThat(typedResult.getBodyParts()).hasSize(2); Entity attachmentPart = typedResult.getBodyParts().get(1); - assertThat(result.getBody()).isEqualToComparingOnlyGivenFields(expectedBody); + assertThat(attachmentPart.getBody()).isEqualToComparingOnlyGivenFields(expectedBody, "content"); + assertThat(attachmentPart.getDispositionType()).isEqualTo("inline"); + assertThat(attachmentPart.getMimeType()).isEqualTo(expectedMimeType); + assertThat(attachmentPart.getHeader().getField("Content-ID").getBody()).isEqualTo(expectedCID); + } + + @Test + public void convertToMimeShouldAddAttachmentAndMultipartAlternativeWhenOneAttachementAndTextAndHtmlBody() { + // Given + MIMEMessageConverter sut = new MIMEMessageConverter(); + + CreationMessage testMessage = CreationMessage.builder() + .mailboxIds(ImmutableList.of("dead-bada55")) + .subject("subject") + .from(DraftEmailer.builder().name("sender").build()) + .textBody("Hello all!") + .htmlBody("Hello <b>all<b>!") + .build(); + TextBody expectedTextBody = new BasicBodyFactory().textBody("Hello all!".getBytes(), Charsets.UTF_8); + TextBody expectedHtmlBody = new BasicBodyFactory().textBody("Hello <b>all<b>!".getBytes(), Charsets.UTF_8); + + String expectedCID = "<cid>"; + String expectedMimeType = "image/png"; + String text = "123456"; + TextBody expectedAttachmentBody = new BasicBodyFactory().textBody(text.getBytes(), Charsets.UTF_8); + MessageAttachment attachment = MessageAttachment.builder() + .attachment(org.apache.james.mailbox.store.mail.model.Attachment.builder() + .attachmentId(AttachmentId.from("blodId")) + .bytes(text.getBytes()) + .type(expectedMimeType) + .build()) + .cid(expectedCID) + .isInline(true) + .build(); + + // When + Message result = sut.convertToMime(new ValueWithId.CreationMessageEntry( + CreationMessageId.of("user|mailbox|1"), testMessage), ImmutableList.of(attachment)); + + // Then + assertThat(result.getBody()).isInstanceOf(Multipart.class); + assertThat(result.isMultipart()).isTrue(); + Multipart typedResult = (Multipart)result.getBody(); + assertThat(typedResult.getBodyParts()).hasSize(2); + Entity mainBodyPart = typedResult.getBodyParts().get(0); + assertThat(mainBodyPart.getBody()).isInstanceOf(Multipart.class); + assertThat(mainBodyPart.isMultipart()).isTrue(); + assertThat(mainBodyPart.getMimeType()).isEqualTo("multipart/alternative"); + assertThat(((Multipart)mainBodyPart.getBody()).getBodyParts()).hasSize(2); + Entity textPart = ((Multipart)mainBodyPart.getBody()).getBodyParts().get(0); + Entity htmlPart = ((Multipart)mainBodyPart.getBody()).getBodyParts().get(1); + assertThat(textPart.getBody()).isEqualToComparingOnlyGivenFields(expectedTextBody, "content"); + assertThat(htmlPart.getBody()).isEqualToComparingOnlyGivenFields(expectedHtmlBody, "content"); + + Entity attachmentPart = typedResult.getBodyParts().get(1); + assertThat(attachmentPart.getBody()).isEqualToComparingOnlyGivenFields(expectedAttachmentBody, "content"); assertThat(attachmentPart.getDispositionType()).isEqualTo("inline"); assertThat(attachmentPart.getMimeType()).isEqualTo(expectedMimeType); assertThat(attachmentPart.getHeader().getField("Content-ID").getBody()).isEqualTo(expectedCID); --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org