You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2006/04/25 09:52:14 UTC

svn commit: r396805 - in /incubator/servicemix/trunk/servicemix-components/src: main/java/org/apache/servicemix/components/email/ test/java/org/apache/servicemix/components/email/ test/resources/org/apache/servicemix/components/email/

Author: gnodet
Date: Tue Apr 25 00:52:10 2006
New Revision: 396805

URL: http://svn.apache.org/viewcvs?rev=396805&view=rev
Log:
SM-406: Email component should support attachment (multipart MIME email)
Patch provided by Jerome Camilleri, thanks!

Modified:
    incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MailMarshalerSupport.java
    incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MimeMailMarshaler.java
    incubator/servicemix/trunk/servicemix-components/src/test/java/org/apache/servicemix/components/email/MimeMailTest.java
    incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/mimeMail.xml
    incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/request.xml

Modified: incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MailMarshalerSupport.java
URL: http://svn.apache.org/viewcvs/incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MailMarshalerSupport.java?rev=396805&r1=396804&r2=396805&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MailMarshalerSupport.java (original)
+++ incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MailMarshalerSupport.java Tue Apr 25 00:52:10 2006
@@ -51,6 +51,7 @@
     private Expression subject = new PropertyExpression("org.apache.servicemix.email.subject", "Message from ServiceMix");
     private Expression replyTo = new PropertyExpression("org.apache.servicemix.email.replyTo");
     private Expression sentDate = new PropertyExpression("org.apache.servicemix.email.sentDate");
+    private Expression attachments = new PropertyExpression("org.apache.servicemix.email.attachments");
 
     public Expression getTo() {
         return to;
@@ -91,7 +92,7 @@
     public void setText(Expression text) {
         this.text = text;
     }
-    
+
     public Expression getHtml() {
         return html;
     }
@@ -132,6 +133,13 @@
         this.dateFormat = dateFormat;
     }
 
+    public Expression getAttachments() {
+        return attachments;
+    }
+
+    public void setAttachments(Expression attachments) {
+        this.attachments = attachments;
+    }
     // Implementation methods
     //-------------------------------------------------------------------------
     protected Date getSentDate(MessageExchange exchange, NormalizedMessage normalizedMessage) throws MessagingException {

Modified: incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MimeMailMarshaler.java
URL: http://svn.apache.org/viewcvs/incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MimeMailMarshaler.java?rev=396805&r1=396804&r2=396805&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MimeMailMarshaler.java (original)
+++ incubator/servicemix/trunk/servicemix-components/src/main/java/org/apache/servicemix/components/email/MimeMailMarshaler.java Tue Apr 25 00:52:10 2006
@@ -15,14 +15,25 @@
  */
 package org.apache.servicemix.components.email;
 
+import java.io.File;
 import java.io.IOException;
 import java.util.Date;
-
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.activation.FileDataSource;
 import javax.jbi.messaging.MessageExchange;
 import javax.jbi.messaging.MessagingException;
 import javax.jbi.messaging.NormalizedMessage;
 import javax.mail.Address;
+import javax.mail.BodyPart;
 import javax.mail.Message;
+import javax.mail.Multipart;
+import javax.mail.Part;
 import javax.mail.internet.AddressException;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
@@ -30,6 +41,8 @@
 import javax.mail.internet.MimeMultipart;
 import javax.xml.transform.TransformerException;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.servicemix.jbi.jaxp.StringSource;
 
 /**
@@ -39,7 +52,7 @@
  * @version $Revision$
  */
 public class MimeMailMarshaler extends MailMarshalerSupport {
-
+    private static Log log = LogFactory.getLog(MimeMailPoller.class);
 
     /**
      * Populates the MessageExchange with values extracted from the mail message using expressions.
@@ -50,34 +63,84 @@
      * @throws javax.mail.MessagingException if the message could not be constructed or there was an error creating an address
      */
 	public void prepareExchange(MessageExchange exchange, NormalizedMessage normalizedMessage, MimeMessage mimeMessage) throws javax.mail.MessagingException {
-		String from 	= InternetAddress.toString(mimeMessage.getFrom());
+		String from     = InternetAddress.toString(mimeMessage.getFrom());
 		String to 		= InternetAddress.toString(mimeMessage.getRecipients(Message.RecipientType.TO));
 		String cc 		= InternetAddress.toString(mimeMessage.getRecipients(Message.RecipientType.CC));
 		String replyTo 	= InternetAddress.toString(mimeMessage.getReplyTo());
 		String sentDate = getDateFormat().format(mimeMessage.getSentDate());
-		String text;
-		try {
-			//TODO: Add Message Attachments and allow multipart messages.
-			text 	= asString(mimeMessage.getContent());
-		} catch (IOException e) {
-			throw new javax.mail.MessagingException("Error while fetching content",e);
-		}
-		
-		normalizedMessage.setProperty("org.apache.servicemix.email.from",from);
-		normalizedMessage.setProperty("org.apache.servicemix.email.to",to);
-		normalizedMessage.setProperty("org.apache.servicemix.email.cc",cc);
-		normalizedMessage.setProperty("org.apache.servicemix.email.text",text);
-		normalizedMessage.setProperty("org.apache.servicemix.email.replyTo",replyTo);
-		normalizedMessage.setProperty("org.apache.servicemix.email.sentDate",sentDate);
-		
-		//TODO: Change this to something that makes more sense
+		String text = null;
+        String html = null;
+        MimeMultipart mp = null;
+        Object content = null;
+        Object subContent = null;
+        MimeMultipart subMP = null;
+
 		try {
-			normalizedMessage.setContent(new StringSource(text));
+            content = mimeMessage.getContent();
+            if (content instanceof String)
+                // simple mail
+                text = asString(content);
+            else if (content instanceof MimeMultipart) {
+                // mail with attachment
+                mp = (MimeMultipart)content;
+                int nbMP = mp.getCount();
+                for (int i=0; i < nbMP; i++) {
+                    Part part = mp.getBodyPart(i);
+                    String disposition = part.getDisposition();
+                    if ((disposition != null) &&
+                        ((disposition.equals(Part.ATTACHMENT) ||
+                         (disposition.equals(Part.INLINE))))) {
+                        //Parts marked with a disposition of Part.ATTACHMENT from part.getDisposition() are clearly attachments
+                        DataHandler att = part.getDataHandler();
+                        normalizedMessage.addAttachment(att.getName(), att);
+                    } else {
+                        MimeBodyPart mbp = (MimeBodyPart)part;
+                        if (mbp.isMimeType("text/plain")) {
+                          // Handle plain
+                            text = (String)mbp.getContent();
+                        } else if (mbp.isMimeType("text/html")) {
+                          // Handle html contents
+                            html = (String)mbp.getContent();
+                        } else if (mbp.isMimeType("multipart/related")){
+                            // Special case for multipart/related message type
+                            subContent = mbp.getContent();
+                            if (subContent instanceof MimeMultipart) {
+                                subMP = (MimeMultipart)subContent;
+                                int nbsubMP = subMP.getCount();
+                                for (int j=0; j < nbsubMP; j++) {
+                                    MimeBodyPart subMBP = (MimeBodyPart)part;
+                                    // add a property into the normalize message
+                                    normalizedMessage.setProperty("org.apache.servicemix.email.alternativeContent" + j, subMBP.getContent());
+                                }
+                            }
+                        } else // strange mail...log a warning
+                            log.warn("Some mail contents can not be traited and is not include into message");
+                    }
+                }
+            } else { // strange mail...log a warning
+                log.warn("Some mail contents can not be traited and is not include into message");
+            }
 		} 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);
+        }
+
+        normalizedMessage.setProperty("org.apache.servicemix.email.from", from);
+        normalizedMessage.setProperty("org.apache.servicemix.email.to", to);
+        normalizedMessage.setProperty("org.apache.servicemix.email.cc", cc);
+        normalizedMessage.setProperty("org.apache.servicemix.email.text", text);
+        normalizedMessage.setProperty("org.apache.servicemix.email.replyTo", replyTo);
+        normalizedMessage.setProperty("org.apache.servicemix.email.sentDate", sentDate);
+        normalizedMessage.setProperty("org.apache.servicemix.email.html", html);
+
+        try {
+            normalizedMessage.setContent(new StringSource(text));
+        } catch (MessagingException e) {
+            throw new javax.mail.MessagingException("Error while setting content on normalized message",e);
+        }
 	}
-	
+
     /**
      * Populates the mime email message with values extracted from the message exchange using expressions.
      *
@@ -117,7 +180,7 @@
                 htmlBodyPart.setContent(html, "text/html");
                 content.addBodyPart(textBodyPart);
                 content.addBodyPart(htmlBodyPart);
-                
+
                 mimeMessage.setContent(content);
             }
             String subject = getSubject(exchange, normalizedMessage);
@@ -132,6 +195,38 @@
             if (replyTo != null) {
                 mimeMessage.setReplyTo(replyTo);
             }
+
+            // add attachment from message and properties
+            HashMap attachments = this.getAttachments(exchange, normalizedMessage);
+            if (attachments != null) {
+                Set attNames = attachments.keySet();
+                Iterator itAttNames = attNames.iterator();
+                if (itAttNames.hasNext()) { // there is at least one attachment
+                    // Create the message part
+                    BodyPart messageBodyPart = new MimeBodyPart();
+                    // Fill the message
+                    messageBodyPart.setText(text);
+                    // Create a Multipart
+                    Multipart multipart = new MimeMultipart();
+                    // Add part one
+                    multipart.addBodyPart(messageBodyPart);
+                    while (itAttNames.hasNext()) {
+                        String oneAttachmentName = (String)itAttNames.next();
+                        // Create another body part
+                        messageBodyPart = new MimeBodyPart();
+                        // Set the data handler to the attachment
+                        messageBodyPart.setDataHandler(new DataHandler((DataSource)attachments.get(oneAttachmentName)));
+                        // Set the filename
+                        messageBodyPart.setFileName(oneAttachmentName);
+                        // Set Disposition
+                        messageBodyPart.setDisposition(Part.ATTACHMENT);
+                        // Add part to multipart
+                        multipart.addBodyPart(messageBodyPart);
+                    }
+                    // Put parts in message
+                    mimeMessage.setContent(multipart);
+                 }
+            }
         }
         catch (MessagingException e) {
             throw new javax.mail.MessagingException(e.getMessage(), e);
@@ -162,6 +257,38 @@
 
     protected Address[] getReplyTo(MessageExchange exchange, NormalizedMessage normalizedMessage) throws MessagingException, AddressException {
         return asAddressArray(getReplyTo().evaluate(exchange, normalizedMessage));
+    }
+
+    protected HashMap getAttachments(MessageExchange exchange, NormalizedMessage normalizedMessage) {
+        HashMap attachments = new HashMap();
+        String filePath = "";
+        String oneAttachmentName = "";
+        try {
+            // get attachment from property org.apache.servicemix.email.attachment
+            String listAttachment = (String)getAttachments().evaluate(exchange, normalizedMessage);
+            if (listAttachment == null || listAttachment.equals(""))
+                return null;// no attachmnent
+            StringTokenizer st = new StringTokenizer(listAttachment, ",");
+            if (st == null)
+                return null; // no attachmnent
+            while (st.hasMoreTokens()) {
+                filePath = st.nextToken();
+                File file = new File(filePath);
+                attachments.put(file.getName(), new FileDataSource(file));
+            }
+        } catch (MessagingException e) {
+            log.warn("file not found for attachment : " + e.getMessage() + " : " + filePath);
+        }
+        // get attachment from Normalize Message
+        Set attNames = normalizedMessage.getAttachmentNames();
+        Iterator itAttNames = attNames.iterator();
+        while (itAttNames.hasNext()) {
+            oneAttachmentName = (String)itAttNames.next();
+            DataSource oneAttchmentInputString = normalizedMessage.getAttachment(oneAttachmentName).getDataSource();
+            attachments.put(oneAttachmentName, oneAttchmentInputString);
+        }
+
+        return attachments;
     }
 
 }

Modified: incubator/servicemix/trunk/servicemix-components/src/test/java/org/apache/servicemix/components/email/MimeMailTest.java
URL: http://svn.apache.org/viewcvs/incubator/servicemix/trunk/servicemix-components/src/test/java/org/apache/servicemix/components/email/MimeMailTest.java?rev=396805&r1=396804&r2=396805&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-components/src/test/java/org/apache/servicemix/components/email/MimeMailTest.java (original)
+++ incubator/servicemix/trunk/servicemix-components/src/test/java/org/apache/servicemix/components/email/MimeMailTest.java Tue Apr 25 00:52:10 2006
@@ -18,13 +18,17 @@
 import java.util.Date;
 import java.util.List;
 
+import javax.activation.DataHandler;
 import javax.jbi.messaging.InOnly;
 import javax.jbi.messaging.NormalizedMessage;
+import javax.mail.Part;
 import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
 import javax.xml.namespace.QName;
 import javax.xml.transform.Source;
 
 import org.apache.servicemix.jbi.resolver.ServiceNameEndpointResolver;
+import org.apache.servicemix.jbi.util.ByteArrayDataSource;
 import org.apache.servicemix.tck.TestSupport;
 import org.springframework.context.support.AbstractXmlApplicationContext;
 import org.apache.xbean.spring.context.ClassPathXmlApplicationContext;
@@ -88,7 +92,50 @@
         assertEquals("subject", "Drink a beer James", message.getSubject());
     }
 
+    public void testUsingXPathExpressionsInEmailWithAttachment() throws Exception {
 
+        // START SNIPPET: xpath
+        QName xpathSender = new QName("http://servicemix.org/cheese/", "emailSenderWithExpressionsAndAttachment");
+        ServiceNameEndpointResolver resolver = new ServiceNameEndpointResolver(xpathSender);
+
+        InOnly exchange = client.createInOnlyExchange(resolver);
+
+        Source source = getSourceFromClassPath("request.xml");
+        exchange.getInMessage().setContent(source);
+        ByteArrayDataSource ds = new ByteArrayDataSource("hello".getBytes(), "text/plain");
+        ds.setName("id");
+        exchange.getInMessage().addAttachment("id", new DataHandler(ds));
+
+        client.send(exchange);
+        // END SNIPPET: xpath
+
+        // lest find the test sender
+        StubJavaMailSender sender = (StubJavaMailSender) getBean("javaMailSender");
+        sender.assertMessagesReceived(1);
+        List messages = sender.getMessages();
+        assertEquals("message size: " + messages, 1, messages.size());
+
+        MimeMessage message = (MimeMessage) messages.get(0);
+
+        System.out.println("Created message: " + message);
+        Object content = message.getContent();
+        assertTrue(content instanceof MimeMultipart);
+        MimeMultipart contentMP = (MimeMultipart) content;
+        assertEquals(contentMP.getCount(), 3); // first attachement for text body and second for file attached
+        Part part = contentMP.getBodyPart(0);
+        assertTrue(part.isMimeType("text/plain"));
+        part = contentMP.getBodyPart(1);
+        String disposition = part.getDisposition();
+        assertTrue(disposition.equalsIgnoreCase(Part.ATTACHMENT));
+        DataHandler att = part.getDataHandler();
+        assertEquals("example.xml", att.getName().toLowerCase());
+        part = contentMP.getBodyPart(2);
+        disposition = part.getDisposition();
+        assertTrue(disposition.equalsIgnoreCase(Part.ATTACHMENT));
+        att = part.getDataHandler();
+        assertEquals("id", att.getName().toLowerCase());
+        assertEquals("subject", "Drink a beer James", message.getSubject());
+    }
 
     protected AbstractXmlApplicationContext createBeanFactory() {
         return new ClassPathXmlApplicationContext("org/apache/servicemix/components/email/mimeMail.xml");

Modified: incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/mimeMail.xml
URL: http://svn.apache.org/viewcvs/incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/mimeMail.xml?rev=396805&r1=396804&r2=396805&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/mimeMail.xml (original)
+++ incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/mimeMail.xml Tue Apr 25 00:52:10 2006
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns:sm="http://servicemix.apache.org/config/1.0" 
+<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
 	   xmlns:foo="http://servicemix.org/cheese/">
 
   <!-- the JBI container -->
@@ -39,6 +39,42 @@
               <property name="text">
                 <bean class="org.apache.servicemix.expression.JaxenStringXPathExpression">
                   <constructor-arg value="concat('Hello there ', /person/name, ' how are you today?')"/>
+                </bean>
+              </property>
+            </bean>
+          </property>
+        </bean></sm:component>
+      </sm:activationSpec>
+
+      <sm:activationSpec componentName="emailSenderWithExpressionsAndAttachment" service="foo:emailSenderWithExpressionsAndAttachment">
+        <sm:component><bean class="org.apache.servicemix.components.email.MimeMailSender">
+          <property name="sender" ref="javaMailSender"/>
+
+          <property name="marshaler">
+            <bean class="org.apache.servicemix.components.email.MimeMailMarshaler">
+              <property name="from">
+                <bean class="org.apache.servicemix.expression.JaxenStringXPathExpression">
+                  <constructor-arg value="/person/email"/>
+                </bean>
+              </property>
+              <property name="to">
+                <bean class="org.apache.servicemix.expression.JaxenStringXPathExpression">
+                  <constructor-arg value="/person/accountant/email"/>
+                </bean>
+              </property>
+              <property name="subject">
+                <bean class="org.apache.servicemix.expression.JaxenStringXPathExpression">
+                  <constructor-arg value="concat('Drink a beer ', /person/name)"/>
+                </bean>
+              </property>
+              <property name="text">
+                <bean class="org.apache.servicemix.expression.JaxenStringXPathExpression">
+                  <constructor-arg value="concat('Hello there ', /person/name, ' how are you today?')"/>
+                </bean>
+              </property>
+              <property name="attachments">
+                <bean class="org.apache.servicemix.expression.JaxenStringXPathExpression">
+                  <constructor-arg value="/person/attachments"/>
                 </bean>
               </property>
             </bean>

Modified: incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/request.xml
URL: http://svn.apache.org/viewcvs/incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/request.xml?rev=396805&r1=396804&r2=396805&view=diff
==============================================================================
--- incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/request.xml (original)
+++ incubator/servicemix/trunk/servicemix-components/src/test/resources/org/apache/servicemix/components/email/request.xml Tue Apr 25 00:52:10 2006
@@ -4,4 +4,5 @@
   <accountant>
     <email>foo@bar.com</email>
   </accountant>
-</person>
\ No newline at end of file
+  <attachments>example.xml</attachments>
+</person>