View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.email;
8   
9   import org.mule.DefaultMuleMessage;
10  import org.mule.api.MuleContext;
11  import org.mule.api.MuleMessage;
12  import org.mule.transport.AbstractMuleMessageFactory;
13  import org.mule.util.StringUtils;
14  
15  import java.util.Date;
16  import java.util.Enumeration;
17  import java.util.HashMap;
18  import java.util.LinkedList;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.TreeMap;
22  
23  import javax.mail.Address;
24  import javax.mail.Header;
25  import javax.mail.Message;
26  import javax.mail.Message.RecipientType;
27  import javax.mail.MessagingException;
28  import javax.mail.Multipart;
29  import javax.mail.Part;
30  import javax.mail.internet.MimeMessage;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  
35  public class MailMuleMessageFactory extends AbstractMuleMessageFactory
36  {
37      public static final String HEADER_LIST_PREFIX = "List:";
38  
39      private static Log log = LogFactory.getLog(MailMuleMessageFactory.class);
40  
41      public MailMuleMessageFactory(MuleContext context)
42      {
43          super(context);
44      }
45  
46      @Override
47      protected Class<?>[] getSupportedTransportMessageTypes()
48      {
49          return new Class[]{Message.class};
50      }
51  
52      @Override
53      protected Object extractPayload(Object transportMessage, String encoding) throws Exception
54      {
55          return transportMessage;
56      }
57  
58      @Override
59      protected void addProperties(DefaultMuleMessage muleMessage, Object transportMessage) throws Exception
60      {
61          super.addProperties(muleMessage, transportMessage);
62  
63          Message mailMessage = (Message) transportMessage;
64  
65          addRecipientProperty(muleMessage, mailMessage, RecipientType.TO, MailProperties.INBOUND_TO_ADDRESSES_PROPERTY);
66          addRecipientProperty(muleMessage, mailMessage, RecipientType.CC, MailProperties.INBOUND_CC_ADDRESSES_PROPERTY);
67          addRecipientProperty(muleMessage, mailMessage, RecipientType.BCC, MailProperties.INBOUND_BCC_ADDRESSES_PROPERTY);
68  
69          addReplyToProperty(muleMessage, mailMessage);
70          addFromProperty(muleMessage, mailMessage);
71  
72          muleMessage.setOutboundProperty(MailProperties.INBOUND_SUBJECT_PROPERTY,
73                                          StringUtils.defaultIfEmpty(mailMessage.getSubject(), "(no subject)"));
74          muleMessage.setOutboundProperty(MailProperties.INBOUND_CONTENT_TYPE_PROPERTY,
75                                          StringUtils.defaultIfEmpty(mailMessage.getContentType(), "text/plain"));
76  
77          addSentDateProperty(muleMessage, mailMessage);
78          addMailHeadersToMessageProperties(mailMessage, muleMessage);
79      }
80  
81      protected void addRecipientProperty(MuleMessage muleMessage, Message mailMessage,
82          RecipientType recipientType, String property) throws MessagingException
83      {
84          MimeMessage mimeMessage = null;
85          if (mailMessage instanceof MimeMessage)
86          {
87              mimeMessage = (MimeMessage) mailMessage;
88          }
89  
90          try
91          {
92              Address[] recipients = mailMessage.getRecipients(recipientType);
93              muleMessage.setOutboundProperty(property, MailUtils.mailAddressesToString(recipients));
94          }
95          catch (MessagingException e)
96          {
97              if (mimeMessage != null)
98              {
99                  String[] header = mimeMessage.getHeader(recipientType.toString());
100                 String recipients = StringUtils.join(header, ", ");
101                 muleMessage.setOutboundProperty(property, recipients);
102             }
103         }
104     }
105 
106     protected void addReplyToProperty(DefaultMuleMessage muleMessage, Message mailMessage)
107     {
108         try
109         {
110             muleMessage.setOutboundProperty(MailProperties.INBOUND_REPLY_TO_ADDRESSES_PROPERTY,
111                                             MailUtils.mailAddressesToString(mailMessage.getReplyTo()));
112         }
113         catch (MessagingException me)
114         {
115             log.warn("Invalid address found in ReplyTo header:", me);
116         }
117     }
118 
119     protected void addFromProperty(DefaultMuleMessage muleMessage, Message mailMessage)
120     {
121         try
122         {
123             muleMessage.setOutboundProperty(MailProperties.INBOUND_FROM_ADDRESS_PROPERTY,
124                                             MailUtils.mailAddressesToString(mailMessage.getFrom()));
125         }
126         catch (javax.mail.MessagingException me)
127         {
128             log.warn("Invalid address found in From header:", me);
129         }
130     }
131 
132     protected void addSentDateProperty(DefaultMuleMessage muleMessage, Message mailMessage)
133         throws MessagingException
134     {
135         Date sentDate = mailMessage.getSentDate();
136         if (sentDate == null)
137         {
138             sentDate = new Date();
139         }
140         muleMessage.setOutboundProperty(MailProperties.SENT_DATE_PROPERTY, sentDate);
141     }
142 
143     @SuppressWarnings({ "unchecked", "rawtypes" })
144     protected void addMailHeadersToMessageProperties(Message mailMessage, DefaultMuleMessage muleMessage)
145         throws MessagingException
146     {
147         for (Enumeration<?> e = mailMessage.getAllHeaders(); e.hasMoreElements();)
148         {
149             Header header = (Header) e.nextElement();
150 
151             String name = header.getName();
152             String listName = MailUtils.toListHeader(name);
153             String value = header.getValue();
154 
155             if (null == muleMessage.getOutboundProperty(name))
156             {
157                 muleMessage.setOutboundProperty(name, value);
158             }
159 
160             Object listPropertyValue = muleMessage.getOutboundProperty(listName);
161             if (null == listPropertyValue)
162             {
163                 listPropertyValue = new LinkedList<Object>();
164                 muleMessage.setOutboundProperty(listName, listPropertyValue);
165             }
166             if (listPropertyValue instanceof List<?>)
167             {
168                 ((List) listPropertyValue).add(header.getValue());
169             }
170         }
171     }
172 
173     @Override
174     protected void addAttachments(DefaultMuleMessage muleMessage, Object transportMessage) throws Exception
175     {
176         super.addAttachments(muleMessage, transportMessage);
177 
178         Object content = ((Message) transportMessage).getContent();
179         if (content instanceof Multipart)
180         {
181             Multipart multipart = (Multipart) content;
182 
183             TreeMap<String, Part> attachments = new TreeMap<String, Part>();
184             MailUtils.getAttachments(multipart, attachments);
185 
186             log.debug("Received Multipart message. Adding attachments");
187             for (Map.Entry<String, Part> entry : attachments.entrySet())
188             {
189                 Part part = entry.getValue();
190                 String name = entry.getKey();
191 
192                 muleMessage.addInboundAttachment(name, part.getDataHandler());
193                 addAttachmentHeaders(name, part, muleMessage);
194             }
195         }
196     }
197 
198     protected void addAttachmentHeaders(String name, Part part, MuleMessage muleMessage) throws javax.mail.MessagingException
199     {
200         Map<String, String> headers = new HashMap<String, String>();
201         for (Enumeration<?> e = part.getAllHeaders(); e.hasMoreElements();)
202         {
203             Header h = (Header) e.nextElement();
204             headers.put(h.getName(), h.getValue());
205         }
206 
207         if (headers.size() > 0)
208         {
209             muleMessage.setOutboundProperty(name + AbstractMailConnector.ATTACHMENT_HEADERS_PROPERTY_POSTFIX,
210                                             headers);
211         }
212     }
213 }