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>