You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ma...@apache.org on 2016/07/08 17:01:06 UTC

[1/5] james-project git commit: JAMES-1794 Add a failing related test

Repository: james-project
Updated Branches:
  refs/heads/master 5c7471cd9 -> 0cad05775


JAMES-1794 Add a failing related test


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a989a4ef
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a989a4ef
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a989a4ef

Branch: refs/heads/master
Commit: a989a4ef5a52dd46535284fef9542f46cd8dd6ba
Parents: c5714ed
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Fri Jul 8 16:40:12 2016 +0200
Committer: Raphael Ouazana <ra...@linagora.com>
Committed: Fri Jul 8 16:47:53 2016 +0200

----------------------------------------------------------------------
 .../integration/SetMessagesMethodTest.java      | 67 ++++++++++++++++++++
 1 file changed, 67 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/a989a4ef/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
index e318778..306c070 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
@@ -1840,4 +1840,71 @@ public abstract class SetMessagesMethodTest {
             .body(firstAttachment + ".type", equalTo("text/html"))
             .body(firstAttachment + ".size", equalTo((int) attachment.getSize()));
     }
+
+    @Ignore("We should rework org.apache.james.jmap.model.message.MimePart to handle multipart/alternative and multipart/mixed")
+    @Test
+    public void attachmentsAndBodyShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesWithTextBodyAndHtmlAttachment() throws Exception {
+        jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "sent");
+
+        Attachment attachment = Attachment.builder()
+                .bytes(("<html>\n" +
+                        "  <body>attachment</body>\n" + // needed indentation, else restassured is adding some
+                        "</html>").getBytes(Charsets.UTF_8))
+                .type("text/html; charset=UTF-8")
+                .build();
+        uploadTextAttachment(attachment);
+
+        String messageCreationId = "creationId";
+        String fromAddress = username;
+        String outboxId = getOutboxId(accessToken);
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}]," +
+                "        \"subject\": \"Message with an attachment\"," +
+                "        \"textBody\": \"Test body, plain text version\"," +
+                "        \"mailboxIds\": [\"" + outboxId + "\"], " +
+                "        \"attachments\": [" +
+                "               {\"blobId\" : \"" + attachment.getAttachmentId().getId() + "\", " +
+                "               \"type\" : \"" + attachment.getType() + "\", " +
+                "               \"size\" : " + attachment.getSize() + ", " +
+                "               \"isInline\" : false }" +
+                "           ]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body(requestBody)
+        .when()
+            .post("/jmap");
+
+        calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken));
+
+        String firstMessage = ARGUMENTS + ".list[0]";
+        String firstAttachment = firstMessage + ".attachments[0]";
+        String presumedMessageId = "username@domain.tld|INBOX|1";
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + "\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .log().ifValidationFails()
+            .body(NAME, equalTo("messages"))
+            .body(ARGUMENTS + ".list", hasSize(1))
+            .body(firstMessage + ".textBody", equalTo("Test body, plain text version"))
+            .body(firstMessage + ".htmlBody", isEmptyOrNullString())
+            .body(firstMessage + ".attachments", hasSize(1))
+            .body(firstAttachment + ".blobId", equalTo(attachment.getAttachmentId().getId()))
+            .body(firstAttachment + ".type", equalTo("text/html"))
+            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()));
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[5/5] james-project git commit: Merge remote-tracking branch 'raphael/JAMES-1794'

Posted by ma...@apache.org.
Merge remote-tracking branch 'raphael/JAMES-1794'


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/0cad0577
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/0cad0577
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/0cad0577

Branch: refs/heads/master
Commit: 0cad057752810117d534ba83d96e88b25bc2a2fd
Parents: 5c7471c a989a4e
Author: Matthieu Baechler <ma...@linagora.com>
Authored: Fri Jul 8 17:52:30 2016 +0200
Committer: Matthieu Baechler <ma...@linagora.com>
Committed: Fri Jul 8 17:52:30 2016 +0200

----------------------------------------------------------------------
 .../store/mail/model/impl/MessageParser.java    |  26 ++--
 .../mail/model/impl/MessageParserTest.java      |  11 +-
 .../eml/oneHtmlAttachmentAndSomeTextInlined.eml |  39 +++++
 .../imap/processor/SetAnnotationProcessor.java  |   1 -
 .../integration/SetMessagesMethodTest.java      | 143 +++++++++++++++++++
 .../jmap/methods/MIMEMessageConverter.java      |  51 +++++--
 .../jmap/methods/MIMEMessageConverterTest.java  |  62 +++++++-
 7 files changed, 299 insertions(+), 34 deletions(-)
----------------------------------------------------------------------



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[4/5] james-project git commit: JAMES-1794 Fix for handling text attachments

Posted by ma...@apache.org.
JAMES-1794 Fix for handling text attachments


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/0be33d70
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/0be33d70
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/0be33d70

Branch: refs/heads/master
Commit: 0be33d70226374330c657adb94df9d484fe4a6b7
Parents: 682aada
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Fri Jul 8 14:36:02 2016 +0200
Committer: Raphael Ouazana <ra...@linagora.com>
Committed: Fri Jul 8 16:47:53 2016 +0200

----------------------------------------------------------------------
 .../store/mail/model/impl/MessageParser.java    | 26 +++----
 .../mail/model/impl/MessageParserTest.java      | 11 ++-
 .../eml/oneHtmlAttachmentAndSomeTextInlined.eml | 39 ++++++++++
 .../integration/SetMessagesMethodTest.java      | 76 ++++++++++++++++++++
 4 files changed, 134 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/0be33d70/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
index 9096efa..7e3f2fd 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java
@@ -45,7 +45,7 @@ import com.google.common.collect.ImmutableList;
 
 public class MessageParser {
 
-    private static final String TEXT_MEDIA_TYPE = "text";
+    private static final String MULTIPART_ALTERNATIVE = "multipart/alternative";
     private static final String CONTENT_TYPE = "Content-Type";
     private static final String CONTENT_ID = "Content-ID";
     private static final String CONTENT_DISPOSITION = "Content-Disposition";
@@ -73,7 +73,7 @@ public class MessageParser {
         ImmutableList.Builder<MessageAttachment> attachments = ImmutableList.builder();
         MessageWriter messageWriter = new DefaultMessageWriter();
         for (Entity entity : multipart.getBodyParts()) {
-            if (entity.isMultipart() && entity.getBody() instanceof Multipart) {
+            if (isMultipart(entity) && !isMainBody(entity)) {
                 attachments.addAll(listAttachments((Multipart) entity.getBody()));
             } else {
                 if (isAttachment(entity)) {
@@ -141,6 +141,14 @@ public class MessageParser {
         }).or(Optional.<String> absent());
     }
 
+    private boolean isMultipart(Entity entity) {
+        return entity.isMultipart() && entity.getBody() instanceof Multipart;
+    }
+
+    private boolean isMainBody(Entity entity) {
+        return entity.getMimeType().equalsIgnoreCase(MULTIPART_ALTERNATIVE);
+    }
+
     private boolean isInline(Optional<ContentDispositionField> contentDispositionField) {
         return contentDispositionField.transform(new Function<ContentDispositionField, Boolean>() {
             @Override
@@ -151,9 +159,6 @@ public class MessageParser {
     }
 
     private boolean isAttachment(Entity part) {
-        if (isTextPart(part)) {
-            return false;
-        }
         return Optional.fromNullable(part.getDispositionType())
                 .transform(new Function<String, Boolean>() {
 
@@ -164,17 +169,6 @@ public class MessageParser {
                 }).isPresent();
     }
 
-    private boolean isTextPart(Entity part) {
-        Optional<ContentTypeField> contentTypeField = getContentTypeField(part);
-        if (contentTypeField.isPresent()) {
-            String mediaType = contentTypeField.get().getMediaType();
-            if (mediaType != null && mediaType.equals(TEXT_MEDIA_TYPE)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     private byte[] getBytes(MessageWriter messageWriter, Body body) throws IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         messageWriter.writeBody(body, out);

http://git-wip-us.apache.org/repos/asf/james-project/blob/0be33d70/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
index 2e3a15e..054ebd0 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java
@@ -126,14 +126,14 @@ public class MessageParserTest {
     }
 
     @Test
-    public void getAttachmentsShouldNotRetrieveEmbeddedAttachmentsWhenSome() throws Exception {
+    public void getAttachmentsShouldRetrieveEmbeddedAttachmentsWhenSome() throws Exception {
         List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithInline.eml"));
 
         assertThat(attachments).hasSize(1);
     }
 
     @Test
-    public void getAttachmentsShouldNotRetrieveInlineAttachmentsWhenSome() throws Exception {
+    public void getAttachmentsShouldRetrieveInlineAttachmentsWhenSome() throws Exception {
         List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithAttachment.eml"));
 
         assertThat(attachments).hasSize(1);
@@ -154,4 +154,11 @@ public class MessageParserTest {
         assertThat(attachments).hasSize(1);
         assertThat(attachments.get(0).isInline()).isTrue();
     }
+
+    @Test
+    public void getAttachementsShouldRetrieveHtmlAttachementsWhenSome() throws Exception {
+        List<MessageAttachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneHtmlAttachmentAndSomeTextInlined.eml"));
+
+        assertThat(attachments).hasSize(1);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0be33d70/mailbox/store/src/test/resources/eml/oneHtmlAttachmentAndSomeTextInlined.eml
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/resources/eml/oneHtmlAttachmentAndSomeTextInlined.eml b/mailbox/store/src/test/resources/eml/oneHtmlAttachmentAndSomeTextInlined.eml
new file mode 100644
index 0000000..2fbb3e0
--- /dev/null
+++ b/mailbox/store/src/test/resources/eml/oneHtmlAttachmentAndSomeTextInlined.eml
@@ -0,0 +1,39 @@
+Mail content:
+To: "=?utf-8?B?UmFuaSBBc3NhZg==?=" <ra...@jri.obm.lng.org>
+Subject: =?utf-8?B?VHIuIDogUGhvdG9zICE=?=
+Importance: Normal
+MIME-Version: 1.0
+Content-Type: multipart/mixed;
+	boundary="----=_Part_0_1330682067197"
+
+------=_Part_0_1330682067197
+Content-Type: multipart/alternative;
+	boundary="----=_Part_2_1330682067197"
+
+------=_Part_2_1330682067197
+Content-Type: text/plain;
+	charset= utf-8
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+Content of part 1-1
+------=_Part_2_1330682067197
+Content-Type: text/html;
+	charset= utf-8
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+<b>Content of part 1-2</b>
+------=_Part_2_1330682067197--
+
+------=_Part_0_1330682067197
+Content-Type: text/html;
+	name="attachment.html"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment;
+	filename="attachment.html"
+<html>
+  <body>
+    Hello!
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/james-project/blob/0be33d70/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
index be3297b..e318778 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetMessagesMethodTest.java
@@ -47,6 +47,7 @@ import java.util.concurrent.TimeUnit;
 
 import javax.mail.Flags;
 
+import org.apache.commons.compress.utils.IOUtils;
 import org.apache.james.GuiceJamesServer;
 import org.apache.james.jmap.JmapAuthentication;
 import org.apache.james.jmap.api.access.AccessToken;
@@ -1682,6 +1683,14 @@ public abstract class SetMessagesMethodTest {
         .post("/upload");
     }
 
+    private void uploadTextAttachment(Attachment attachment) throws IOException {
+        with()
+            .header("Authorization", accessToken.serialize())
+            .contentType(attachment.getType())
+            .content(new String(IOUtils.toByteArray(attachment.getStream()), Charsets.UTF_8))
+        .post("/upload");
+    }
+
     @Test
     public void attachmentsShouldBeRetrievedWhenChainingSetMessagesAndGetMessages() throws Exception {
         jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "sent");
@@ -1764,4 +1773,71 @@ public abstract class SetMessagesMethodTest {
             return false;
         }
     }
+
+    @Test
+    public void attachmentsAndBodysShouldBeRetrievedWhenChainingSetMessagesAndGetMessagesWithMixedTextAndHtmlBodyAndHtmlAttachment() throws Exception {
+        jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "sent");
+
+        Attachment attachment = Attachment.builder()
+                .bytes(("<html>\n" +
+                        "  <body>attachment</body>\n" + // needed indentation, else restassured is adding some
+                        "</html>").getBytes(Charsets.UTF_8))
+                .type("text/html; charset=UTF-8")
+                .build();
+        uploadTextAttachment(attachment);
+
+        String messageCreationId = "creationId";
+        String fromAddress = username;
+        String outboxId = getOutboxId(accessToken);
+        String requestBody = "[" +
+                "  [" +
+                "    \"setMessages\","+
+                "    {" +
+                "      \"create\": { \"" + messageCreationId  + "\" : {" +
+                "        \"from\": { \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}," +
+                "        \"to\": [{ \"name\": \"Me\", \"email\": \"" + fromAddress + "\"}]," +
+                "        \"subject\": \"Message with an attachment\"," +
+                "        \"textBody\": \"Test body, plain text version\"," +
+                "        \"htmlBody\": \"Test <b>body</b>, HTML version\"," +
+                "        \"mailboxIds\": [\"" + outboxId + "\"], " +
+                "        \"attachments\": [" +
+                "               {\"blobId\" : \"" + attachment.getAttachmentId().getId() + "\", " +
+                "               \"type\" : \"" + attachment.getType() + "\", " +
+                "               \"size\" : " + attachment.getSize() + ", " +
+                "               \"isInline\" : false }" +
+                "           ]" +
+                "      }}" +
+                "    }," +
+                "    \"#0\"" +
+                "  ]" +
+                "]";
+
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body(requestBody)
+        .when()
+            .post("/jmap");
+
+        calmlyAwait.atMost(30, TimeUnit.SECONDS).until( () -> isAnyMessageFoundInInbox(accessToken));
+
+        String firstMessage = ARGUMENTS + ".list[0]";
+        String firstAttachment = firstMessage + ".attachments[0]";
+        String presumedMessageId = "username@domain.tld|INBOX|1";
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"" + presumedMessageId + "\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .log().ifValidationFails()
+            .body(NAME, equalTo("messages"))
+            .body(ARGUMENTS + ".list", hasSize(1))
+            .body(firstMessage + ".textBody", equalTo("Test body, plain text version"))
+            .body(firstMessage + ".htmlBody", equalTo("Test <b>body</b>, HTML version"))
+            .body(firstMessage + ".attachments", hasSize(1))
+            .body(firstAttachment + ".blobId", equalTo(attachment.getAttachmentId().getId()))
+            .body(firstAttachment + ".type", equalTo("text/html"))
+            .body(firstAttachment + ".size", equalTo((int) attachment.getSize()));
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[2/5] james-project git commit: JAMES-1794 Generate correct multipart/alternative when htmlBody and textBody

Posted by ma...@apache.org.
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 <ra...@linagora.com>
Authored: Fri Jul 8 16:28:29 2016 +0200
Committer: Raphael Ouazana <ra...@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-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[3/5] james-project git commit: Fix warning

Posted by ma...@apache.org.
Fix warning


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/682aada5
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/682aada5
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/682aada5

Branch: refs/heads/master
Commit: 682aada5afca423e5ab1ff6da84dcbd60e97d752
Parents: 662fa4a
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Fri Jul 8 11:40:57 2016 +0200
Committer: Raphael Ouazana <ra...@linagora.com>
Committed: Fri Jul 8 16:47:53 2016 +0200

----------------------------------------------------------------------
 .../org/apache/james/imap/processor/SetAnnotationProcessor.java     | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/682aada5/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
index feb5d68..0a5bdc6 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/SetAnnotationProcessor.java
@@ -35,7 +35,6 @@ import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.model.MailboxPath;
-import org.slf4j.Logger;
 
 import com.google.common.collect.ImmutableList;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org