1
19
20 package com.liferay.util.mail;
21
22 import com.liferay.mail.service.MailServiceUtil;
23 import com.liferay.portal.SystemException;
24 import com.liferay.portal.kernel.log.Log;
25 import com.liferay.portal.kernel.log.LogFactoryUtil;
26 import com.liferay.portal.kernel.mail.Account;
27 import com.liferay.portal.kernel.mail.MailMessage;
28 import com.liferay.portal.kernel.mail.SMTPAccount;
29 import com.liferay.portal.kernel.util.GetterUtil;
30 import com.liferay.portal.kernel.util.InfrastructureUtil;
31 import com.liferay.portal.kernel.util.Validator;
32
33 import java.io.ByteArrayInputStream;
34 import java.io.File;
35
36 import java.net.SocketException;
37
38 import java.util.Date;
39 import java.util.Properties;
40
41 import javax.activation.DataHandler;
42 import javax.activation.DataSource;
43 import javax.activation.FileDataSource;
44
45 import javax.mail.Message;
46 import javax.mail.MessagingException;
47 import javax.mail.Part;
48 import javax.mail.SendFailedException;
49 import javax.mail.Session;
50 import javax.mail.Transport;
51 import javax.mail.internet.AddressException;
52 import javax.mail.internet.InternetAddress;
53 import javax.mail.internet.MimeBodyPart;
54 import javax.mail.internet.MimeMessage;
55 import javax.mail.internet.MimeMultipart;
56
57 import org.apache.commons.lang.time.StopWatch;
58
59
70 public class MailEngine {
71
72 public static Session getSession() {
73 return getSession(false);
74 }
75
76 public static Session getSession(boolean cache) {
77 Session session = null;
78
79 try {
80 session = MailServiceUtil.getSession();
81 }
82 catch (SystemException se) {
83 if (_log.isWarnEnabled()) {
84 _log.warn(se, se);
85 }
86
87 session = InfrastructureUtil.getMailSession();
88 }
89
90 if (_log.isDebugEnabled()) {
91 session.setDebug(true);
92
93 session.getProperties().list(System.out);
94 }
95
96 return session;
97 }
98
99 public static Session getSession(Account account) {
100 Properties properties = _getProperties(account);
101
102 Session session = Session.getInstance(properties);
103
104 if (_log.isDebugEnabled()) {
105 session.setDebug(true);
106
107 session.getProperties().list(System.out);
108 }
109
110 return session;
111 }
112
113 public static void send(MailMessage mailMessage)
114 throws MailEngineException {
115
116 send(
117 mailMessage.getFrom(), mailMessage.getTo(), mailMessage.getCC(),
118 mailMessage.getBCC(), mailMessage.getBulkAddresses(),
119 mailMessage.getSubject(), mailMessage.getBody(),
120 mailMessage.isHTMLFormat(), mailMessage.getReplyTo(),
121 mailMessage.getMessageId(), mailMessage.getInReplyTo(),
122 mailMessage.getAttachments(), mailMessage.getSMTPAccount());
123 }
124
125 public static void send(String from, String to, String subject, String body)
126 throws MailEngineException {
127
128 try {
129 send(
130 new InternetAddress(from), new InternetAddress(to), subject,
131 body);
132 }
133 catch (AddressException ae) {
134 throw new MailEngineException(ae);
135 }
136 }
137
138 public static void send(
139 InternetAddress from, InternetAddress to,
140 String subject, String body)
141 throws MailEngineException {
142
143 send(
144 from, new InternetAddress[] {to}, null, null, subject, body, false,
145 null, null, null);
146 }
147
148 public static void send(
149 InternetAddress from, InternetAddress to, String subject,
150 String body, boolean htmlFormat)
151 throws MailEngineException {
152
153 send(
154 from, new InternetAddress[] {to}, null, null, subject, body,
155 htmlFormat, null, null, null);
156 }
157
158 public static void send(
159 InternetAddress from, InternetAddress[] to, String subject,
160 String body)
161 throws MailEngineException {
162
163 send(from, to, null, null, subject, body, false, null, null, null);
164 }
165
166 public static void send(
167 InternetAddress from, InternetAddress[] to, String subject,
168 String body, boolean htmlFormat)
169 throws MailEngineException {
170
171 send(from, to, null, null, subject, body, htmlFormat, null, null, null);
172 }
173
174 public static void send(
175 InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
176 String subject, String body)
177 throws MailEngineException {
178
179 send(from, to, cc, null, subject, body, false, null, null, null);
180 }
181
182 public static void send(
183 InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
184 String subject, String body, boolean htmlFormat)
185 throws MailEngineException {
186
187 send(from, to, cc, null, subject, body, htmlFormat, null, null, null);
188 }
189
190 public static void send(
191 InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
192 InternetAddress[] bcc, String subject, String body)
193 throws MailEngineException {
194
195 send(from, to, cc, bcc, subject, body, false, null, null, null);
196 }
197
198 public static void send(
199 InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
200 InternetAddress[] bcc, String subject, String body,
201 boolean htmlFormat, InternetAddress[] replyTo, String messageId,
202 String inReplyTo)
203 throws MailEngineException {
204
205 send(
206 from, to, cc, bcc, null, subject, body, htmlFormat, replyTo,
207 messageId, inReplyTo, null);
208 }
209
210 public static void send(
211 InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
212 InternetAddress[] bcc, InternetAddress[] bulkAddresses,
213 String subject, String body, boolean htmlFormat,
214 InternetAddress[] replyTo, String messageId, String inReplyTo)
215 throws MailEngineException {
216
217 send(
218 from, to, cc, bcc, bulkAddresses, subject, body, htmlFormat,
219 replyTo, messageId, inReplyTo, null);
220 }
221
222 public static void send(
223 InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
224 InternetAddress[] bcc, InternetAddress[] bulkAddresses,
225 String subject, String body, boolean htmlFormat,
226 InternetAddress[] replyTo, String messageId, String inReplyTo,
227 File[] attachments)
228 throws MailEngineException {
229
230 send(
231 from, to, cc, bcc, bulkAddresses, subject, body, htmlFormat,
232 replyTo, messageId, inReplyTo, attachments, null);
233 }
234
235 public static void send(
236 InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
237 InternetAddress[] bcc, InternetAddress[] bulkAddresses,
238 String subject, String body, boolean htmlFormat,
239 InternetAddress[] replyTo, String messageId, String inReplyTo,
240 File[] attachments, SMTPAccount smtpAccount)
241 throws MailEngineException {
242
243 StopWatch stopWatch = null;
244
245 if (_log.isDebugEnabled()) {
246 stopWatch = new StopWatch();
247
248 stopWatch.start();
249
250 _log.debug("From: " + from);
251 _log.debug("To: " + to);
252 _log.debug("CC: " + cc);
253 _log.debug("BCC: " + bcc);
254 _log.debug("List Addresses: " + bulkAddresses);
255 _log.debug("Subject: " + subject);
256 _log.debug("Body: " + body);
257 _log.debug("HTML Format: " + htmlFormat);
258 _log.debug("Reply to: " + replyTo);
259 _log.debug("Message ID: " + messageId);
260 _log.debug("In Reply To: " + inReplyTo);
261
262 if (attachments != null) {
263 for (int i = 0; i < attachments.length; i++) {
264 File attachment = attachments[i];
265
266 if (attachment != null) {
267 String path = attachment.getAbsolutePath();
268
269 _log.debug("Attachment #" + (i + 1) + ": " + path);
270 }
271 }
272 }
273 }
274
275 try {
276 Session session = null;
277
278 if (smtpAccount == null) {
279 session = getSession();
280 }
281 else {
282 session = getSession(smtpAccount);
283 }
284
285 Message msg = new LiferayMimeMessage(session);
286
287 msg.setFrom(from);
288 msg.setRecipients(Message.RecipientType.TO, to);
289
290 if (cc != null) {
291 msg.setRecipients(Message.RecipientType.CC, cc);
292 }
293
294 if (bcc != null) {
295 msg.setRecipients(Message.RecipientType.BCC, bcc);
296 }
297
298 msg.setSubject(subject);
299
300 if ((attachments != null) && (attachments.length > 0)) {
301 MimeMultipart rootMultipart = new MimeMultipart(
302 _MULTIPART_TYPE_MIXED);
303
304 MimeMultipart messageMultipart = new MimeMultipart(
305 _MULTIPART_TYPE_ALTERNATIVE);
306
307 MimeBodyPart messageBodyPart = new MimeBodyPart();
308
309 messageBodyPart.setContent(messageMultipart);
310
311 rootMultipart.addBodyPart(messageBodyPart);
312
313 if (htmlFormat) {
314 MimeBodyPart bodyPart = new MimeBodyPart();
315
316 bodyPart.setContent(body, _TEXT_HTML);
317
318 messageMultipart.addBodyPart(bodyPart);
319 }
320 else {
321 MimeBodyPart bodyPart = new MimeBodyPart();
322
323 bodyPart.setText(body);
324
325 messageMultipart.addBodyPart(bodyPart);
326 }
327
328 for (int i = 0; i < attachments.length; i++) {
329 File attachment = attachments[i];
330
331 if (attachment != null) {
332 MimeBodyPart bodyPart = new MimeBodyPart();
333
334 DataSource source = new FileDataSource(attachment);
335
336 bodyPart.setDisposition(Part.ATTACHMENT);
337 bodyPart.setDataHandler(new DataHandler(source));
338 bodyPart.setFileName(attachment.getName());
339
340 rootMultipart.addBodyPart(bodyPart);
341 }
342 }
343
344 msg.setContent(rootMultipart);
345
346 msg.saveChanges();
347 }
348 else {
349 if (htmlFormat) {
350 msg.setContent(body, _TEXT_HTML);
351 }
352 else {
353 msg.setContent(body, _TEXT_PLAIN);
354 }
355 }
356
357 msg.setSentDate(new Date());
358
359 if (replyTo != null) {
360 msg.setReplyTo(replyTo);
361 }
362
363 if (messageId != null) {
364 msg.setHeader("Message-ID", messageId);
365 }
366
367 if (inReplyTo != null) {
368 msg.setHeader("In-Reply-To", inReplyTo);
369 msg.setHeader("References", inReplyTo);
370 }
371
372 _send(session, msg, bulkAddresses);
373 }
374 catch (SendFailedException sfe) {
375 _log.error(sfe);
376 }
377 catch (Exception e) {
378 throw new MailEngineException(e);
379 }
380
381 if (_log.isDebugEnabled()) {
382 _log.debug("Sending mail takes " + stopWatch.getTime() + " ms");
383 }
384 }
385
386 public static void send(byte[] msgByteArray) throws MailEngineException {
387 try {
388 Session session = getSession();
389
390 Message msg = new MimeMessage(
391 session, new ByteArrayInputStream(msgByteArray));
392
393 _send(session, msg, null);
394 }
395 catch (Exception e) {
396 throw new MailEngineException(e);
397 }
398 }
399
400 private static Properties _getProperties(Account account) {
401 Properties properties = new Properties();
402
403 String protocol = account.getProtocol();
404
405 properties.setProperty("mail.transport.protocol", protocol);
406 properties.setProperty("mail." + protocol + ".host", account.getHost());
407 properties.setProperty(
408 "mail." + protocol + ".port", String.valueOf(account.getPort()));
409
410 if (account.isRequiresAuthentication()) {
411 properties.setProperty("mail." + protocol + ".auth", "true");
412 properties.setProperty(
413 "mail." + protocol + ".user", account.getUser());
414 properties.setProperty(
415 "mail." + protocol + ".password", account.getPassword());
416 }
417
418 if (account.isSecure()) {
419 properties.setProperty(
420 "mail." + protocol + ".socketFactory.class",
421 "javax.net.ssl.SSLSocketFactory");
422 properties.setProperty(
423 "mail." + protocol + ".socketFactory.fallback", "false");
424 properties.setProperty(
425 "mail." + protocol + ".socketFactory.port",
426 String.valueOf(account.getPort()));
427 }
428
429 return properties;
430 }
431
432 private static String _getSMTPProperty(Session session, String suffix) {
433 String protocol = GetterUtil.getString(
434 session.getProperty("mail.transport.protocol"));
435
436 if (protocol.equals(Account.PROTOCOL_SMTPS)) {
437 return session.getProperty("mail.smtps." + suffix);
438 }
439 else {
440 return session.getProperty("mail.smtp." + suffix);
441 }
442 }
443
444 private static void _send(
445 Session session, Message msg, InternetAddress[] bulkAddresses) {
446
447 try {
448 boolean smtpAuth = GetterUtil.getBoolean(
449 _getSMTPProperty(session, "auth"), false);
450 String smtpHost = _getSMTPProperty(session, "host");
451 int smtpPort = GetterUtil.getInteger(
452 _getSMTPProperty(session, "port"), Account.PORT_SMTP);
453 String user = _getSMTPProperty(session, "user");
454 String password = _getSMTPProperty(session, "password");
455
456 if (smtpAuth && Validator.isNotNull(user) &&
457 Validator.isNotNull(password)) {
458
459 String protocol = GetterUtil.getString(
460 session.getProperty("mail.transport.protocol"),
461 Account.PROTOCOL_SMTP);
462
463 Transport transport = session.getTransport(protocol);
464
465 transport.connect(smtpHost, smtpPort, user, password);
466
467 if ((bulkAddresses != null) && (bulkAddresses.length > 0)) {
468 transport.sendMessage(msg, bulkAddresses);
469 }
470 else {
471 transport.sendMessage(msg, msg.getAllRecipients());
472 }
473
474 transport.close();
475 }
476 else {
477 if ((bulkAddresses != null) && (bulkAddresses.length > 0)) {
478 Transport.send(msg, bulkAddresses);
479 }
480 else {
481 Transport.send(msg);
482 }
483 }
484 }
485 catch (MessagingException me) {
486 if (me.getNextException() instanceof SocketException) {
487 if (_log.isWarnEnabled()) {
488 _log.warn(
489 "Failed to connect to a valid mail server. Please " +
490 "make sure one is properly configured. " +
491 me.getMessage());
492 }
493 }
494 }
495 }
496
497 private static final String _MULTIPART_TYPE_ALTERNATIVE = "alternative";
498
499 private static final String _MULTIPART_TYPE_MIXED = "mixed";
500
501 private static final String _TEXT_HTML = "text/html;charset=\"UTF-8\"";
502
503 private static final String _TEXT_PLAIN = "text/plain;charset=\"UTF-8\"";
504
505 private static Log _log = LogFactoryUtil.getLog(MailEngine.class);
506
507 }