[EMAIL-137] Fix MimeMessageParser to correctly parse MimeMessages created by calling HtmlEmail.getMimeMessage(). Thanks to Alex Kogan.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/email/trunk@1591128 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 4a13feb..16545dd 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -23,6 +23,10 @@
<body>
<release version="1.3.3" date="xxx">
+ <action dev="tn" type="fix" issue="EMAIL-137" date="2014-04-30" due-to="Alex Kogan">
+ MimeMessageParser did not correctly parse MimeMessage objects created by
+ calling HtmlEmail.buildMimeMessage() and HtmlEmail.getMimeMessage().
+ </action>
<action dev="ggregory" type="fix" issue="EMAIL-136" date="2014-02-01" due-to="Ville Skyttä">
Fix Javadoc 1.8 errors.
</action>
diff --git a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java
index cc57282..6aa3d2c 100644
--- a/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java
+++ b/src/main/java/org/apache/commons/mail/util/MimeMessageParser.java
@@ -16,18 +16,6 @@
*/
package org.apache.commons.mail.util;
-import javax.activation.DataHandler;
-import javax.activation.DataSource;
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Part;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimePart;
-import javax.mail.internet.MimeUtility;
-import javax.mail.util.ByteArrayDataSource;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
@@ -38,6 +26,21 @@
import java.util.Arrays;
import java.util.List;
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Part;
+import javax.mail.internet.ContentType;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimePart;
+import javax.mail.internet.MimeUtility;
+import javax.mail.internet.ParseException;
+import javax.mail.util.ByteArrayDataSource;
+
/**
* Parses a MimeMessage and stores the individual parts such a plain text,
* HTML text and attachments.
@@ -170,21 +173,21 @@
protected void parse(Multipart parent, MimePart part)
throws MessagingException, IOException
{
- if (part.isMimeType("text/plain") && (plainContent == null)
+ if (isMimeType(part, "text/plain") && (plainContent == null)
&& (!MimePart.ATTACHMENT.equalsIgnoreCase(part.getDisposition())))
{
plainContent = (String) part.getContent();
}
else
{
- if (part.isMimeType("text/html") && (htmlContent == null)
+ if (isMimeType(part, "text/html") && (htmlContent == null)
&& (!MimePart.ATTACHMENT.equalsIgnoreCase(part.getDisposition())))
{
htmlContent = (String) part.getContent();
}
else
{
- if (part.isMimeType("multipart/*"))
+ if (isMimeType(part, "multipart/*"))
{
this.isMultiPart = true;
Multipart mp = (Multipart) part.getContent();
@@ -206,6 +209,32 @@
}
/**
+ * Checks whether the MimePart contains an object of the given mime type.
+ *
+ * @param part the current MimePart
+ * @param mimeType the mime type to check
+ * @return {@code true} if the MimePart matches the given mime type, {@code false} otherwise
+ * @throws MessagingException parsing the MimeMessage failed
+ * @throws IOException parsing the MimeMessage failed
+ */
+ private boolean isMimeType(MimePart part, String mimeType)
+ throws MessagingException, IOException
+ {
+ // Do not use part.isMimeType(String) as it is broken for MimeBodyPart
+ // and does not really check the actual content type.
+
+ try
+ {
+ ContentType ct = new ContentType(part.getDataHandler().getContentType());
+ return ct.match(mimeType);
+ }
+ catch (ParseException ex)
+ {
+ return part.getContentType().equalsIgnoreCase(mimeType);
+ }
+ }
+
+ /**
* Parses the MimePart to create a DataSource.
*
* @param parent the parent multi-part
diff --git a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java
index a159adb..05dc6a1 100644
--- a/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java
+++ b/src/test/java/org/apache/commons/mail/util/MimeMessageParserTest.java
@@ -16,18 +16,23 @@
*/
package org.apache.commons.mail.util;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
import javax.activation.DataSource;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
+import org.apache.commons.mail.HtmlEmail;
import org.junit.Test;
-import java.io.File;
-import java.util.List;
-import java.util.Properties;
-
/**
* Testing the MimeMessageParser.
*/
@@ -92,7 +97,7 @@
mimeMessageParser.parse();
assertEquals("Test", mimeMessageParser.getSubject());
- assertNotNull(mimeMessageParser.getMimeMessage());
+ assertNotNull(mimeMessageParser.getMimeMessage());
assertTrue(mimeMessageParser.isMultipart());
assertTrue(mimeMessageParser.hasHtmlContent());
assertTrue(mimeMessageParser.hasPlainContent());
@@ -307,7 +312,7 @@
mimeMessageParser.parse();
assertEquals("test", mimeMessageParser.getSubject());
- assertNotNull(mimeMessageParser.getMimeMessage());
+ assertNotNull(mimeMessageParser.getMimeMessage());
assertTrue(mimeMessageParser.isMultipart());
assertFalse(mimeMessageParser.hasHtmlContent());
assertTrue(mimeMessageParser.hasPlainContent());
@@ -327,4 +332,108 @@
assertEquals("text/html", dataSource.getContentType());
}
+ @Test
+ public void testParseCreatedHtmlEmailWithNoContent() throws Exception
+ {
+ Session session = Session.getDefaultInstance(new Properties());
+
+ HtmlEmail email = new HtmlEmail();
+
+ email.setMailSession(session);
+
+ email.setFrom("test_from@apache.org");
+ email.setSubject("Test Subject");
+ email.addTo("test_to@apache.org");
+
+ email.buildMimeMessage();
+ MimeMessage msg = email.getMimeMessage();
+
+ MimeMessageParser mimeMessageParser = new MimeMessageParser(msg);
+ mimeMessageParser.parse();
+
+ assertEquals("Test Subject", mimeMessageParser.getSubject());
+ assertNotNull(mimeMessageParser.getMimeMessage());
+ assertTrue(mimeMessageParser.isMultipart());
+ assertFalse(mimeMessageParser.hasHtmlContent());
+ assertFalse(mimeMessageParser.hasPlainContent());
+ assertNull(mimeMessageParser.getPlainContent());
+ assertNull(mimeMessageParser.getHtmlContent());
+ assertTrue(mimeMessageParser.getTo().size() == 1);
+ assertTrue(mimeMessageParser.getCc().size() == 0);
+ assertTrue(mimeMessageParser.getBcc().size() == 0);
+ assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
+ assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
+ assertFalse(mimeMessageParser.hasAttachments());
+ }
+
+ @Test
+ public void testParseCreatedHtmlEmailWithTextContent() throws Exception
+ {
+ Session session = Session.getDefaultInstance(new Properties());
+
+ HtmlEmail email = new HtmlEmail();
+
+ email.setMailSession(session);
+
+ email.setFrom("test_from@apache.org");
+ email.setSubject("Test Subject");
+ email.addTo("test_to@apache.org");
+ email.setTextMsg("My test message");
+
+ email.buildMimeMessage();
+ MimeMessage msg = email.getMimeMessage();
+
+ MimeMessageParser mimeMessageParser = new MimeMessageParser(msg);
+ mimeMessageParser.parse();
+
+ assertEquals("Test Subject", mimeMessageParser.getSubject());
+ assertNotNull(mimeMessageParser.getMimeMessage());
+ assertTrue(mimeMessageParser.isMultipart());
+ assertFalse(mimeMessageParser.hasHtmlContent());
+ assertTrue(mimeMessageParser.hasPlainContent());
+ assertNotNull(mimeMessageParser.getPlainContent());
+ assertNull(mimeMessageParser.getHtmlContent());
+ assertTrue(mimeMessageParser.getTo().size() == 1);
+ assertTrue(mimeMessageParser.getCc().size() == 0);
+ assertTrue(mimeMessageParser.getBcc().size() == 0);
+ assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
+ assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
+ assertFalse(mimeMessageParser.hasAttachments());
+ }
+
+ @Test
+ public void testParseCreatedHtmlEmailWithMixedContent() throws Exception
+ {
+ Session session = Session.getDefaultInstance(new Properties());
+
+ HtmlEmail email = new HtmlEmail();
+
+ email.setMailSession(session);
+
+ email.setFrom("test_from@apache.org");
+ email.setSubject("Test Subject");
+ email.addTo("test_to@apache.org");
+ email.setTextMsg("My test message");
+ email.setHtmlMsg("<p>My HTML message</p>");
+
+ email.buildMimeMessage();
+ MimeMessage msg = email.getMimeMessage();
+
+ MimeMessageParser mimeMessageParser = new MimeMessageParser(msg);
+ mimeMessageParser.parse();
+
+ assertEquals("Test Subject", mimeMessageParser.getSubject());
+ assertNotNull(mimeMessageParser.getMimeMessage());
+ assertTrue(mimeMessageParser.isMultipart());
+ assertTrue(mimeMessageParser.hasHtmlContent());
+ assertTrue(mimeMessageParser.hasPlainContent());
+ assertNotNull(mimeMessageParser.getPlainContent());
+ assertNotNull(mimeMessageParser.getHtmlContent());
+ assertTrue(mimeMessageParser.getTo().size() == 1);
+ assertTrue(mimeMessageParser.getCc().size() == 0);
+ assertTrue(mimeMessageParser.getBcc().size() == 0);
+ assertEquals("test_from@apache.org", mimeMessageParser.getFrom());
+ assertEquals("test_from@apache.org", mimeMessageParser.getReplyTo());
+ assertFalse(mimeMessageParser.hasAttachments());
+ }
}