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