View Javadoc

1   /*
2    * $Id: ObjectToMimeMessage.java 19965 2010-10-18 21:40:52Z mike.schilling $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.transport.email.transformers;
12  
13  import org.mule.api.MuleMessage;
14  import org.mule.api.transformer.TransformerException;
15  import org.mule.transformer.simple.SerializableToByteArray;
16  import org.mule.transport.email.AbstractMailConnector;
17  import org.mule.util.StringUtils;
18  
19  import java.io.IOException;
20  import java.io.Serializable;
21  import java.util.Map;
22  
23  import javax.activation.DataHandler;
24  import javax.mail.BodyPart;
25  import javax.mail.Message;
26  import javax.mail.MessagingException;
27  import javax.mail.internet.MimeBodyPart;
28  import javax.mail.internet.MimeMultipart;
29  import javax.mail.util.ByteArrayDataSource;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  
34  /**
35   * Transforms a {@link javax.mail.Message} to a {@link MuleMessage}, with support for attachments
36   */
37  public class ObjectToMimeMessage extends StringToEmailMessage
38  {
39      private Log logger = LogFactory.getLog(getClass());
40      private boolean useInboundAttachments = true;
41      private boolean useOutboundAttachments = true;
42  
43      @Override
44      protected void setContent(Object payload, Message msg, String contentType, MuleMessage message)
45          throws Exception
46      {
47          boolean transformInboundAttachments = useInboundAttachments && message.getInboundAttachmentNames().size() > 0;
48          boolean transformOutboundAttachments = useOutboundAttachments && message.getOutboundAttachmentNames().size() > 0;
49          if (transformInboundAttachments || transformOutboundAttachments)
50          {
51              // The content type must be multipart/mixed
52              MimeMultipart multipart = new MimeMultipart("mixed");
53              multipart.addBodyPart(getPayloadBodyPart(message.getPayload(), contentType));
54              if (transformInboundAttachments)
55              {
56                  for (String name : message.getInboundAttachmentNames())
57                  {
58                      // Let outbound attachments override inbound ones
59                      if (!transformOutboundAttachments || message.getOutboundAttachment(name) == null)
60                      {
61                          BodyPart part = getBodyPartForAttachment(message.getInboundAttachment(name), name);
62                          // Check message props for extra headers
63                          addBodyPartHeaders(part, name, message);
64                          multipart.addBodyPart(part);
65                      }
66                  }
67              }
68              if (transformOutboundAttachments)
69              {
70                  for (String name : message.getOutboundAttachmentNames())
71                  {
72                      BodyPart part = getBodyPartForAttachment(message.getOutboundAttachment(name), name);
73                      // Check message props for extra headers
74                      addBodyPartHeaders(part, name, message);
75                      multipart.addBodyPart(part);
76                  }
77              }
78              // the payload must be set to the constructed MimeMultipart message
79              payload = multipart;
80              // the ContentType of the message to be sent, must be the multipart content type
81              contentType = multipart.getContentType();
82          }
83          
84          // now the message will contain the multipart payload, and the multipart
85          // contentType
86          super.setContent(payload, msg, contentType, message);
87      }
88  
89      protected void addBodyPartHeaders(BodyPart part, String name, MuleMessage message)
90      {
91          Map<String, String> headers = message.getOutboundProperty(
92              name + AbstractMailConnector.ATTACHMENT_HEADERS_PROPERTY_POSTFIX);
93  
94          if (null != headers)
95          {
96              for (String key : headers.keySet())
97              {
98                  try
99                  {
100                     part.setHeader(key, headers.get(key));
101                 }
102                 catch (MessagingException me)
103                 {
104                     logger.error("Failed to set bodypart header", me);
105                 }
106             }
107         }
108     }
109 
110     protected BodyPart getBodyPartForAttachment(DataHandler handler, String name) throws MessagingException
111     {
112         BodyPart part = new MimeBodyPart();
113         part.setDataHandler(handler);
114         part.setDescription(name);
115 
116         part.setFileName(StringUtils.defaultString(handler.getName(), name));
117         return part;
118     }
119 
120     protected BodyPart getPayloadBodyPart(Object payload, String contentType)
121         throws MessagingException, TransformerException, IOException
122     {
123         DataHandler handler;
124         if (payload instanceof String)
125         {
126             handler = new DataHandler(new ByteArrayDataSource((String) payload, contentType));
127         }
128         else if (payload instanceof byte[])
129         {
130             handler = new DataHandler(new ByteArrayDataSource((byte[])payload, contentType));
131         }
132         else if (payload instanceof Serializable)
133         {
134             handler = new DataHandler(new ByteArrayDataSource(
135                 (byte[])new SerializableToByteArray().transform(payload), contentType));
136         }
137         else
138         {
139             throw new IllegalArgumentException();
140         }
141         BodyPart part = new MimeBodyPart();
142         part.setDataHandler(handler);
143         part.setDescription("Payload");
144         return part;
145     }
146 
147     /**
148      * Set whether inbound attachments should be transformed into MIME parts
149      */
150     public void setUseInboundAttachments(boolean useInboundAttachments)
151     {
152         this.useInboundAttachments = useInboundAttachments;
153     }
154 
155     /**
156      * Set whether outbound attachments should be transformed into MIME parts
157      */
158     public void setUseOutboundAttachments(boolean useOutboundAttachments)
159     {
160         this.useOutboundAttachments = useOutboundAttachments;
161     }
162 }