
com.liferay.util.mail.MailEngine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.util.java Show documentation
Show all versions of com.liferay.util.java Show documentation
Contains useful utilities. Classes are loaded separately for each plugin.
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.util.mail;
import com.liferay.mail.kernel.model.Account;
import com.liferay.mail.kernel.model.FileAttachment;
import com.liferay.mail.kernel.model.MailMessage;
import com.liferay.mail.kernel.model.SMTPAccount;
import com.liferay.mail.kernel.service.MailServiceUtil;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.log.LogUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.InfrastructureUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import java.io.File;
import java.net.SocketException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.SendFailedException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
/**
* @author Brian Wing Shun Chan
* @author Brian Myunghun Kim
* @author Jorge Ferrer
* @author Neil Griffin
* @author Thiago Moreira
* @author Brett Swaim
*/
public class MailEngine {
public static Session getSession() {
return getSession(false);
}
public static Session getSession(Account account) {
Properties properties = _getProperties(account);
Session session = Session.getInstance(properties);
if (_log.isDebugEnabled()) {
session.setDebug(true);
session.getProperties().list(System.out);
}
return session;
}
public static Session getSession(boolean cache) {
Session session = null;
try {
session = MailServiceUtil.getSession();
}
catch (SystemException se) {
if (_log.isWarnEnabled()) {
_log.warn(se, se);
}
session = InfrastructureUtil.getMailSession();
}
if (_log.isDebugEnabled()) {
session.setDebug(true);
session.getProperties().list(System.out);
}
return session;
}
public static void send(byte[] bytes) throws MailEngineException {
try {
Session session = getSession();
Message message = new MimeMessage(
session, new UnsyncByteArrayInputStream(bytes));
_send(session, message, null, _BATCH_SIZE);
}
catch (Exception e) {
throw new MailEngineException(e);
}
}
public static void send(
InternetAddress from, InternetAddress to, String subject,
String body)
throws MailEngineException {
send(
from, new InternetAddress[] {to}, null, null, subject, body, false,
null, null, null);
}
public static void send(
InternetAddress from, InternetAddress to, String subject,
String body, boolean htmlFormat)
throws MailEngineException {
send(
from, new InternetAddress[] {to}, null, null, subject, body,
htmlFormat, null, null, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
InternetAddress[] bcc, InternetAddress[] bulkAddresses,
String subject, String body, boolean htmlFormat,
InternetAddress[] replyTo, String messageId, String inReplyTo)
throws MailEngineException {
send(
from, to, cc, bcc, bulkAddresses, subject, body, htmlFormat,
replyTo, messageId, inReplyTo, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
InternetAddress[] bcc, InternetAddress[] bulkAddresses,
String subject, String body, boolean htmlFormat,
InternetAddress[] replyTo, String messageId, String inReplyTo,
List fileAttachments)
throws MailEngineException {
send(
from, to, cc, bcc, bulkAddresses, subject, body, htmlFormat,
replyTo, messageId, inReplyTo, fileAttachments, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
InternetAddress[] bcc, InternetAddress[] bulkAddresses,
String subject, String body, boolean htmlFormat,
InternetAddress[] replyTo, String messageId, String inReplyTo,
List fileAttachments, SMTPAccount smtpAccount)
throws MailEngineException {
long startTime = System.currentTimeMillis();
if (_log.isDebugEnabled()) {
_log.debug("From: " + from);
_log.debug("To: " + Arrays.toString(to));
_log.debug("CC: " + Arrays.toString(cc));
_log.debug("BCC: " + Arrays.toString(bcc));
_log.debug("List Addresses: " + Arrays.toString(bulkAddresses));
_log.debug("Subject: " + subject);
_log.debug("Body: " + body);
_log.debug("HTML Format: " + htmlFormat);
_log.debug("Reply to: " + Arrays.toString(replyTo));
_log.debug("Message ID: " + messageId);
_log.debug("In Reply To: " + inReplyTo);
if ((fileAttachments != null) && _log.isDebugEnabled()) {
for (int i = 0; i < fileAttachments.size(); i++) {
FileAttachment fileAttachment = fileAttachments.get(i);
File file = fileAttachment.getFile();
if (file == null) {
continue;
}
_log.debug(
"Attachment " + i + " file " + file.getAbsolutePath() +
" and file name " + fileAttachment.getFileName());
}
}
}
try {
InternetAddressUtil.validateAddress(from);
if (ArrayUtil.isNotEmpty(to)) {
InternetAddressUtil.validateAddresses(to);
}
if (ArrayUtil.isNotEmpty(cc)) {
InternetAddressUtil.validateAddresses(cc);
}
if (ArrayUtil.isNotEmpty(bcc)) {
InternetAddressUtil.validateAddresses(bcc);
}
if (ArrayUtil.isNotEmpty(replyTo)) {
InternetAddressUtil.validateAddresses(replyTo);
}
if (ArrayUtil.isNotEmpty(bulkAddresses)) {
InternetAddressUtil.validateAddresses(bulkAddresses);
}
Session session = null;
if (smtpAccount == null) {
session = getSession();
}
else {
session = getSession(smtpAccount);
}
Message message = new LiferayMimeMessage(session);
message.addHeader(
"X-Auto-Response-Suppress", "AutoReply, DR, NDR, NRN, OOF, RN");
message.setFrom(from);
if (ArrayUtil.isNotEmpty(to)) {
message.setRecipients(Message.RecipientType.TO, to);
}
if (ArrayUtil.isNotEmpty(cc)) {
message.setRecipients(Message.RecipientType.CC, cc);
}
if (ArrayUtil.isNotEmpty(bcc)) {
message.setRecipients(Message.RecipientType.BCC, bcc);
}
subject = GetterUtil.getString(subject);
message.setSubject(_sanitizeCRLF(subject));
if (ListUtil.isNotEmpty(fileAttachments)) {
MimeMultipart rootMultipart = new MimeMultipart(
_MULTIPART_TYPE_MIXED);
MimeMultipart messageMultipart = new MimeMultipart(
_MULTIPART_TYPE_ALTERNATIVE);
MimeBodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(messageMultipart);
rootMultipart.addBodyPart(messageBodyPart);
if (htmlFormat) {
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent(body, _TEXT_HTML);
messageMultipart.addBodyPart(bodyPart);
}
else {
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setText(body);
messageMultipart.addBodyPart(bodyPart);
}
for (int i = 0; i < fileAttachments.size(); i++) {
FileAttachment fileAttachment = fileAttachments.get(i);
File file = fileAttachment.getFile();
if (file == null) {
continue;
}
MimeBodyPart mimeBodyPart = new MimeBodyPart();
DataSource dataSource = new FileDataSource(file);
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
mimeBodyPart.setDisposition(Part.ATTACHMENT);
if (fileAttachment.getFileName() != null) {
mimeBodyPart.setFileName(fileAttachment.getFileName());
}
else {
mimeBodyPart.setFileName(file.getName());
}
rootMultipart.addBodyPart(mimeBodyPart);
}
message.setContent(rootMultipart);
message.saveChanges();
}
else {
if (htmlFormat) {
message.setContent(body, _TEXT_HTML);
}
else {
message.setContent(body, _TEXT_PLAIN);
}
}
message.setSentDate(new Date());
if (ArrayUtil.isNotEmpty(replyTo)) {
message.setReplyTo(replyTo);
}
if (messageId != null) {
message.setHeader("Message-ID", _sanitizeCRLF(messageId));
}
if (inReplyTo != null) {
message.setHeader("In-Reply-To", _sanitizeCRLF(inReplyTo));
message.setHeader("References", _sanitizeCRLF(inReplyTo));
}
int batchSize = GetterUtil.getInteger(
PropsUtil.get(PropsKeys.MAIL_BATCH_SIZE), _BATCH_SIZE);
_send(session, message, bulkAddresses, batchSize);
}
catch (SendFailedException sfe) {
_log.error(sfe);
if (_isThrowsExceptionOnFailure()) {
throw new MailEngineException(sfe);
}
}
catch (Exception e) {
throw new MailEngineException(e);
}
if (_log.isDebugEnabled()) {
_log.debug(
"Sending mail takes " +
(System.currentTimeMillis() - startTime) + " ms");
}
}
public static void send(
InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
InternetAddress[] bcc, String subject, String body)
throws MailEngineException {
send(from, to, cc, bcc, subject, body, false, null, null, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
InternetAddress[] bcc, String subject, String body,
boolean htmlFormat, InternetAddress[] replyTo, String messageId,
String inReplyTo)
throws MailEngineException {
send(
from, to, cc, bcc, null, subject, body, htmlFormat, replyTo,
messageId, inReplyTo, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
String subject, String body)
throws MailEngineException {
send(from, to, cc, null, subject, body, false, null, null, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, InternetAddress[] cc,
String subject, String body, boolean htmlFormat)
throws MailEngineException {
send(from, to, cc, null, subject, body, htmlFormat, null, null, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, String subject,
String body)
throws MailEngineException {
send(from, to, null, null, subject, body, false, null, null, null);
}
public static void send(
InternetAddress from, InternetAddress[] to, String subject,
String body, boolean htmlFormat)
throws MailEngineException {
send(from, to, null, null, subject, body, htmlFormat, null, null, null);
}
public static void send(MailMessage mailMessage)
throws MailEngineException {
send(
mailMessage.getFrom(), mailMessage.getTo(), mailMessage.getCC(),
mailMessage.getBCC(), mailMessage.getBulkAddresses(),
mailMessage.getSubject(), mailMessage.getBody(),
mailMessage.isHTMLFormat(), mailMessage.getReplyTo(),
mailMessage.getMessageId(), mailMessage.getInReplyTo(),
mailMessage.getFileAttachments(), mailMessage.getSMTPAccount());
}
public static void send(String from, String to, String subject, String body)
throws MailEngineException {
try {
send(
new InternetAddress(from), new InternetAddress(to), subject,
body);
}
catch (AddressException ae) {
throw new MailEngineException(ae);
}
}
private static Address[] _getBatchAddresses(
Address[] addresses, int index, int batchSize) {
if ((batchSize == _BATCH_SIZE) && (index == 0)) {
return addresses;
}
else if (batchSize == _BATCH_SIZE) {
return null;
}
int start = index * batchSize;
if (start > addresses.length) {
return null;
}
int end = ((index + 1) * batchSize);
if (end > addresses.length) {
end = addresses.length;
}
return ArrayUtil.subset(addresses, start, end);
}
private static Properties _getProperties(Account account) {
Properties properties = new Properties();
String protocol = account.getProtocol();
properties.setProperty("mail.transport.protocol", protocol);
properties.setProperty("mail." + protocol + ".host", account.getHost());
properties.setProperty(
"mail." + protocol + ".port", String.valueOf(account.getPort()));
if (account.isRequiresAuthentication()) {
properties.setProperty("mail." + protocol + ".auth", "true");
properties.setProperty(
"mail." + protocol + ".user", account.getUser());
properties.setProperty(
"mail." + protocol + ".password", account.getPassword());
}
if (account.isSecure()) {
properties.setProperty(
"mail." + protocol + ".socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
properties.setProperty(
"mail." + protocol + ".socketFactory.fallback", "false");
properties.setProperty(
"mail." + protocol + ".socketFactory.port",
String.valueOf(account.getPort()));
}
return properties;
}
private static String _getSMTPProperty(Session session, String suffix) {
String protocol = GetterUtil.getString(
session.getProperty("mail.transport.protocol"));
if (protocol.equals(Account.PROTOCOL_SMTPS)) {
return session.getProperty("mail.smtps." + suffix);
}
else {
return session.getProperty("mail.smtp." + suffix);
}
}
private static boolean _isThrowsExceptionOnFailure() {
return GetterUtil.getBoolean(
PropsUtil.get(PropsKeys.MAIL_THROWS_EXCEPTION_ON_FAILURE));
}
private static String _sanitizeCRLF(String text) {
return StringUtil.replace(
text, new char[] {CharPool.NEW_LINE, CharPool.RETURN},
new char[] {CharPool.SPACE, CharPool.SPACE});
}
private static void _send(
Session session, Message message, InternetAddress[] bulkAddresses,
int batchSize)
throws MailEngineException {
try {
boolean smtpAuth = GetterUtil.getBoolean(
_getSMTPProperty(session, "auth"), false);
String smtpHost = _getSMTPProperty(session, "host");
int smtpPort = GetterUtil.getInteger(
_getSMTPProperty(session, "port"), Account.PORT_SMTP);
String user = _getSMTPProperty(session, "user");
String password = _getSMTPProperty(session, "password");
if (smtpAuth && Validator.isNotNull(user) &&
Validator.isNotNull(password)) {
String protocol = GetterUtil.getString(
session.getProperty("mail.transport.protocol"),
Account.PROTOCOL_SMTP);
Transport transport = session.getTransport(protocol);
transport.connect(smtpHost, smtpPort, user, password);
Address[] addresses = null;
if (ArrayUtil.isNotEmpty(bulkAddresses)) {
addresses = bulkAddresses;
}
else {
addresses = message.getAllRecipients();
}
for (int i = 0;; i++) {
Address[] batchAddresses = _getBatchAddresses(
addresses, i, batchSize);
if (ArrayUtil.isEmpty(batchAddresses)) {
break;
}
transport.sendMessage(message, batchAddresses);
}
transport.close();
}
else {
if (ArrayUtil.isNotEmpty(bulkAddresses)) {
int curBatch = 0;
Address[] portion = _getBatchAddresses(
bulkAddresses, curBatch, batchSize);
while (ArrayUtil.isNotEmpty(portion)) {
Transport.send(message, portion);
curBatch++;
portion = _getBatchAddresses(
bulkAddresses, curBatch, batchSize);
}
}
else {
Transport.send(message);
}
}
}
catch (MessagingException me) {
if (me.getNextException() instanceof SocketException) {
if (_log.isWarnEnabled()) {
_log.warn(
"Failed to connect to a valid mail server. Please " +
"make sure one is properly configured. " +
me.getMessage());
}
}
else {
LogUtil.log(_log, me);
}
if (_isThrowsExceptionOnFailure()) {
throw new MailEngineException(me);
}
}
}
private static final int _BATCH_SIZE = 0;
private static final String _MULTIPART_TYPE_ALTERNATIVE = "alternative";
private static final String _MULTIPART_TYPE_MIXED = "mixed";
private static final String _TEXT_HTML = "text/html;charset=\"UTF-8\"";
private static final String _TEXT_PLAIN = "text/plain;charset=\"UTF-8\"";
private static final Log _log = LogFactoryUtil.getLog(MailEngine.class);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy