You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by lh...@apache.org on 2009/08/27 11:02:23 UTC
svn commit: r808329 - in
/servicemix/components/bindings/servicemix-mail/trunk/src:
main/java/org/apache/servicemix/mail/marshaler/
main/java/org/apache/servicemix/mail/utils/
test/java/org/apache/servicemix/mail/
Author: lhein
Date: Thu Aug 27 09:02:23 2009
New Revision: 808329
URL: http://svn.apache.org/viewvc?rev=808329&view=rev
Log:
improved several things (see SMXCOMP-499)
Added:
servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailContentType.java (with props)
Modified:
servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/AbstractMailMarshaler.java
servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/DefaultMailMarshaler.java
servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailUtils.java
servicemix/components/bindings/servicemix-mail/trunk/src/test/java/org/apache/servicemix/mail/DefaultMailMarshalerTest.java
Modified: servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/AbstractMailMarshaler.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/AbstractMailMarshaler.java?rev=808329&r1=808328&r2=808329&view=diff
==============================================================================
--- servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/AbstractMailMarshaler.java (original)
+++ servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/AbstractMailMarshaler.java Thu Aug 27 09:02:23 2009
@@ -112,22 +112,6 @@
public static final String MSG_TAG_FROM = "org.apache.servicemix.mail.from";
/**
- * this tag is used in normalized messages to represent the text portion
- * of the mail received OR the text portion of the mail to be sent
- * if both html and text properties are set, then it will be a multipart
- * mail message containing both
- */
- public static final String MSG_TAG_TEXT = "org.apache.servicemix.mail.text";
-
- /**
- * this tag is used in normalized messages to represent the html portion
- * of the mail received OR the html portion of the mail to be sent
- * if both html and text properties are set, then it will be a multipart
- * mail message containing both
- */
- public static final String MSG_TAG_HTML = "org.apache.servicemix.mail.html";
-
- /**
* this tag is used in normalized messages to represent the subject of the
* mail received OR the subject of the mail to be sent
*/
@@ -146,11 +130,35 @@
public static final String MSG_TAG_SENTDATE = "org.apache.servicemix.mail.sentdate";
/**
- * this tag is used in normalized messages to represent the alternative
- * content of a multipart/related message type
+ * this tag is used in normalized messages to represent the content type of
+ * the mail received or the mail to be sent
*/
- public static final String MSG_TAG_ALTERNATIVE_CONTENT = "org.apache.servicemix.mail.alternativecontent";
-
+ public static final String MSG_TAG_MAIL_CONTENT_TYPE ="org.apache.servicemix.mail.type";
+
+ /**
+ * this tag is used in normalized messages to represent the charset used in
+ * the received mail or to be used in the mail to be sent
+ */
+ public static final String MSG_TAG_MAIL_CHARSET = "org.apache.servicemix.mail.charset";
+
+ /**
+ * this tag is used in normalized messages to flag that the attachments have to be
+ * treatened as inline attachments
+ */
+ public static final String MSG_TAG_MAIL_USE_INLINE_ATTACHMENTS = "org.apache.servicemix.mail.attachments.inline";
+
+ /**
+ * this tag is used in normalized messages to represent the plain text content used in
+ * the received mail or to be used in the mail to be sent
+ */
+ public static final String MSG_TAG_TEXT = "org.apache.servicemix.mail.text";
+
+ /**
+ * this tag is used in normalized messages to represent the html content used in
+ * the received mail or to be used in the mail to be sent
+ */
+ public static final String MSG_TAG_HTML = "org.apache.servicemix.mail.html";
+
/**
* the default sender address for outgoing mails
*/
@@ -166,6 +174,9 @@
*/
public static final String DUMMY_CONTENT = "no content";
+ /**
+ * a map of files to be cleaned up later on
+ */
private Map< String, List<File> > temporaryFilesMap = Collections.synchronizedMap(new HashMap<String, List<File> >());
/**
Modified: servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/DefaultMailMarshaler.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/DefaultMailMarshaler.java?rev=808329&r1=808328&r2=808329&view=diff
==============================================================================
--- servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/DefaultMailMarshaler.java (original)
+++ servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/marshaler/DefaultMailMarshaler.java Thu Aug 27 09:02:23 2009
@@ -19,13 +19,9 @@
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
-import java.util.Enumeration;
import java.util.Iterator;
import javax.activation.DataHandler;
@@ -35,20 +31,18 @@
import javax.jbi.messaging.NormalizedMessage;
import javax.mail.Address;
import javax.mail.BodyPart;
-import javax.mail.Header;
import javax.mail.Message;
-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.MimeMultipart;
-import javax.mail.util.ByteArrayDataSource;
+import javax.mail.internet.MimeUtility;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.servicemix.jbi.jaxp.SourceTransformer;
import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.apache.servicemix.mail.utils.MailContentType;
import org.apache.servicemix.mail.utils.MailUtils;
/**
@@ -69,11 +63,22 @@
@Override
public void convertMailToJBI(MessageExchange exchange, NormalizedMessage nmsg, MimeMessage mailMsg)
throws javax.mail.MessagingException {
- // copy headers
- copyHeaders(exchange, nmsg, mailMsg);
+ // extract the headers from the mail message
+ MailUtils.extractHeadersFromMail(exchange, nmsg, mailMsg);
- // now copy the mail body and the attachments
- copyBodyAndAttachments(exchange, nmsg, mailMsg);
+ // extract the body
+ try {
+ MailUtils.extractBodyFromMail(exchange, nmsg, mailMsg);
+ if (nmsg.getContent() == null) {
+ nmsg.setContent(new StringSource(AbstractMailMarshaler.DUMMY_CONTENT));
+ }
+ } catch (Exception e) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, AbstractMailMarshaler.DUMMY_CONTENT);
+ log.error("Unable to extract the mail content: " + MailUtils.extractBodyFromMail(mailMsg), e);
+ }
+
+ // extract the attachments
+ MailUtils.extractAttachmentsFromMail(exchange, nmsg, mailMsg);
}
/*
@@ -108,6 +113,225 @@
protected void fillMailBodyAndAttachments(MimeMessage mimeMessage, MessageExchange exchange,
NormalizedMessage nmsg) throws Exception {
+ String contentType = null;
+
+ if (nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE) != null) {
+ contentType = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE).toString();
+ }
+
+ boolean isText = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT) != null;
+ boolean isHtml = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML) != null || !isText || nmsg.getContent() != null;
+
+ if (contentType == null) {
+ // we need to guess what is best to use here
+ if (isHtml) {
+ // we got attachments or a html content...so it will be some multipart/* message
+ prepareMixedMail(MailContentType.MULTIPART, mimeMessage, exchange, nmsg);
+ } else {
+ // we will use a text/plain message
+ preparePlainTextMail(MailContentType.TEXT_PLAIN, mimeMessage, exchange, nmsg);
+ }
+ } else {
+ MailContentType mct = MailContentType.getEnumForValue(contentType);
+ switch (mct) {
+ case TEXT_PLAIN: preparePlainTextMail(mct, mimeMessage, exchange, nmsg);
+ break;
+ case TEXT_HTML:
+ case TEXT_XML:
+ case MULTIPART:
+ case MULTIPART_MIXED: prepareMixedMail(mct, mimeMessage, exchange, nmsg);
+ break;
+ case MULTIPART_ALTERNATIVE: prepareAlternativeMail(mct, mimeMessage, exchange, nmsg);
+ break;
+ default: if (isHtml && isText) {
+ prepareAlternativeMail(mct, mimeMessage, exchange, nmsg);
+ } else if (isText && nmsg.getAttachmentNames().size() == 0) {
+ preparePlainTextMail(mct, mimeMessage, exchange, nmsg);
+ } else {
+ prepareMixedMail(mct, mimeMessage, exchange, nmsg);
+ }
+ }
+ }
+ }
+
+ /**
+ * prepares a plain text mail message
+ *
+ * @param mct the mail content type
+ * @param mimeMessage the mail message
+ * @param exchange the message exchange
+ * @param nmsg the normalized message
+ * @throws Exception on errors
+ */
+ protected void preparePlainTextMail(MailContentType mct, MimeMessage mimeMessage, MessageExchange exchange,
+ NormalizedMessage nmsg) throws Exception {
+
+ Object content = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT);
+ Object charset = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CHARSET);
+
+ if (content != null) {
+ if (charset != null) {
+ mimeMessage.setText(content.toString(), charset.toString(), "plain");
+ } else {
+ mimeMessage.setText(content.toString(), MimeUtility.getDefaultJavaCharset(), "plain");
+ }
+ } else {
+ // no message content...throw exception
+ throw new MessagingException("Unable to get mail content for text/plain message from exchange.");
+ }
+ }
+
+ /**
+ * prepares a multipart mixed mail message
+ *
+ * @param mct the mail content type
+ * @param mimeMessage the mail message
+ * @param exchange the message exchange
+ * @param nmsg the normalized message
+ * @throws Exception on errors
+ */
+ protected void prepareMixedMail(MailContentType mct, MimeMessage mimeMessage, MessageExchange exchange,
+ NormalizedMessage nmsg) throws Exception {
+
+ boolean isText = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT) != null;
+ boolean isHtml = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML) != null;
+ boolean useInline = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_USE_INLINE_ATTACHMENTS) != null &&
+ ((Boolean)nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_USE_INLINE_ATTACHMENTS)).booleanValue();
+
+ Object content_text = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT);
+ Object content_html = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML);
+ Object charset = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CHARSET);
+
+ // Create a Multipart
+ MimeMultipart multipart = new MimeMultipart();
+ multipart.setSubType("mixed");
+
+ // fill the body with text if existing
+ if (isText && content_text != null) {
+ MimeBodyPart textBodyPart = new MimeBodyPart();
+ if (charset != null) {
+ textBodyPart.setText(content_text.toString(), charset.toString(), "plain");
+ } else {
+ textBodyPart.setText(content_text.toString(), MimeUtility.getDefaultJavaCharset(), "plain");
+ }
+ multipart.addBodyPart(textBodyPart);
+ }
+
+ // fill the body with html if existing
+ if (isHtml && content_html != null) {
+ MimeBodyPart htmlBodyPart = new MimeBodyPart();
+ htmlBodyPart.setContent(content_html.toString(), MailContentType.TEXT_HTML.getMimeType());
+ multipart.addBodyPart(htmlBodyPart);
+ }
+
+ // put attachments in place
+ appendAttachments(exchange, nmsg, multipart, useInline ? Part.INLINE : Part.ATTACHMENT);
+
+ // Put parts in message
+ mimeMessage.setContent(multipart);
+ }
+
+ /**
+ * prepares a multipart alternative mail message (both html and text)
+ *
+ * @param mct the mail content type
+ * @param mimeMessage the mail message
+ * @param exchange the message exchange
+ * @param nmsg the normalized message
+ * @throws Exception on errors
+ */
+ protected void prepareAlternativeMail(MailContentType mct, MimeMessage mimeMessage, MessageExchange exchange,
+ NormalizedMessage nmsg) throws Exception {
+
+ boolean isText = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT) != null;
+ boolean isHtml = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML) != null;
+ boolean useInline = true; // defaults to true
+
+ // only use attachments if it's definitive set so
+ if (nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_USE_INLINE_ATTACHMENTS) != null &&
+ ((Boolean)nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_USE_INLINE_ATTACHMENTS)).booleanValue() == false) {
+ useInline = false;
+ }
+
+ Object content_text = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT);
+ Object content_html = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML);
+ Object charset = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CHARSET);
+
+ // Create a Multipart
+ MimeMultipart multipart = new MimeMultipart();
+ multipart.setSubType("alternative");
+
+ // fill the body with text if existing
+ if (isText && content_text != null) {
+ MimeBodyPart textBodyPart = new MimeBodyPart();
+ if (charset != null) {
+ textBodyPart.setText(content_text.toString(), charset.toString(), "plain");
+ } else {
+ textBodyPart.setText(content_text.toString(), MimeUtility.getDefaultJavaCharset(), "plain");
+ }
+ multipart.addBodyPart(textBodyPart);
+ }
+
+ if (nmsg.getAttachmentNames().size() < 1) {
+ // no attachments
+ // fill the body with html if existing
+ if (isHtml && content_html != null) {
+ MimeBodyPart htmlBodyPart = new MimeBodyPart();
+ htmlBodyPart.setContent(content_html.toString(), MailContentType.TEXT_HTML.getMimeType());
+ multipart.addBodyPart(htmlBodyPart);
+ }
+ } else {
+ // found attachments
+ if (!useInline) {
+ // no inline attachments
+ BodyPart htmlpart = new MimeBodyPart();
+ MimeMultipart mmp = new MimeMultipart();
+ mmp.setSubType("mixed");
+
+ // fill the body with html if existing
+ if (isHtml && content_html != null) {
+ MimeBodyPart htmlBodyPart = new MimeBodyPart();
+ htmlBodyPart.setContent(content_html.toString(), MailContentType.TEXT_HTML.getMimeType());
+ mmp.addBodyPart(htmlBodyPart);
+ }
+ htmlpart.setContent(mmp);
+ multipart.addBodyPart(htmlpart);
+
+ // put attachments in place
+ appendAttachments(exchange, nmsg, mmp, useInline ? Part.INLINE : Part.ATTACHMENT);
+ } else {
+ // use inline attachments
+ MimeMultipart multipartRelated = new MimeMultipart("related");
+ BodyPart related = new MimeBodyPart();
+ related.setContent(multipartRelated);
+ multipart.addBodyPart(related);
+
+ // fill the body with html if existing
+ if (isHtml && content_html != null) {
+ MimeBodyPart htmlBodyPart = new MimeBodyPart();
+ htmlBodyPart.setContent(content_html.toString(), MailContentType.TEXT_HTML.getMimeType());
+ multipartRelated.addBodyPart(htmlBodyPart);
+ }
+ // put attachments in place
+ appendAttachments(exchange, nmsg, multipartRelated, useInline ? Part.INLINE : Part.ATTACHMENT);
+ }
+ }
+
+ // Put parts in message
+ mimeMessage.setContent(multipart);
+ }
+
+ /**
+ * appends all attachments to the mime message
+ *
+ * @param exchange the message exchange
+ * @param nmsg the normalized message
+ * @param multipart the mime multipart
+ * @param partType the part type (INLINE / ATTACHMENT)
+ * @throws Exception on any errors
+ */
+ protected void appendAttachments(MessageExchange exchange, NormalizedMessage nmsg,
+ MimeMultipart multipart, String partType) throws Exception {
// if there are attachments, then a multipart mime mail with
// attachments will be sent
if (nmsg.getAttachmentNames().size() > 0) {
@@ -115,14 +339,7 @@
if (itAttNames.hasNext()) {
// there is at least one attachment
-
- // Create a Multipart
- MimeMultipart multipart = new MimeMultipart();
-
- // fill the body with text, html or both
- fillMailBody(mimeMessage, exchange, nmsg, multipart);
-
- BodyPart messageBodyPart = null;
+ MimeBodyPart messageBodyPart = null;
// loop the existing attachments and put them to the mail
while (itAttNames.hasNext()) {
@@ -141,7 +358,7 @@
DataHandler dh = nmsg.getAttachment(oneAttachmentName);
File f = File.createTempFile("" + System.currentTimeMillis() + "-", dh.getDataSource().getName());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f));
- copyInputStream(dh.getInputStream(), bos);
+ dh.writeTo(bos);
bos.close();
log.debug("Saved temp file: " + f.getName() + " with length: " + f.length());
@@ -155,134 +372,18 @@
// Set the filename
messageBodyPart.setFileName(dh.getDataSource().getName());
// Set Disposition
- messageBodyPart.setDisposition(Part.ATTACHMENT);
+ messageBodyPart.setDisposition(partType);
+ // add a Content-ID header to the attachment
+ if (oneAttachmentName.toLowerCase().startsWith("cid:")) {
+ messageBodyPart.setContentID(oneAttachmentName.substring(4));
+ }
// Add part to multipart
multipart.addBodyPart(messageBodyPart);
}
- // Put parts in message
- mimeMessage.setContent(multipart);
}
- } else {
- // fill the body with text, html or both
- fillMailBody(mimeMessage, exchange, nmsg, null);
}
}
-
- /**
- * fills the body of the mail
- *
- * @param mimeMessage the mail message
- * @param exchange the jbi exchange
- * @param nmsg the normalized message
- * @param content the content of a multipart to use or null
- * @throws Exception on errors
- */
- protected void fillMailBody(MimeMessage mimeMessage, MessageExchange exchange, NormalizedMessage nmsg,
- MimeMultipart content) throws Exception {
- // check if we are going to send a plain text mail or html or both
- boolean isPlainTextMessage = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT) != null;
- boolean isHtmlMessage = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML) != null;
-
- if (isPlainTextMessage && !isHtmlMessage) {
- // a plain text mail will be sent
- if (content != null) {
- content.setSubType("mixed");
- MimeBodyPart textBodyPart = new MimeBodyPart();
- textBodyPart.setContent(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT).toString(),
- "text/plain");
- content.addBodyPart(textBodyPart);
- } else {
- mimeMessage.setText(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT).toString());
- }
- } else if (isHtmlMessage && !isPlainTextMessage) {
- // a html message will be sent
- if (content != null) {
- content.setSubType("mixed");
- MimeBodyPart htmlBodyPart = new MimeBodyPart();
- htmlBodyPart.setContent(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML).toString(),
- "text/html");
- content.addBodyPart(htmlBodyPart);
- } else {
- content = new MimeMultipart("mixed");
- MimeBodyPart htmlBodyPart = new MimeBodyPart();
- htmlBodyPart.setContent(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML).toString(),
- "text/html");
- content.addBodyPart(htmlBodyPart);
- // Put parts in message
- mimeMessage.setContent(content);
- }
- } else if (isHtmlMessage && isPlainTextMessage) {
- // both parts will be sent
- if (content != null) {
- content.setSubType("mixed");
- MimeBodyPart textBodyPart = new MimeBodyPart();
- MimeBodyPart htmlBodyPart = new MimeBodyPart();
- textBodyPart.setContent(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT).toString(),
- "text/plain");
- htmlBodyPart.setContent(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML).toString(),
- "text/html");
- content.addBodyPart(textBodyPart);
- content.addBodyPart(htmlBodyPart);
- } else {
- content = new MimeMultipart("mixed");
- MimeBodyPart textBodyPart = new MimeBodyPart();
- MimeBodyPart htmlBodyPart = new MimeBodyPart();
- textBodyPart.setContent(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT).toString(),
- "text/plain");
- htmlBodyPart.setContent(nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_HTML).toString(),
- "text/html");
- content.addBodyPart(textBodyPart);
- content.addBodyPart(htmlBodyPart);
- // Put parts in message
- mimeMessage.setContent(content);
- }
- } else {
- if (nmsg.getContent() != null) {
- // use the content of the message
- SourceTransformer st = new SourceTransformer();
- try {
- st.toDOMDocument(nmsg);
- // a html message will be sent
- if (content != null) {
- content.setSubType("mixed");
- MimeBodyPart htmlBodyPart = new MimeBodyPart();
- htmlBodyPart.setContent(st.contentToString(nmsg), "text/html");
- content.addBodyPart(htmlBodyPart);
- } else {
- content = new MimeMultipart("mixed");
- MimeBodyPart htmlBodyPart = new MimeBodyPart();
- htmlBodyPart.setContent(st.contentToString(nmsg), "text/html");
- content.addBodyPart(htmlBodyPart);
- // Put parts in message
- mimeMessage.setContent(content);
- }
- } catch (Exception ex) {
- // no xml document - plain text used now
- if (content != null) {
- content.setSubType("mixed");
- MimeBodyPart textBodyPart = new MimeBodyPart();
- textBodyPart.setContent(st.contentToString(nmsg), "text/plain");
- content.addBodyPart(textBodyPart);
- } else {
- // Put text in message
- mimeMessage.setText(st.contentToString(nmsg));
- }
- }
- } else {
- // a plain text mail will be sent
- if (content != null) {
- content.setSubType("mixed");
- MimeBodyPart textBodyPart = new MimeBodyPart();
- textBodyPart.setContent(AbstractMailMarshaler.DUMMY_CONTENT, "text/plain");
- content.addBodyPart(textBodyPart);
- } else {
- mimeMessage.setText(AbstractMailMarshaler.DUMMY_CONTENT);
- }
- }
- }
- }
-
/**
* fills the mail headers according to the normalized message headers
*
@@ -388,237 +489,4 @@
}
}
}
-
- /**
- * copy the headers of the mail message into the normalized message headers
- *
- * @param exchange the exchange to use
- * @param nmsg the message to use
- * @param mailMsg the mail message
- * @throws javax.mail.MessagingException on any errors
- */
- protected void copyHeaders(MessageExchange exchange, NormalizedMessage nmsg, MimeMessage mailMsg)
- throws javax.mail.MessagingException {
- // first convert the headers of the mail to properties of the message
- Enumeration headers = mailMsg.getAllHeaders();
- while (headers.hasMoreElements()) {
- Header header = (Header)headers.nextElement();
- if (nmsg.getProperty(header.getName()) != null) {
- // this is a multi line header - add it at the end
- nmsg.setProperty(header.getName(), nmsg.getProperty(header.getName() + ";"
- + header.getValue()));
- } else {
- // add it to the message properties
- nmsg.setProperty(header.getName(), header.getValue());
- }
- log.debug("Setting property: " + header.getName() + " = " + header.getValue());
- }
-
- // now fill some predefined properties to the message
- if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_BCC) != null) {
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_BCC, nmsg
- .getProperty(AbstractMailMarshaler.MAIL_TAG_BCC));
- }
- if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_CC) != null) {
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_CC, nmsg
- .getProperty(AbstractMailMarshaler.MAIL_TAG_CC));
- }
- if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_FROM) != null) {
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_FROM, nmsg
- .getProperty(AbstractMailMarshaler.MAIL_TAG_FROM));
- }
- if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_REPLYTO) != null) {
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_REPLYTO, nmsg
- .getProperty(AbstractMailMarshaler.MAIL_TAG_REPLYTO));
- }
- if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_SENTDATE) != null) {
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SENTDATE, nmsg
- .getProperty(AbstractMailMarshaler.MAIL_TAG_SENTDATE));
- }
- if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_SUBJECT) != null) {
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SUBJECT, nmsg
- .getProperty(AbstractMailMarshaler.MAIL_TAG_SUBJECT));
- }
- if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_TO) != null) {
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TO, nmsg
- .getProperty(AbstractMailMarshaler.MAIL_TAG_TO));
- }
- }
-
- /**
- * copies the mail body and attachments to the normalized message
- *
- * @param exchange the exchange to use
- * @param nmsg the message to use
- * @param mailMsg the mail to use
- * @throws javax.mail.MessagingException on any errors
- */
- protected void copyBodyAndAttachments(MessageExchange exchange, NormalizedMessage nmsg,
- MimeMessage mailMsg) throws javax.mail.MessagingException {
- // now convert the mail body and attachments and put it to the msg
- Object content;
- Multipart mp;
- String text = null;
- String html = null;
-
- try {
- content = mailMsg.getContent();
-
- if (content instanceof String) {
- // simple mail
- text = asString(content);
- } else if (content instanceof Multipart) {
- // mail with attachment
- mp = (Multipart)content;
- // first grab all attachments
- MailUtils.extractFromMultipart(mp, nmsg);
- log.debug("Attachments found: " + nmsg.getAttachmentNames().size());
-
- for (int i = 0; i < mp.getCount(); i++) {
- Part part = mp.getBodyPart(i);
- String disposition = part.getDisposition();
-
- if (disposition == null) {
- // Check if plain
- MimeBodyPart mbp = (MimeBodyPart)part;
- if (mbp.isMimeType("text/plain")) {
- // Handle plain text
- text = (String)mbp.getContent();
- } else if (mbp.isMimeType("text/html")) {
- // Handle html contents
- html = (String)mbp.getContent();
- } else {
- // Special non-attachment cases (image/gif, ...)
- if (mbp.getContent() instanceof MimeMultipart) {
- MimeMultipart subMP = (MimeMultipart)mbp.getContent();
- for (int j = 0; j < subMP.getCount(); j++) {
- MimeBodyPart subMBP = (MimeBodyPart)subMP.getBodyPart(j);
-
- if (subMBP.getContent() instanceof InputStream) {
- // parse the part
- parsePart(subMBP, nmsg);
- } else if (subMBP.isMimeType("text/plain")
- && (text == null || text.length() <= 0)) {
- // Handle plain text
- text = (String)subMBP.getContent();
- } else if (subMBP.isMimeType("text/html")
- && (html == null || html.length() <= 0)) {
- // Handle plain text
- html = (String)subMBP.getContent();
- } else {
- // add as property into the normalize message
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_ALTERNATIVE_CONTENT
- + j, subMBP.getContent());
- }
- }
- } else {
- // parse the part
- parsePart(mbp, nmsg);
- }
- }
- }
- }
- } else { // strange mail structure...log a warning
- log.warn("The content of the mail message is not supported by this component. ("
- + content.getClass().getName() + ")");
- }
- } catch (MessagingException e) {
- throw new javax.mail.MessagingException("Error while setting content on normalized message", e);
- } catch (IOException e) {
- throw new javax.mail.MessagingException("Error while fetching content", e);
- }
-
- String msgContent = null;
-
- if (text == null && html != null) {
- // html mail body
- msgContent = html;
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_HTML, html);
- } else if (text != null && html != null) {
- // both text and html
- msgContent = text;
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_HTML, html);
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, text);
- } else {
- // text mail body
- if (text == null) {
- // text and html content is null
- log.debug("No content found! \n" + nmsg.toString());
- }
-
- msgContent = text;
- nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, text);
- }
-
- try {
- // now set the converted content for the normalized message
- nmsg.setContent(new StringSource(msgContent != null ? msgContent : "No mail content found!"));
- } catch (javax.jbi.messaging.MessagingException e) {
- throw new javax.mail.MessagingException("Error while setting message content", e);
- }
- }
-
- /**
- * extracts and parses the attachments found in the mail bodies and puts
- * them to the normalized message attachments
- *
- * @param mbp the mime body part to parse
- * @param nmsg the normalized message to fill
- * @throws MessagingException
- * @throws javax.mail.MessagingException
- * @throws IOException
- */
- protected void parsePart(MimeBodyPart mbp, NormalizedMessage nmsg) throws MessagingException,
- javax.mail.MessagingException, IOException {
- Object subContent = mbp.getContent();
-
- log.debug("Parsing: " + subContent.getClass().getName());
-
- if (subContent instanceof InputStream) {
- String cid = mbp.getContentID();
- if (cid != null) {
- cid = cid.replaceAll("<", "").replaceAll(">", "").toLowerCase();
- }
-
- log.debug("Adding special attachment: "
- + (mbp.getFileName() != null ? mbp.getFileName() : cid));
-
- // read the stream into a byte array
- byte[] data = new byte[mbp.getSize()];
- InputStream stream = (InputStream)subContent;
- stream.read(data);
-
- // create a byte array data source for use in data handler
- ByteArrayDataSource bads = new ByteArrayDataSource(data, mbp.getContentType());
-
- // remember the name of the attachment
- bads.setName(mbp.getFileName() != null ? mbp.getFileName() : cid);
-
- // add the attachment to the message
- nmsg.addAttachment(bads.getName(), new DataHandler(bads));
- // add the cid2attachment mapping to properties
- if (cid != null) {
- nmsg.setProperty(cid, mbp.getFileName());
- }
- }
- }
-
- /**
- * Copy in stream to an out stream
- *
- * @param in
- * @param out
- * @throws IOException
- */
- public static void copyInputStream(InputStream in, OutputStream out) throws IOException {
- byte[] buffer = new byte[8192];
- int len = in.read(buffer);
- while (len >= 0) {
- out.write(buffer, 0, len);
- len = in.read(buffer);
- }
- in.close();
- out.close();
- }
-
}
Added: servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailContentType.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailContentType.java?rev=808329&view=auto
==============================================================================
--- servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailContentType.java (added)
+++ servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailContentType.java Thu Aug 27 09:02:23 2009
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.servicemix.mail.utils;
+
+/**
+ * @author lhein
+ */
+public enum MailContentType {
+ TEXT_PLAIN ("text/plain", "text/plain"),
+ TEXT_HTML ("text/html", "text/html"),
+ TEXT_XML ("text/xml", "text/xml"),
+ MULTIPART ("multipart/*", "multipart/*"),
+ MULTIPART_MIXED ("multipart/mixed", "multipart/mixed"),
+ MULTIPART_ALTERNATIVE ("multipart/alternative", "multipart/alternative"),
+ UNKNOWN ("unknown", "text/plain");
+
+ private String key;
+ private String mimeType;
+
+ /**
+ * creates a mail content type enum object
+ *
+ * @param key the key
+ * @param mimeType the mime type
+ */
+ private MailContentType(String key, String mimeType) {
+ this.key = key;
+ this.mimeType = mimeType;
+ }
+
+ /**
+ * @return Returns the key.
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * @return Returns the mimeType.
+ */
+ public String getMimeType() {
+ return this.mimeType;
+ }
+
+ /**
+ * returns the enum type for a value
+ *
+ * @param value the string value
+ * @return the enum matching this value or UNKNOWN if unrecognized
+ */
+ public static MailContentType getEnumForValue(String value) {
+ for (MailContentType ct : values()) {
+ if (ct.getMimeType().equalsIgnoreCase(value)) {
+ return ct;
+ }
+ }
+ return MailContentType.UNKNOWN;
+ }
+}
Propchange: servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailContentType.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailUtils.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailUtils.java?rev=808329&r1=808328&r2=808329&view=diff
==============================================================================
--- servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailUtils.java (original)
+++ servicemix/components/bindings/servicemix-mail/trunk/src/main/java/org/apache/servicemix/mail/utils/MailUtils.java Thu Aug 27 09:02:23 2009
@@ -17,17 +17,33 @@
package org.apache.servicemix.mail.utils;
import java.io.IOException;
+import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import java.util.Properties;
+import javax.activation.DataHandler;
+import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
+import javax.mail.Header;
+import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import javax.mail.internet.ParseException;
+import javax.mail.util.ByteArrayDataSource;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.jbi.jaxp.StringSource;
+import org.apache.servicemix.mail.marshaler.AbstractMailMarshaler;
import org.apache.servicemix.mail.security.CustomSSLSocketFactory;
/**
@@ -36,6 +52,11 @@
* @author lhein
*/
public final class MailUtils {
+ private static Log log = LogFactory.getLog(MailUtils.class);
+
+ public static final String KEY_BODY_TEXT = "text";
+ public static final String KEY_BODY_HTML = "html";
+
public static final String SSL_FACTORY = "org.apache.servicemix.mail.security.CustomSSLSocketFactory"; // javax.net.ssl.SSLSocketFactory
public static final int DEFAULT_PORT_SMTP = 25;
@@ -216,6 +237,108 @@
}
/**
+ * Extracts the body from the Mail message
+ */
+ public static Object extractBodyFromMail(Message message) {
+ try {
+ return message.getContent();
+ } catch (UnsupportedEncodingException e) {
+ return "Unable to decode the mail because charset is not supported: " + e.getMessage();
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to extract body due to: " + e.getMessage()
+ + ". Message: " + message, e);
+ }
+ }
+
+ /**
+ * copy the headers of the mail message into the normalized message headers
+ *
+ * @param exchange the exchange to use
+ * @param nmsg the message to use
+ * @param mailMsg the mail message
+ * @throws javax.mail.MessagingException on any errors
+ */
+ public static void extractHeadersFromMail(MessageExchange exchange, NormalizedMessage nmsg, MimeMessage mailMsg)
+ throws javax.mail.MessagingException {
+ // first convert the headers of the mail to properties of the message
+ Enumeration headers = mailMsg.getAllHeaders();
+ while (headers.hasMoreElements()) {
+ Header header = (Header)headers.nextElement();
+ if (nmsg.getProperty(header.getName()) != null) {
+ // this is a multi line header - add it at the end
+ try {
+ nmsg.setProperty(header.getName(), nmsg.getProperty(header.getName() + ";"
+ + MimeUtility.decodeText(header.getValue())));
+ } catch (UnsupportedEncodingException e) {
+ nmsg.setProperty(header.getName(), nmsg.getProperty(header.getName() + ";"
+ + header.getValue()));
+ }
+ } else {
+ // add it to the message properties
+ try {
+ nmsg.setProperty(header.getName(), MimeUtility.decodeText(header.getValue()));
+ } catch (UnsupportedEncodingException e) {
+ nmsg.setProperty(header.getName(), header.getValue());
+ }
+ }
+ try {
+ log.debug("Setting property: " + header.getName() + " = " + MimeUtility.decodeText(header.getValue()));
+ } catch (UnsupportedEncodingException e) {
+ log.debug("Setting property: " + header.getName() + " = " + header.getValue());
+ }
+ }
+
+ // grab the mime type
+ if (mailMsg.getContentType() != null) {
+ if (mailMsg.isMimeType(MailContentType.TEXT_PLAIN.getMimeType())) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.TEXT_PLAIN.getMimeType());
+ } else if (mailMsg.isMimeType(MailContentType.TEXT_HTML.getMimeType())) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.TEXT_HTML.getMimeType());
+ } else if (mailMsg.isMimeType(MailContentType.TEXT_XML.getMimeType())) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.TEXT_XML.getMimeType());
+ } else if (mailMsg.isMimeType(MailContentType.MULTIPART_ALTERNATIVE.getMimeType())) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.MULTIPART_ALTERNATIVE.getMimeType());
+ } else if (mailMsg.isMimeType(MailContentType.MULTIPART_MIXED.getMimeType())) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.MULTIPART_MIXED.getMimeType());
+ } else if (mailMsg.isMimeType(MailContentType.MULTIPART.getMimeType())) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.MULTIPART.getMimeType());
+ } else {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.UNKNOWN.getMimeType());
+ }
+ }
+
+ // now fill some predefined properties to the message
+ if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_BCC) != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_BCC, nmsg
+ .getProperty(AbstractMailMarshaler.MAIL_TAG_BCC));
+ }
+ if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_CC) != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_CC, nmsg
+ .getProperty(AbstractMailMarshaler.MAIL_TAG_CC));
+ }
+ if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_FROM) != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_FROM, nmsg
+ .getProperty(AbstractMailMarshaler.MAIL_TAG_FROM));
+ }
+ if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_REPLYTO) != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_REPLYTO, nmsg
+ .getProperty(AbstractMailMarshaler.MAIL_TAG_REPLYTO));
+ }
+ if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_SENTDATE) != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SENTDATE, nmsg
+ .getProperty(AbstractMailMarshaler.MAIL_TAG_SENTDATE));
+ }
+ if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_SUBJECT) != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SUBJECT, nmsg
+ .getProperty(AbstractMailMarshaler.MAIL_TAG_SUBJECT));
+ }
+ if (nmsg.getProperty(AbstractMailMarshaler.MAIL_TAG_TO) != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TO, nmsg
+ .getProperty(AbstractMailMarshaler.MAIL_TAG_TO));
+ }
+ }
+
+ /**
* extracts attachments from a multipart mail part
*
* @param mp the multipart
@@ -224,39 +347,262 @@
* @throws MessagingException on jbi messaging errors
* @throws IOException on io errors
*/
- public static void extractFromMultipart(Multipart mp, NormalizedMessage nmsg)
+ public static void extractAttachmentsFromMultipart(Multipart mp, NormalizedMessage nmsg)
throws javax.mail.MessagingException, MessagingException, IOException {
for (int i = 0; i < mp.getCount(); i++) {
- Part part = mp.getBodyPart(i);
- if (part.isMimeType("multipart/*")) {
- extractFromMultipart((Multipart)part.getContent(), nmsg);
+ MimeBodyPart part = (MimeBodyPart)mp.getBodyPart(i);
+ if (part.isMimeType(MailContentType.MULTIPART.getMimeType())) {
+ try {
+ Multipart mup = (Multipart)part.getContent();
+ extractAttachmentsFromMultipart(mup, nmsg);
+ } catch (UnsupportedEncodingException e) {
+ log.error("Unable to decode the mail because charset is not supported.", e);
+ }
} else {
+ if (i < 1) {
+ // skip first part always
+ continue;
+ }
String disposition = part.getDisposition();
- if (disposition != null) {
- if (disposition.equalsIgnoreCase(Part.ATTACHMENT)
- || disposition.equalsIgnoreCase(Part.INLINE)) {
- String name = part.getFileName();
- // only add named attachments
- if (name != null) {
- // Parts marked with a disposition of
- // Part.ATTACHMENT
- // are clearly attachments
- if (name != null) {
- try {
- name = MimeUtility.decodeText(name);
- } catch (UnsupportedEncodingException e) {
- // ignore it
- }
+ if (disposition != null &&
+ disposition.equalsIgnoreCase(Part.ATTACHMENT)) {
+
+ // treat as attachment
+ String name = part.getFileName();
+ // only add named attachments
+ if (name != null) {
+ // Parts marked with a disposition of
+ // Part.ATTACHMENT
+ // are clearly attachments
+ try {
+ name = MimeUtility.decodeText(name);
+ } catch (UnsupportedEncodingException e) {
+ // ignore it
+ }
+ nmsg.addAttachment(name, part.getDataHandler());
+ } else if (part.getDataHandler() != null) {
+ // also add unnamed if there is a data handler
+ nmsg.addAttachment(disposition, part.getDataHandler());
+ }
+ } else if (disposition != null && disposition.equalsIgnoreCase(Part.INLINE)) {
+ String contentID = part.getContentID();
+ if (contentID != null) {
+ contentID = contentID.replace('<', ' ');
+ contentID = contentID.replace('>', ' ');
+ contentID = contentID.trim();
+ } else {
+ contentID = part.getFileName();
+ }
+ contentID = "cid:" + contentID;
+ // treat as inline attachment
+ String name = part.getFileName();
+ // only add named attachments
+ if (name != null) {
+ // Parts marked with a disposition of
+ // Part.ATTACHMENT
+ // are clearly attachments
+ try {
+ name = MimeUtility.decodeText(name);
+ } catch (UnsupportedEncodingException e) {
+ // ignore it
+ }
+ nmsg.addAttachment(contentID, part.getDataHandler());
+ nmsg.setProperty(contentID, name);
+ } else if (part.getDataHandler() != null) {
+ // also add unnamed if there is a data handler
+ nmsg.addAttachment(contentID, part.getDataHandler());
+ nmsg.setProperty(contentID, contentID);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * returns the body of the mail
+ *
+ * @param mp
+ * @param nmsg
+ * @return
+ */
+ public static Map<String, String> extractBodyFromMultipart(Multipart mp, NormalizedMessage nmsg)
+ throws javax.mail.MessagingException, IOException {
+ Map<String, String> content = new HashMap<String, String>();
+
+ for (int i = 0; i < mp.getCount(); i++) {
+ Part part = mp.getBodyPart(i);
+ String disposition = part.getDisposition();
+
+ if (disposition == null) {
+ // Check if plain
+ if (part.isMimeType(MailContentType.MULTIPART.getMimeType())) {
+ try {
+ Multipart mup = (Multipart)part.getContent();
+ Map<String, String> res = extractBodyFromMultipart(mup, nmsg);
+ Iterator<String> keyIt = res.keySet().iterator();
+ while (keyIt.hasNext()) {
+ String key = keyIt.next();
+ if (content.containsKey(key)) {
+ content.put(key, content.get(key) + '\n' + res.get(key));
+ } else {
+ content.put(key, res.get(key));
}
- nmsg.addAttachment(name, part.getDataHandler());
- } else if (part.getDataHandler() != null) {
- // also add unnamed if there is a data handler
- nmsg.addAttachment(disposition, part.getDataHandler());
}
+ } catch (UnsupportedEncodingException e) {
+ log.error("Unable to decode the mail because charset is not supported.", e);
+ }
+ } else if (part.isMimeType(MailContentType.TEXT_PLAIN.getMimeType())) {
+ try {
+ content.put(KEY_BODY_TEXT, (String)part.getContent());
+ } catch (UnsupportedEncodingException e) {
+ content.put(KEY_BODY_TEXT, AbstractMailMarshaler.DUMMY_CONTENT);
+ log.error("Unable to decode the mail because charset is not supported.", e);
+ }
+ } else if (part.isMimeType(MailContentType.TEXT_HTML.getMimeType()) ||
+ part.isMimeType(MailContentType.TEXT_XML.getMimeType()) ) {
+ try {
+ content.put(KEY_BODY_HTML, (String)part.getContent());
+ } catch (UnsupportedEncodingException e) {
+ log.error("Unable to decode the mail because charset is not supported.", e);
}
+ } else {
+ // can't parse that...skipping
}
}
}
+
+ // do a final check if this is a multipart/alternative and if yes, then
+ // switch the content type according
+ if (content.size() == 2 && !nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE).toString().equalsIgnoreCase(MailContentType.MULTIPART_ALTERNATIVE.getMimeType())) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_MAIL_CONTENT_TYPE, MailContentType.MULTIPART_ALTERNATIVE.getKey());
+ }
+
+ return content;
+ }
+
+ /**
+ * extracts and parses the attachments found in the mail bodies and puts
+ * them to the normalized message attachments
+ *
+ * @param mbp the mime body part to parse
+ * @param nmsg the normalized message to fill
+ * @throws MessagingException
+ * @throws javax.mail.MessagingException
+ * @throws IOException
+ */
+ public static void parsePart(MimeBodyPart mbp, NormalizedMessage nmsg) throws MessagingException,
+ javax.mail.MessagingException, IOException {
+ Object subContent = mbp.getContent();
+
+ log.debug("Parsing: " + subContent.getClass().getName());
+
+ if (subContent instanceof InputStream) {
+ String cid = mbp.getContentID();
+ if (cid != null) {
+ cid = cid.replaceAll("<", "").replaceAll(">", "").toLowerCase();
+ }
+
+ log.debug("Adding special attachment: "
+ + (mbp.getFileName() != null ? mbp.getFileName() : cid));
+
+ // read the stream into a byte array
+ byte[] data = new byte[mbp.getSize()];
+ InputStream stream = (InputStream)subContent;
+ stream.read(data);
+
+ // create a byte array data source for use in data handler
+ ByteArrayDataSource bads = new ByteArrayDataSource(data, mbp.getContentType());
+
+ // remember the name of the attachment
+ bads.setName(mbp.getFileName() != null ? mbp.getFileName() : cid);
+
+ // add the attachment to the message
+ nmsg.addAttachment(bads.getName(), new DataHandler(bads));
+ // add the cid2attachment mapping to properties
+ if (cid != null) {
+ nmsg.setProperty(cid, mbp.getFileName());
+ }
+ }
+ }
+
+ /**
+ * extracts the body from the mail
+ *
+ * @param exchange the message exchange
+ * @param nmsg the normalized message
+ * @param mailMsg the mail message
+ */
+ public static void extractBodyFromMail(MessageExchange exchange, NormalizedMessage nmsg, MimeMessage mailMsg)
+ throws javax.mail.MessagingException, MessagingException {
+
+ Object content = MailUtils.extractBodyFromMail(mailMsg);
+ String text = null;
+ String html = null;
+
+ if (content == null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, AbstractMailMarshaler.DUMMY_CONTENT);
+ return;
+ }
+
+ if (mailMsg.isMimeType(MailContentType.TEXT_PLAIN.getMimeType())) {
+ // simple mail
+ text = (String)content;
+ } else if (mailMsg.isMimeType(MailContentType.TEXT_HTML.getMimeType()) ||
+ mailMsg.isMimeType(MailContentType.TEXT_XML.getMimeType())) {
+ html = (String)content;
+ } else if (mailMsg.isMimeType(MailContentType.MULTIPART.getMimeType())) {
+ // multipart - scan for body
+ Multipart mp = (Multipart)content;
+ try {
+ Map<String, String> parts = extractBodyFromMultipart(mp, nmsg);
+
+ // check for text
+ if (parts.containsKey(KEY_BODY_TEXT)) {
+ text = parts.get(KEY_BODY_TEXT);
+ }
+ // check for html
+ if (parts.containsKey(KEY_BODY_HTML)) {
+ html = parts.get(KEY_BODY_HTML);
+ }
+ } catch (Exception e) {
+ log.error("Error extracting body from message " + mailMsg, e);
+ }
+ }
+
+ if ((html == null || html.trim().length() < 1) &&
+ (text == null || text.trim().length() < 1)) {
+ text = AbstractMailMarshaler.DUMMY_CONTENT;
+ }
+
+ if (text != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, text);
+ }
+
+ if (html != null) {
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_HTML, html);
+ nmsg.setContent(new StringSource(html));
+ }
+ }
+
+ /**
+ * extracts the attachments from the mail
+ *
+ * @param exchange the message exchange
+ * @param nmsg the normalized message
+ * @param mailMsg the mail message
+ */
+ public static void extractAttachmentsFromMail(MessageExchange exchange, NormalizedMessage nmsg, MimeMessage mailMsg) {
+ Object content = MailUtils.extractBodyFromMail(mailMsg);
+ if (content != null && content instanceof Multipart) {
+ // mail with attachment
+ Multipart mp = (Multipart)content;
+ try {
+ MailUtils.extractAttachmentsFromMultipart(mp, nmsg);
+ log.debug("Attachments found: " + nmsg.getAttachmentNames().size());
+ } catch (Exception e) {
+ log.error("Error extracting attachments from message " + mailMsg, e);
+ }
+ }
}
}
Modified: servicemix/components/bindings/servicemix-mail/trunk/src/test/java/org/apache/servicemix/mail/DefaultMailMarshalerTest.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-mail/trunk/src/test/java/org/apache/servicemix/mail/DefaultMailMarshalerTest.java?rev=808329&r1=808328&r2=808329&view=diff
==============================================================================
--- servicemix/components/bindings/servicemix-mail/trunk/src/test/java/org/apache/servicemix/mail/DefaultMailMarshalerTest.java (original)
+++ servicemix/components/bindings/servicemix-mail/trunk/src/test/java/org/apache/servicemix/mail/DefaultMailMarshalerTest.java Thu Aug 27 09:02:23 2009
@@ -26,11 +26,13 @@
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
+import javax.mail.Part;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
import junit.framework.TestCase;
@@ -39,6 +41,7 @@
import org.apache.servicemix.jbi.messaging.InOnlyImpl;
import org.apache.servicemix.mail.marshaler.AbstractMailMarshaler;
import org.apache.servicemix.mail.marshaler.DefaultMailMarshaler;
+import org.apache.servicemix.mail.utils.MailContentType;
/**
* this is a collection of test which validate the marshaler conversion results
@@ -120,7 +123,7 @@
assertEquals("The TEXT content is wrong!", TEXT, nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT));
assertNotNull("The message content was null!", nmsg.getContent());
- String result = st.contentToString(nmsg);
+ String result = nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT).toString();
assertEquals("The content is wrong!", TEXT, result);
}
@@ -168,7 +171,9 @@
assertNotNull("The message content was null!", nmsg.getContent());
String result = st.contentToString(nmsg);
- assertEquals("The content is wrong!", TEXT, result);
+ if (HTML.indexOf(result) == -1) {
+ fail("The HTML content is wrong! Expected: " + HTML + " Result: " + result);
+ }
}
/**
@@ -191,9 +196,6 @@
assertEquals("The TEXT content is wrong!", TEXT, nmsg.getProperty(AbstractMailMarshaler.MSG_TAG_TEXT));
assertNotNull("The message content was null!", nmsg.getContent());
- String result = st.contentToString(nmsg);
- assertEquals("The content is wrong!", TEXT, result);
-
if (nmsg.getAttachmentNames().size() != 1) {
fail("The attachments are invalid. Expected: 1 Found: " + nmsg.getAttachmentNames().size());
}
@@ -266,8 +268,15 @@
assertNotNull("The message content was null!", nmsg.getContent());
String result = st.contentToString(nmsg);
- assertEquals("The content is wrong!", TEXT, result);
+ if (HTML.indexOf(result) == -1) {
+ fail("The HTML content is wrong! Expected: " + HTML + " Result: " + result);
+ }
+ Iterator i = nmsg.getAttachmentNames().iterator();
+ while (i.hasNext()) {
+ System.err.println("ATT: " + i.next().toString());
+ }
+
if (nmsg.getAttachmentNames().size() != 1) {
fail("The attachments are invalid. Expected: 1 Found: " + nmsg.getAttachmentNames().size());
}
@@ -298,8 +307,6 @@
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SUBJECT, SUBJECT);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, TEXT);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_REPLYTO, FROM);
- // prepare content
- nmsg.setContent(new StringSource(TEXT));
// convert
marshaler.convertJBIToMail(mail, exchange, nmsg, null, null);
@@ -417,8 +424,7 @@
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_BCC, BCC);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SUBJECT, SUBJECT);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_REPLYTO, FROM);
- // prepare content
- nmsg.setContent(new StringSource(TEXT));
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, TEXT);
// convert
marshaler.convertJBIToMail(mail, exchange, nmsg, null, null);
@@ -472,8 +478,6 @@
.toString());
assertEquals("The SUBJECT is invalid!", SUBJECT, mail
.getHeader(AbstractMailMarshaler.MAIL_TAG_SUBJECT)[0].toString());
- assertEquals("The HTML is invalid!", HTML, ((MimeMultipart)mail.getContent()).getBodyPart(0)
- .getContent());
assertEquals("The REPLY-TO is invalid!", FROM,
mail.getHeader(AbstractMailMarshaler.MAIL_TAG_REPLYTO)[0].toString());
}
@@ -494,8 +498,6 @@
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SUBJECT, SUBJECT);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, TEXT);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_REPLYTO, FROM);
- // prepare content
- nmsg.setContent(new StringSource(TEXT));
// prepare attachment
nmsg.addAttachment(FILE, new DataHandler(new FileDataSource(new File(PATH, FILE))));
@@ -513,19 +515,8 @@
.toString());
assertEquals("The SUBJECT is invalid!", SUBJECT, mail
.getHeader(AbstractMailMarshaler.MAIL_TAG_SUBJECT)[0].toString());
- assertEquals("The TEXT is invalid!", TEXT, ((MimeMultipart)mail.getContent()).getBodyPart(0)
- .getContent());
assertEquals("The REPLY-TO is invalid!", FROM,
mail.getHeader(AbstractMailMarshaler.MAIL_TAG_REPLYTO)[0].toString());
-
- // check attachment
- assertNotNull("No attachment part found!", ((MimeMultipart)mail.getContent()).getBodyPart(1));
- BodyPart att = ((MimeMultipart)mail.getContent()).getBodyPart(1);
- assertEquals("Attachment file name is invalid!", FILE, att.getFileName());
- if (att.getDataHandler().getInputStream().available() != new File(PATH, FILE).length()) {
- fail("Attachment size wrong. Expected: " + new File(PATH, FILE).length() + " Found: "
- + att.getDataHandler().getInputStream().available());
- }
}
/**
@@ -595,8 +586,7 @@
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, TEXT);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_HTML, HTML);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_REPLYTO, FROM);
- // prepare content
- nmsg.setContent(new StringSource(TEXT));
+ nmsg.setContent(new StringSource(HTML));
// prepare attachment
nmsg.addAttachment(FILE, new DataHandler(new FileDataSource(new File(PATH, FILE))));
@@ -647,8 +637,7 @@
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_BCC, BCC);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_SUBJECT, SUBJECT);
nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_REPLYTO, FROM);
- // prepare content
- nmsg.setContent(new StringSource(TEXT));
+ nmsg.setProperty(AbstractMailMarshaler.MSG_TAG_TEXT, TEXT);
// prepare attachment
nmsg.addAttachment(FILE, new DataHandler(new FileDataSource(new File(PATH, FILE))));
@@ -666,19 +655,8 @@
.toString());
assertEquals("The SUBJECT is invalid!", SUBJECT, mail
.getHeader(AbstractMailMarshaler.MAIL_TAG_SUBJECT)[0].toString());
- assertEquals("The TEXT is invalid!", TEXT, ((MimeMultipart)mail.getContent()).getBodyPart(0)
- .getContent());
assertEquals("The REPLY-TO is invalid!", FROM,
mail.getHeader(AbstractMailMarshaler.MAIL_TAG_REPLYTO)[0].toString());
-
- // check attachment
- assertNotNull("No attachment part found!", ((MimeMultipart)mail.getContent()).getBodyPart(1));
- BodyPart att = ((MimeMultipart)mail.getContent()).getBodyPart(1);
- assertEquals("Attachment file name is invalid!", FILE, att.getFileName());
- if (att.getDataHandler().getInputStream().available() != new File(PATH, FILE).length()) {
- fail("Attachment size wrong. Expected: " + new File(PATH, FILE).length() + " Found: "
- + att.getDataHandler().getInputStream().available());
- }
}
/**
@@ -716,19 +694,8 @@
.toString());
assertEquals("The SUBJECT is invalid!", SUBJECT, mail
.getHeader(AbstractMailMarshaler.MAIL_TAG_SUBJECT)[0].toString());
- assertEquals("The HTML is invalid!", HTML, ((MimeMultipart)mail.getContent()).getBodyPart(0)
- .getContent());
assertEquals("The REPLY-TO is invalid!", FROM,
mail.getHeader(AbstractMailMarshaler.MAIL_TAG_REPLYTO)[0].toString());
-
- // check attachment
- assertNotNull("No attachment part found!", ((MimeMultipart)mail.getContent()).getBodyPart(1));
- BodyPart att = ((MimeMultipart)mail.getContent()).getBodyPart(1);
- assertEquals("Attachment file name is invalid!", FILE, att.getFileName());
- if (att.getDataHandler().getInputStream().available() != new File(PATH, FILE).length()) {
- fail("Attachment size wrong. Expected: " + new File(PATH, FILE).length() + " Found: "
- + att.getDataHandler().getInputStream().available());
- }
}
/**
@@ -867,35 +834,30 @@
message.addRecipient(Message.RecipientType.BCC, new InternetAddress(BCC));
if (withAttachments) {
- // Create a Multipart
MimeMultipart multipart = new MimeMultipart();
+ multipart.setSubType("mixed");
- // Create your new message part
- BodyPart messageBodyPart = new MimeBodyPart();
-
- // Set the content of the body part
- messageBodyPart.setContent(TEXT, "text/plain");
-
- // Add body part to multipart
- multipart.addBodyPart(messageBodyPart);
-
- messageBodyPart = new MimeBodyPart();
-
- // Set the content of the body part
- messageBodyPart.setContent(HTML, "text/html");
-
- // Add body part to multipart
- multipart.addBodyPart(messageBodyPart);
-
- // Create part for the image
- messageBodyPart = new MimeBodyPart();
+ MimeBodyPart textBodyPart = new MimeBodyPart();
+ textBodyPart.setText(TEXT, MimeUtility.getDefaultJavaCharset(), "plain");
+ multipart.addBodyPart(textBodyPart);
+
+ MimeBodyPart htmlBodyPart = new MimeBodyPart();
+ htmlBodyPart.setContent(HTML, MailContentType.TEXT_HTML.getMimeType());
+ multipart.addBodyPart(htmlBodyPart);
// Fetch the image and associate to part
FileDataSource fds = new FileDataSource(new File(PATH, FILE));
+
+ MimeBodyPart messageBodyPart = null;
+ // Create another body part
+ messageBodyPart = new MimeBodyPart();
+ // Set the data handler to the attachment
messageBodyPart.setDataHandler(new DataHandler(fds));
+ // Set the filename
messageBodyPart.setFileName(fds.getName());
-
- // Add part to multi-part
+ // Set Disposition
+ messageBodyPart.setDisposition(Part.ATTACHMENT);
+ // Add part to multipart
multipart.addBodyPart(messageBodyPart);
// Associate multi-part with message