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