Bug 454033: MailUtility: use MimeUtility.encodeText when setting
FileName for FileDataSource
Change-Id: I67f49bf8076a3f071cd0c7b651b1c535e7e83ad0
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=454033
Reviewed-on: https://git.eclipse.org/r/37571
Tested-by: Hudson CI
Reviewed-by: Judith Gull <jgu@bsiag.com>
Reviewed-on: https://git.eclipse.org/r/37633
(cherry picked from commit 515b810a83b82c70043f963ee0c711602a0bc03a)
Conflicts:
org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/MailUtilityTest.java
Change-Id: I4b11cfbdf5b664ba355611430fa1b74fa1d490ac
Reviewed-on: https://git.eclipse.org/r/41450
Tested-by: Hudson CI
Reviewed-by: Adrian Sacchi <adrian.sacchi@bsiag.com>
diff --git a/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/MailUtilityTest.java b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/MailUtilityTest.java
index 5efb245..21353db 100644
--- a/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/MailUtilityTest.java
+++ b/org.eclipse.scout.commons.test/src/org/eclipse/scout/commons/MailUtilityTest.java
@@ -18,14 +18,26 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import javax.activation.DataSource;
+import javax.mail.BodyPart;
import javax.mail.MessagingException;
+import javax.mail.Part;
+import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
import javax.mail.util.ByteArrayDataSource;
import org.eclipse.scout.commons.exception.ProcessingException;
+import org.junit.Assert;
import org.junit.Test;
/**
@@ -36,7 +48,7 @@
/**
* Message without sender can be created
- *
+ *
* @throws ProcessingException
* ,MessagingException
*/
@@ -89,4 +101,163 @@
MimeMessage message = MailUtility.createMimeMessage("test", null, new DataSource[]{ds});
message.writeTo(new ByteArrayOutputStream());
}
+
+ @Test
+ public void testGetParts() throws ProcessingException, IOException, MessagingException {
+ final byte[] sampleData = new byte[]{0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+ DataSource[] attachments = new DataSource[]{
+ MailUtility.createDataSource(new ByteArrayInputStream(sampleData), "sample1.dat", null),
+ MailUtility.createDataSource(new ByteArrayInputStream(sampleData), "sample2.dat", null),
+ MailUtility.createDataSource(new ByteArrayInputStream(sampleData), "sample3.dat", null)
+ };
+
+ final String plainText = "plain text";
+ final String htmlText = "<html><body><p>plain text</p></body></html>";
+ MimeMessage message = MailUtility.createMimeMessage(plainText, htmlText, attachments);
+
+ verifyPlainTextAndHtml(message, plainText, htmlText);
+
+ // validate that the method call does not throw an exception
+ MailUtility.collectMailParts(null, null, null, null);
+ MailUtility.collectMailParts(message, null, null, null);
+
+ List<Part> bodyCollector = new ArrayList<Part>();
+ List<Part> attachmentCollector = new ArrayList<Part>();
+ List<Part> inlineAttachmentCollector = new ArrayList<Part>();
+ MailUtility.collectMailParts(message, bodyCollector, attachmentCollector, inlineAttachmentCollector);
+ Assert.assertEquals("body parts size is wrong", 2, bodyCollector.size());
+ Assert.assertEquals("attachments parts size is wrong", 3, attachmentCollector.size());
+ Assert.assertEquals("inline attachments parts size is wrong", 0, inlineAttachmentCollector.size());
+ }
+
+ private void verifyPlainTextAndHtml(MimeMessage message, String plainText, String htmlText) throws ProcessingException, IOException, MessagingException {
+ Assert.assertEquals("wrong plain text", plainText, MailUtility.getPlainText(message));
+
+ Part[] bodyParts = MailUtility.getBodyParts(message);
+ Assert.assertEquals("body parts size is wrong", 2, bodyParts.length);
+
+ Part[] attachmentParts = MailUtility.getAttachmentParts(message);
+ Assert.assertEquals("attachments parts size is wrong", 3, attachmentParts.length);
+
+ Part plainTextPart = MailUtility.getPlainTextPart(bodyParts);
+ Assert.assertNotNull("no plain text part found", plainTextPart);
+ Assert.assertTrue("plain text part content is not string", plainTextPart.getContent() instanceof String);
+ Assert.assertEquals("wrong plain text", plainText, (String) plainTextPart.getContent());
+
+ Part htmlPart = MailUtility.getHtmlPart(bodyParts);
+ Assert.assertNotNull("no html part found", htmlPart);
+ Assert.assertTrue("html part content is not string", htmlPart.getContent() instanceof String);
+ Assert.assertEquals("wrong html text", htmlText, (String) htmlPart.getContent());
+ }
+
+ @Test
+ public void testInlineAttachmentCollector() throws MessagingException, ProcessingException {
+ CharsetSafeMimeMessage message = new CharsetSafeMimeMessage();
+ MimeMultipart multiPart = new MimeMultipart();
+ message.setContent(multiPart);
+
+ MimeBodyPart bodyPart = new MimeBodyPart();
+ bodyPart.setText("plain text", "UTF-8");
+ bodyPart.addHeader(MailUtility.CONTENT_TYPE_ID, MailUtility.CONTENT_TYPE_TEXT_PLAIN);
+ multiPart.addBodyPart(bodyPart);
+
+ BodyPart inlineAttachmentPart = new MimeBodyPart();
+ inlineAttachmentPart.setContent("base-64-encoded-image-content", "image/gif");
+ inlineAttachmentPart.addHeader(MailUtility.CONTENT_TYPE_ID, "image/gif; name=\"graycol.gif\"");
+ inlineAttachmentPart.addHeader("Content-ID", "<5__=4EBBF65EEFABF58A8f9e8a9@example.org>");
+ inlineAttachmentPart.addHeader("Content-Disposition", Part.INLINE);
+ multiPart.addBodyPart(inlineAttachmentPart);
+
+ List<Part> bodyCollector = new ArrayList<Part>();
+ List<Part> attachmentCollector = new ArrayList<Part>();
+ List<Part> inlineAttachmentCollector = new ArrayList<Part>();
+ MailUtility.collectMailParts(message, bodyCollector, attachmentCollector, inlineAttachmentCollector);
+ Assert.assertEquals("body parts size is wrong", 1, bodyCollector.size());
+ Assert.assertEquals("attachments parts size is wrong", 0, attachmentCollector.size());
+ Assert.assertEquals("inline attachments parts size is wrong", 1, inlineAttachmentCollector.size());
+ }
+
+ @Test
+ public void testAddAttachmentsToMimeMessage() throws ProcessingException, IOException, MessagingException {
+ // create html mime message without attachments
+ MimeMessage message = MailUtility.createMimeMessage("plain text", "<html><body><p>plain text</p></html>", null);
+ verifyAttachments(message /* no attachments*/);
+
+ // add 3 attachments to mime message
+ final byte[] sampleData = new byte[]{0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+ List<File> attachments = new ArrayList<File>();
+ attachments.add(IOUtility.createTempFile("sample1.dat", sampleData));
+ attachments.add(IOUtility.createTempFile("sample2.dat", sampleData));
+ attachments.add(IOUtility.createTempFile("sample3_öüä.dat", sampleData));
+ MailUtility.addAttachmentsToMimeMessage(message, attachments);
+
+ // verify added attachments in java instance
+ verifyAttachments(message, "sample1.dat", "sample2.dat", MimeUtility.encodeText("sample3_öüä.dat"));
+
+ // store and recreate mime message (byte[])
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ message.writeTo(bos);
+ message = new MimeMessage(null, new ByteArrayInputStream(bos.toByteArray()));
+
+ // verify new instance
+ verifyAttachments(message, "sample1.dat", "sample2.dat", MimeUtility.encodeText("sample3_öüä.dat"));
+ }
+
+ @Test
+ public void testCreateMimeMessageFromWordArchiveDirectory() throws ProcessingException, IOException, MessagingException {
+ // create temp files for 3 attachments
+ final byte[] sampleData = new byte[]{0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+ List<File> attachments = new ArrayList<File>();
+ attachments.add(IOUtility.createTempFile("sample1.dat", sampleData));
+ attachments.add(IOUtility.createTempFile("sample2.dat", sampleData));
+ attachments.add(IOUtility.createTempFile("sample3_öüä.dat", sampleData));
+
+ // create files for word archive with plain text and html files (no additional attachments in archive)
+ final String plainText = "plain text";
+ final String htmlText = "<html><body><p>plain text</p></body></html>";
+ final String archiveSimpleName = "myarchive";
+ File archiveDir = IOUtility.createTempDirectory("word_archive");
+ File txtFile = new File(archiveDir, archiveSimpleName + ".txt");
+ File htmlFile = new File(archiveDir, archiveSimpleName + ".html");
+ IOUtility.writeContent(new FileOutputStream(txtFile), plainText.getBytes());
+ IOUtility.writeContent(new FileOutputStream(htmlFile), htmlText.getBytes());
+
+ // create word archive file (zip)
+ File archiveFile = IOUtility.createTempFile(archiveSimpleName + ".zip", null);
+ FileUtility.compressArchive(archiveDir, archiveFile);
+
+ // remove temp files
+ txtFile.delete();
+ htmlFile.delete();
+ archiveDir.delete();
+
+ // create mime message from word archive and verify message
+ MimeMessage message = MailUtility.createMimeMessageFromWordArchive(archiveFile, attachments.toArray(new File[attachments.size()]));
+ verifyPlainTextAndHtml(message, plainText, htmlText);
+ verifyAttachments(message, "sample1.dat", "sample2.dat", MimeUtility.encodeText("sample3_öüä.dat"));
+ }
+
+ /**
+ * Verifies that the mime message has the correct number of attachments with the correct filenames.
+ *
+ * @param message
+ * Message to check attachments
+ * @param attachmentFilenames
+ * Filenames of attachments (use {@link MimeUtility#encodeText(String)} in case the filename as non-supported
+ * chars)
+ * @throws ProcessingException
+ * @throws MessagingException
+ */
+ protected void verifyAttachments(MimeMessage message, String... attachmentFilenames) throws ProcessingException, MessagingException {
+ Part[] attachmentParts = MailUtility.getAttachmentParts(message);
+ Assert.assertEquals("attachments parts size is wrong", attachmentFilenames.length, attachmentParts.length);
+ Set<String> attachmentFilenamesSet = new HashSet<String>();
+ for (Part part : attachmentParts) {
+ attachmentFilenamesSet.add(part.getFileName());
+ }
+ Assert.assertEquals("attachments filenames size is wrong", attachmentFilenames.length, attachmentFilenamesSet.size());
+ for (String attachmentFilename : attachmentFilenames) {
+ Assert.assertTrue("attachment filename " + attachmentFilename + " is missing", attachmentFilenamesSet.contains(attachmentFilename));
+ }
+ }
}
diff --git a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/MailUtility.java b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/MailUtility.java
index 66c1eba..f522434 100644
--- a/org.eclipse.scout.commons/src/org/eclipse/scout/commons/MailUtility.java
+++ b/org.eclipse.scout.commons/src/org/eclipse/scout/commons/MailUtility.java
@@ -43,6 +43,7 @@
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
+import javax.mail.internet.MimeUtility;
import javax.mail.util.ByteArrayDataSource;
import org.eclipse.scout.commons.exception.ProcessingException;
@@ -555,7 +556,7 @@
FileDataSource fds = new FileDataSource(attachment);
DataHandler handler = new DataHandler(fds);
part.setDataHandler(handler);
- part.setFileName(attachment.getName());
+ part.setFileName(MimeUtility.encodeText(attachment.getName()));
multiPart.addBodyPart(part);
}
}
@@ -589,6 +590,9 @@
catch (MessagingException e) {
throw new ProcessingException("Error occured while creating MIME-message", e);
}
+ catch (UnsupportedEncodingException e) {
+ throw new ProcessingException("Error occured while creating MIME-message", e);
+ }
}
private String removeWordTags(String htmlMessage) {
@@ -780,7 +784,7 @@
MimeBodyPart bodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(attachment);
bodyPart.setDataHandler(new DataHandler(source));
- bodyPart.setFileName(attachment.getName());
+ bodyPart.setFileName(MimeUtility.encodeText(attachment.getName()));
multiPart.addBodyPart(bodyPart);
}
msg.saveChanges();