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 ad...@apache.org on 2016/07/01 15:30:37 UTC

[3/4] james-project git commit: JAMES-1777 Parse attachment file name

JAMES-1777 Parse attachment file name


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

Branch: refs/heads/master
Commit: 8b7cdb2acac03a85525e8cb5208579b4ab2f7e92
Parents: 9d0b3b4
Author: Antoine Duprat <ad...@linagora.com>
Authored: Thu Jun 23 22:17:09 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Jul 1 16:32:41 2016 +0200

----------------------------------------------------------------------
 .../store/mail/model/impl/MessageParser.java    | 56 ++++++++++++--------
 .../AbstractMailboxManagerAttachmentTest.java   | 14 +++++
 .../mail/model/impl/MessageParserTest.java      | 19 +++++++
 .../resources/eml/oneAttachmentWithoutName.eml  | 38 +++++++++++++
 4 files changed, 105 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/8b7cdb2a/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 be342d8..56099ff 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
@@ -31,21 +31,19 @@ import org.apache.james.mime4j.dom.Entity;
 import org.apache.james.mime4j.dom.MessageWriter;
 import org.apache.james.mime4j.dom.Multipart;
 import org.apache.james.mime4j.dom.field.ContentDispositionField;
+import org.apache.james.mime4j.dom.field.ContentTypeField;
 import org.apache.james.mime4j.message.DefaultMessageBuilder;
 import org.apache.james.mime4j.message.DefaultMessageWriter;
 import org.apache.james.mime4j.stream.Field;
 
+import com.google.common.base.Function;
 import com.google.common.base.Optional;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
 
 public class MessageParser {
 
     private static final String CONTENT_TYPE = "Content-Type";
     private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
-    private static final String HEADER_SEPARATOR = ";";
 
     public List<Attachment> retrieveAttachments(InputStream fullContent) throws MimeException, IOException {
         Body body = new DefaultMessageBuilder()
@@ -67,38 +65,52 @@ public class MessageParser {
         MessageWriter messageWriter = new DefaultMessageWriter();
         for (Entity entity : multipart.getBodyParts()) {
             if (isAttachment(entity)) {
-                Optional<String> contentType = contentType(entity.getHeader().getField(CONTENT_TYPE));
-                attachments.add(createAttachment(messageWriter, entity.getBody(), contentType.or(DEFAULT_CONTENT_TYPE)));
+                Optional<ContentTypeField> contentTypeField = contentTypeField(entity.getHeader().getField(CONTENT_TYPE));
+                Optional<String> contentType = contentType(contentTypeField);
+                Optional<String> name = name(contentTypeField);
+                
+                attachments.add(Attachment.builder()
+                        .bytes(getBytes(messageWriter, entity.getBody()))
+                        .type(contentType.or(DEFAULT_CONTENT_TYPE))
+                        .name(name)
+                        .build());
             }
         }
         return attachments.build();
     }
 
-    private Optional<String> contentType(Field contentType) {
-        if (contentType == null) {
-            return Optional.absent();
-        }
-        String body = contentType.getBody();
-        if (Strings.isNullOrEmpty(body)) {
+    private Optional<String> contentType(Optional<ContentTypeField> contentTypeField) {
+        return contentTypeField.transform(new Function<ContentTypeField, Optional<String>>() {
+            @Override
+            public Optional<String> apply(ContentTypeField field) {
+                return Optional.fromNullable(field.getMimeType());
+            }
+        }).or(Optional.<String> absent());
+    }
+
+    private Optional<String> name(Optional<ContentTypeField> contentTypeField) {
+        return contentTypeField.transform(new Function<ContentTypeField, Optional<String>>() {
+            @Override
+            public Optional<String> apply(ContentTypeField field) {
+                return Optional.fromNullable(field.getParameter("name"));
+            }
+        }).or(Optional.<String> absent());
+    }
+
+    private Optional<ContentTypeField> contentTypeField(Field contentType) {
+        if (contentType == null || !(contentType instanceof ContentTypeField)) {
             return Optional.absent();
         }
-        if (body.contains(HEADER_SEPARATOR)) {
-            return Optional.of(Iterables.get(Splitter.on(HEADER_SEPARATOR).split(body), 0));
-        }
-        return Optional.of(body);
+        return Optional.of((ContentTypeField) contentType);
     }
 
     private boolean isAttachment(Entity part) {
         return ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT.equalsIgnoreCase(part.getDispositionType());
     }
 
-    private Attachment createAttachment(MessageWriter messageWriter, Body body, String contentType) throws IOException {
+    private byte[] getBytes(MessageWriter messageWriter, Body body) throws IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         messageWriter.writeBody(body, out);
-        byte[] bytes = out.toByteArray();
-        return Attachment.builder()
-                .bytes(bytes)
-                .type(contentType)
-                .build();
+        return out.toByteArray();
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b7cdb2a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
index bde8984..5f14fda 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/AbstractMailboxManagerAttachmentTest.java
@@ -48,6 +48,8 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
+import com.google.common.base.Optional;
+
 public abstract class AbstractMailboxManagerAttachmentTest {
     private static final String USERNAME = "user@domain.tld";
     private static final Date SUN_SEP_9TH_2001 = new Date(1000000000000L);
@@ -108,6 +110,18 @@ public abstract class AbstractMailboxManagerAttachmentTest {
     }
 
     @Test
+    public void appendMessageShouldStoreAttachmentNameWhenMailWithOneAttachment() throws Exception {
+        InputStream mailInputStream = ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeInlined.eml");
+        inboxMessageManager.appendMessage(mailInputStream, SUN_SEP_9TH_2001, mailboxSession, true, new Flags(Flags.Flag.RECENT));
+
+        Optional<String> expectedName = Optional.of("exploits_of_a_mom.png");
+
+        Iterator<MailboxMessage> messages = messageMapper.findInMailbox(inbox, MessageRange.all(), FetchType.Full, 1);
+        List<AttachmentId> attachmentsIds = messages.next().getAttachmentsIds();
+        assertThat(attachmentMapper.getAttachment(attachmentsIds.get(0)).getName()).isEqualTo(expectedName);
+    }
+
+    @Test
     public void appendMessageShouldStoreARetrievableAttachmentWhenMailWithOneAttachment() throws Exception {
         InputStream mailInputStream = ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeInlined.eml");
         inboxMessageManager.appendMessage(mailInputStream, SUN_SEP_9TH_2001, mailboxSession, true, new Flags(Flags.Flag.RECENT));

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b7cdb2a/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 ab8b88b..ca6847d 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
@@ -27,6 +27,8 @@ import org.apache.james.mailbox.store.mail.model.Attachment;
 import org.junit.Before;
 import org.junit.Test;
 
+import com.google.common.base.Optional;
+
 public class MessageParserTest {
 
     private MessageParser testee;
@@ -51,6 +53,23 @@ public class MessageParserTest {
     }
 
     @Test
+    public void getAttachmentsShouldRetrieveAttachmentNameWhenOne() throws Exception {
+        List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeInlined.eml"));
+
+        assertThat(attachments).hasSize(1);
+        Optional<String> expectedName = Optional.of("exploits_of_a_mom.png");
+        assertThat(attachments.get(0).getName()).isEqualTo(expectedName);
+    }
+
+    @Test
+    public void getAttachmentsShouldRetrieveEmptyNameWhenNone() throws Exception {
+        List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithoutName.eml"));
+
+        assertThat(attachments).hasSize(1);
+        assertThat(attachments.get(0).getName()).isEqualTo(Optional.absent());
+    }
+
+    @Test
     public void getAttachmentsShouldNotFailWhenContentTypeIsNotHere() throws Exception {
         List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentWithoutContentType.eml"));
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/8b7cdb2a/mailbox/store/src/test/resources/eml/oneAttachmentWithoutName.eml
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/resources/eml/oneAttachmentWithoutName.eml b/mailbox/store/src/test/resources/eml/oneAttachmentWithoutName.eml
new file mode 100644
index 0000000..b5a9aa2
--- /dev/null
+++ b/mailbox/store/src/test/resources/eml/oneAttachmentWithoutName.eml
@@ -0,0 +1,38 @@
+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: application/octet-stream;
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+	filename="gimp.png"
+
+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
+
+------=_Part_0_1330682067197--
+


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