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