1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.util.mail;
24  
25  import com.liferay.portal.kernel.jndi.PortalJNDIUtil;
26  import com.liferay.portal.kernel.mail.MailMessage;
27  import com.liferay.portal.kernel.util.GetterUtil;
28  import com.liferay.portal.kernel.util.Validator;
29  
30  import java.io.ByteArrayInputStream;
31  import java.io.File;
32  
33  import java.net.SocketException;
34  
35  import java.util.Date;
36  
37  import javax.activation.DataHandler;
38  import javax.activation.DataSource;
39  import javax.activation.FileDataSource;
40  
41  import javax.mail.Message;
42  import javax.mail.MessagingException;
43  import javax.mail.Part;
44  import javax.mail.SendFailedException;
45  import javax.mail.Session;
46  import javax.mail.Transport;
47  import javax.mail.internet.AddressException;
48  import javax.mail.internet.InternetAddress;
49  import javax.mail.internet.MimeBodyPart;
50  import javax.mail.internet.MimeMessage;
51  import javax.mail.internet.MimeMultipart;
52  
53  import javax.naming.NamingException;
54  
55  import org.apache.commons.lang.time.StopWatch;
56  import org.apache.commons.logging.Log;
57  import org.apache.commons.logging.LogFactory;
58  
59  /**
60   * <a href="MailEngine.java.html"><b><i>View Source</i></b></a>
61   *
62   * @author Brian Wing Shun Chan
63   * @author Brian Myunghun Kim
64   * @author Jorge Ferrer
65   * @author Neil Griffin
66   *
67   */
68  public class MailEngine {
69  
70      public static Session getSession() throws NamingException {
71          return getSession(false);
72      }
73  
74      public static Session getSession(boolean cache) throws NamingException {
75          Session session = PortalJNDIUtil.getMailSession();
76  
77          session.setDebug(_log.isDebugEnabled());
78  
79          if (_log.isDebugEnabled()) {
80              session.getProperties().list(System.out);
81          }
82  
83          return session;
84      }
85  
86      public static void send(MailMessage mailMessage)
87          throws MailEngineException {
88  
89          send(
90              mailMessage.getFrom(), mailMessage.getTo(), mailMessage.getCC(),
91              mailMessage.getBCC(), mailMessage.getBulkAddresses(),
92              mailMessage.getSubject(), mailMessage.getBody(),
93              mailMessage.isHTMLFormat(), mailMessage.getReplyTo(),
94              mailMessage.getMessageId(), mailMessage.getInReplyTo(),
95              mailMessage.getAttachments());
96      }
97  
98      public static void send(String from, String to, String subject, String body)
99          throws MailEngineException {
100 
101         try {
102             send(
103                 new InternetAddress(from), new InternetAddress(to), subject,
104                 body);
105         }
106         catch (AddressException ae) {
107             throw new MailEngineException(ae);
108         }
109     }
110 
111     public static void send(
112             InternetAddress from, InternetAddress to,
113             String subject, String body)
114         throws MailEngineException {
115 
116         send(
117             from, new InternetAddress[] {to}, null, null, subject, body, false,
118             null, null, null);
119     }
120 
121     public static void send(
122             InternetAddress from, InternetAddress to, String subject,
123             String body, boolean htmlFormat)
124         throws MailEngineException {
125 
126         send(
127             from, new InternetAddress[] {to}, null, null, subject, body,
128             htmlFormat, null, null, null);
129     }
130 
131     public static void send(
132             InternetAddress from, InternetAddress[] to, String subject,
133             String body)
134         throws MailEngineException {
135 
136         send(from, to, null, null, subject, body, false, null, null, null);
137     }
138 
139     public static void send(
140             InternetAddress from, InternetAddress[] to, String subject,
141             String body, boolean htmlFormat)
142         throws MailEngineException {
143 
144         send(from, to, null, null, subject, body, htmlFormat, null, null, null);
145     }
146 
147     public static void send(
148             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
149             String subject, String body)
150         throws MailEngineException {
151 
152         send(from, to, cc, null, subject, body, false, null, null, null);
153     }
154 
155     public static void send(
156             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
157             String subject, String body, boolean htmlFormat)
158         throws MailEngineException {
159 
160         send(from, to, cc, null, subject, body, htmlFormat, null, null, null);
161     }
162 
163     public static void send(
164             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
165             InternetAddress[] bcc, String subject, String body)
166         throws MailEngineException {
167 
168         send(from, to, cc, bcc, subject, body, false, null, null, null);
169     }
170 
171     public static void send(
172             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
173             InternetAddress[] bcc, String subject, String body,
174             boolean htmlFormat, InternetAddress[] replyTo, String messageId,
175             String inReplyTo)
176         throws MailEngineException {
177 
178         send(
179             from, to, cc, bcc, null, subject, body, htmlFormat, replyTo,
180             messageId, inReplyTo, null);
181     }
182 
183     public static void send(
184             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
185             InternetAddress[] bcc, InternetAddress[] bulkAddresses,
186             String subject, String body, boolean htmlFormat,
187             InternetAddress[] replyTo, String messageId, String inReplyTo)
188         throws MailEngineException {
189 
190         send(
191             from, to, cc, bcc, bulkAddresses, subject, body, htmlFormat,
192             replyTo, messageId, inReplyTo, null);
193     }
194 
195     public static void send(
196             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
197             InternetAddress[] bcc, InternetAddress[] bulkAddresses,
198             String subject, String body, boolean htmlFormat,
199             InternetAddress[] replyTo, String messageId, String inReplyTo,
200             File[] attachments)
201         throws MailEngineException {
202 
203         StopWatch stopWatch = null;
204 
205         if (_log.isDebugEnabled()) {
206             stopWatch = new StopWatch();
207 
208             stopWatch.start();
209 
210             _log.debug("From: " + from);
211             _log.debug("To: " + to);
212             _log.debug("CC: " + cc);
213             _log.debug("BCC: " + bcc);
214             _log.debug("List Addresses: " + bulkAddresses);
215             _log.debug("Subject: " + subject);
216             _log.debug("Body: " + body);
217             _log.debug("HTML Format: " + htmlFormat);
218             _log.debug("Reply to: " + replyTo);
219             _log.debug("Message ID: " + messageId);
220             _log.debug("In Reply To: " + inReplyTo);
221 
222             if (attachments != null) {
223                 for (int i = 0; i < attachments.length; i++) {
224                     File attachment = attachments[i];
225 
226                     if (attachment != null) {
227                         String path = attachment.getAbsolutePath();
228 
229                         _log.debug("Attachment #" + (i + 1) + ": " + path);
230                     }
231                 }
232             }
233         }
234 
235         try {
236             Session session = getSession();
237 
238             Message msg = new LiferayMimeMessage(session);
239 
240             msg.setFrom(from);
241             msg.setRecipients(Message.RecipientType.TO, to);
242 
243             if (cc != null) {
244                 msg.setRecipients(Message.RecipientType.CC, cc);
245             }
246 
247             if (bcc != null) {
248                 msg.setRecipients(Message.RecipientType.BCC, bcc);
249             }
250 
251             msg.setSubject(subject);
252 
253             if ((attachments != null) && (attachments.length > 0)) {
254                 MimeMultipart rootMultipart = new MimeMultipart(
255                     _MULTIPART_TYPE_MIXED);
256 
257                 MimeMultipart messageMultipart = new MimeMultipart(
258                     _MULTIPART_TYPE_ALTERNATIVE);
259 
260                 MimeBodyPart messageBodyPart = new MimeBodyPart();
261 
262                 messageBodyPart.setContent(messageMultipart);
263 
264                 rootMultipart.addBodyPart(messageBodyPart);
265 
266                 if (htmlFormat) {
267                     MimeBodyPart bodyPart = new MimeBodyPart();
268 
269                     bodyPart.setContent(body, _TEXT_HTML);
270 
271                     messageMultipart.addBodyPart(bodyPart);
272                 }
273                 else {
274                     MimeBodyPart bodyPart = new MimeBodyPart();
275 
276                     bodyPart.setText(body);
277 
278                     messageMultipart.addBodyPart(bodyPart);
279                 }
280 
281                 for (int i = 0; i < attachments.length; i++) {
282                     File attachment = attachments[i];
283 
284                     if (attachment != null) {
285                         MimeBodyPart bodyPart = new MimeBodyPart();
286 
287                         DataSource source = new FileDataSource(attachment);
288 
289                         bodyPart.setDisposition(Part.ATTACHMENT);
290                         bodyPart.setDataHandler(new DataHandler(source));
291                         bodyPart.setFileName(attachment.getName());
292 
293                         rootMultipart.addBodyPart(bodyPart);
294                     }
295                 }
296 
297                 msg.setContent(rootMultipart);
298 
299                 msg.saveChanges();
300             }
301             else {
302                 if (htmlFormat) {
303                     msg.setContent(body, _TEXT_HTML);
304                 }
305                 else {
306                     msg.setContent(body, _TEXT_PLAIN);
307                 }
308             }
309 
310             msg.setSentDate(new Date());
311 
312             if (replyTo != null) {
313                 msg.setReplyTo(replyTo);
314             }
315 
316             if (messageId != null) {
317                 msg.setHeader("Message-ID", messageId);
318             }
319 
320             if (inReplyTo!= null) {
321                 msg.setHeader("In-Reply-To", inReplyTo);
322                 msg.setHeader("References", inReplyTo);
323             }
324 
325             _send(session, msg, bulkAddresses);
326         }
327         catch (SendFailedException sfe) {
328             _log.error(sfe);
329         }
330         catch (Exception e) {
331             throw new MailEngineException(e);
332         }
333 
334         if (_log.isDebugEnabled()) {
335             _log.debug("Sending mail takes " + stopWatch.getTime() + " ms");
336         }
337     }
338 
339     public static void send(byte[] msgByteArray) throws MailEngineException {
340         try {
341             Session session = getSession();
342 
343             Message msg = new MimeMessage(
344                 session, new ByteArrayInputStream(msgByteArray));
345 
346             _send(session, msg, null);
347         }
348         catch (Exception e) {
349             throw new MailEngineException(e);
350         }
351     }
352 
353     private static void _send(
354             Session session, Message msg, InternetAddress[] bulkAddresses)
355         throws MessagingException {
356 
357         try {
358             boolean smtpAuth = GetterUtil.getBoolean(
359                 session.getProperty("mail.smtp.auth"), false);
360             String smtpHost = session.getProperty("mail.smtp.host");
361             String user = session.getProperty("mail.smtp.user");
362             String password = session.getProperty("mail.smtp.password");
363 
364             if (smtpAuth && Validator.isNotNull(user) &&
365                 Validator.isNotNull(password)) {
366 
367                 Transport transport = session.getTransport("smtp");
368 
369                 transport.connect(smtpHost, user, password);
370 
371                 if (bulkAddresses != null && bulkAddresses.length > 0) {
372                     transport.sendMessage(msg, bulkAddresses);
373                 }
374                 else {
375                     transport.sendMessage(msg, msg.getAllRecipients());
376                 }
377 
378                 transport.close();
379             }
380             else {
381                 if ((bulkAddresses != null) && (bulkAddresses.length > 0)) {
382                     Transport.send(msg, bulkAddresses);
383                 }
384                 else {
385                     Transport.send(msg);
386                 }
387             }
388         }
389         catch (MessagingException me) {
390             if (me.getNextException() instanceof SocketException) {
391                 if (_log.isWarnEnabled()) {
392                     _log.warn(
393                         "Failed to connect to a valid mail server. Please " +
394                             "make sure one is properly configured. " +
395                                 me.getMessage());
396                 }
397             }
398         }
399     }
400 
401     private static final String _MULTIPART_TYPE_ALTERNATIVE = "alternative";
402 
403     private static final String _MULTIPART_TYPE_MIXED = "mixed";
404 
405     private static final String _TEXT_HTML = "text/html;charset=\"UTF-8\"";
406 
407     private static final String _TEXT_PLAIN = "text/plain;charset=\"UTF-8\"";
408 
409     private static Log _log = LogFactory.getLog(MailEngine.class);
410 
411 }