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