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