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