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