1   /**
2    * Copyright (c) 2000-2007 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.getSubject(),
92              mailMessage.getBody(), mailMessage.isHTMLFormat(),
93              mailMessage.getReplyTo(), mailMessage.getMessageId(),
94              mailMessage.getInReplyTo(), mailMessage.getAttachments());
95      }
96  
97      public static void send(String from, String to, String subject, String body)
98          throws MailEngineException {
99  
100         try {
101             send(
102                 new InternetAddress(from), new InternetAddress(to), subject,
103                 body);
104         }
105         catch (AddressException ae) {
106             throw new MailEngineException(ae);
107         }
108     }
109 
110     public static void send(
111             InternetAddress from, InternetAddress to,
112             String subject, String body)
113         throws MailEngineException {
114 
115         send(
116             from, new InternetAddress[] {to}, null, null, subject, body, false,
117             null, null, null);
118     }
119 
120     public static void send(
121             InternetAddress from, InternetAddress to, String subject,
122             String body, boolean htmlFormat)
123         throws MailEngineException {
124 
125         send(
126             from, new InternetAddress[] {to}, null, null, subject, body,
127             htmlFormat, null, null, null);
128     }
129 
130     public static void send(
131             InternetAddress from, InternetAddress[] to, String subject,
132             String body)
133         throws MailEngineException {
134 
135         send(from, to, null, null, subject, body, false, null, null, null);
136     }
137 
138     public static void send(
139             InternetAddress from, InternetAddress[] to, String subject,
140             String body, boolean htmlFormat)
141         throws MailEngineException {
142 
143         send(from, to, null, null, subject, body, htmlFormat, null, null, null);
144     }
145 
146     public static void send(
147             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
148             String subject, String body)
149         throws MailEngineException {
150 
151         send(from, to, cc, null, subject, body, false, null, null, null);
152     }
153 
154     public static void send(
155             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
156             String subject, String body, boolean htmlFormat)
157         throws MailEngineException {
158 
159         send(from, to, cc, null, subject, body, htmlFormat, null, null, null);
160     }
161 
162     public static void send(
163             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
164             InternetAddress[] bcc, String subject, String body)
165         throws MailEngineException {
166 
167         send(from, to, cc, bcc, subject, body, false, null, null, null);
168     }
169 
170     public static void send(
171             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
172             InternetAddress[] bcc, String subject, String body,
173             boolean htmlFormat, InternetAddress[] replyTo, String messageId,
174             String inReplyTo)
175         throws MailEngineException {
176 
177         send(
178             from, to, cc, bcc, subject, body, htmlFormat, replyTo, messageId,
179             inReplyTo, null);
180     }
181 
182     public static void send(
183             InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
184             InternetAddress[] bcc, String subject, String body,
185             boolean htmlFormat, InternetAddress[] replyTo, String messageId,
186             String inReplyTo, File[] attachments)
187         throws MailEngineException {
188 
189         StopWatch stopWatch = null;
190 
191         if (_log.isDebugEnabled()) {
192             stopWatch = new StopWatch();
193 
194             stopWatch.start();
195 
196             _log.debug("From: " + from);
197             _log.debug("To: " + to);
198             _log.debug("CC: " + cc);
199             _log.debug("BCC: " + bcc);
200             _log.debug("Subject: " + subject);
201             _log.debug("Body: " + body);
202             _log.debug("HTML Format: " + htmlFormat);
203             _log.debug("Reply to: " + replyTo);
204             _log.debug("Message ID: " + messageId);
205             _log.debug("In Reply To: " + inReplyTo);
206 
207             if (attachments != null) {
208                 for (int i = 0; i < attachments.length; i++) {
209                     File attachment = attachments[i];
210 
211                     if (attachment != null) {
212                         String path = attachment.getAbsolutePath();
213 
214                         _log.debug("Attachment #" + (i + 1) + ": " + path);
215                     }
216                 }
217             }
218         }
219 
220         try {
221             Session session = getSession();
222 
223             Message msg = new LiferayMimeMessage(session);
224 
225             msg.setFrom(from);
226             msg.setRecipients(Message.RecipientType.TO, to);
227 
228             if (cc != null) {
229                 msg.setRecipients(Message.RecipientType.CC, cc);
230             }
231 
232             if (bcc != null) {
233                 msg.setRecipients(Message.RecipientType.BCC, bcc);
234             }
235 
236             msg.setSubject(subject);
237 
238             if ((attachments != null) && (attachments.length > 0)) {
239                 MimeMultipart rootMultipart = new MimeMultipart(
240                     _MULTIPART_TYPE_MIXED);
241 
242                 MimeMultipart messageMultipart = new MimeMultipart(
243                     _MULTIPART_TYPE_ALTERNATIVE);
244 
245                 MimeBodyPart messageBodyPart = new MimeBodyPart();
246 
247                 messageBodyPart.setContent(messageMultipart);
248 
249                 rootMultipart.addBodyPart(messageBodyPart);
250 
251                 if (htmlFormat) {
252                     MimeBodyPart bodyPart = new MimeBodyPart();
253 
254                     bodyPart.setContent(body, _TEXT_HTML);
255 
256                     messageMultipart.addBodyPart(bodyPart);
257                 }
258                 else {
259                     MimeBodyPart bodyPart = new MimeBodyPart();
260 
261                     bodyPart.setText(body);
262 
263                     messageMultipart.addBodyPart(bodyPart);
264                 }
265 
266                 for (int i = 0; i < attachments.length; i++) {
267                     File attachment = attachments[i];
268 
269                     if (attachment != null) {
270                         MimeBodyPart bodyPart = new MimeBodyPart();
271 
272                         DataSource source = new FileDataSource(attachment);
273 
274                         bodyPart.setDisposition(Part.ATTACHMENT);
275                         bodyPart.setDataHandler(new DataHandler(source));
276                         bodyPart.setFileName(attachment.getName());
277 
278                         rootMultipart.addBodyPart(bodyPart);
279                     }
280                 }
281 
282                 msg.setContent(rootMultipart);
283 
284                 msg.saveChanges();
285             }
286             else {
287                 if (htmlFormat) {
288                     msg.setContent(body, _TEXT_HTML);
289                 }
290                 else {
291                     msg.setContent(body, _TEXT_PLAIN);
292                 }
293             }
294 
295             msg.setSentDate(new Date());
296 
297             if (replyTo != null) {
298                 msg.setReplyTo(replyTo);
299             }
300 
301             if (messageId != null) {
302                 msg.setHeader("Message-ID", messageId);
303             }
304 
305             if (inReplyTo!= null) {
306                 msg.setHeader("In-Reply-To", inReplyTo);
307                 msg.setHeader("References", inReplyTo);
308             }
309 
310             _send(session, msg);
311         }
312         catch (SendFailedException sfe) {
313             _log.error(sfe);
314         }
315         catch (Exception e) {
316             throw new MailEngineException(e);
317         }
318 
319         if (_log.isDebugEnabled()) {
320             _log.debug("Sending mail takes " + stopWatch.getTime() + " ms");
321         }
322     }
323 
324     public static void send(byte[] msgByteArray) throws MailEngineException {
325         try {
326             Session session = getSession();
327 
328             Message msg = new MimeMessage(
329                 session, new ByteArrayInputStream(msgByteArray));
330 
331             _send(session, msg);
332         }
333         catch (Exception e) {
334             throw new MailEngineException(e);
335         }
336     }
337 
338     private static void _send(Session session, Message msg)
339         throws MessagingException {
340 
341         try {
342             boolean smtpAuth = GetterUtil.getBoolean(
343                 session.getProperty("mail.smtp.auth"), false);
344             String smtpHost = session.getProperty("mail.smtp.host");
345             String user = session.getProperty("mail.smtp.user");
346             String password = session.getProperty("mail.smtp.password");
347 
348             if (smtpAuth && Validator.isNotNull(user) &&
349                 Validator.isNotNull(password)) {
350 
351                 Transport transport = session.getTransport("smtp");
352 
353                 transport.connect(smtpHost, user, password);
354                 transport.sendMessage(msg, msg.getAllRecipients());
355                 transport.close();
356             }
357             else {
358                 Transport.send(msg);
359             }
360         }
361         catch (MessagingException me) {
362             if (me.getNextException() instanceof SocketException) {
363                 if (_log.isWarnEnabled()) {
364                     _log.warn(
365                         "Failed to connect to a valid mail server. Please " +
366                             "make sure one is properly configured. " +
367                                 me.getMessage());
368                 }
369             }
370         }
371     }
372 
373     private static final String _MULTIPART_TYPE_ALTERNATIVE = "alternative";
374 
375     private static final String _MULTIPART_TYPE_MIXED = "mixed";
376 
377     private static final String _TEXT_HTML = "text/html;charset=\"UTF-8\"";
378 
379     private static final String _TEXT_PLAIN = "text/plain;charset=\"UTF-8\"";
380 
381     private static Log _log = LogFactory.getLog(MailEngine.class);
382 
383 }