org.ow2.petals.bc.mail.MailUtil Maven / Gradle / Ivy
/**
* Copyright (c) 2007-2012 EBM WebSourcing, 2012-2023 Linagora
*
* This program/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 program/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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program/library; If not, see http://www.gnu.org/licenses/
* for the GNU Lesser General Public License version 2.1.
*/
package org.ow2.petals.bc.mail;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import org.ow2.petals.bc.mail.exception.MissingElementException;
import org.ow2.petals.bc.mail.service.consume.ConsumeDescriptor;
import org.ow2.petals.bc.mail.service.provide.ProvideDescriptor;
import org.ow2.petals.component.framework.api.configuration.SuConfigurationParameters;
import org.ow2.petals.component.framework.api.message.Exchange;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import com.ebmwebsourcing.easycommons.lang.StringHelper;
import com.ebmwebsourcing.easycommons.xml.XMLHelper;
/**
* @author Mathieu CARROLLE - EBM WebSourcing
*/
public class MailUtil {
private MailUtil() {
// Private constructor because it's an utility class
}
/**
* Extract mail session properties from the service unit for Provide node
*
* @param extensions
* extensions associated to the given message exchange
* @return {@link ProvideDescriptor}
* @throws MessagingException
* @throws MissingElementException
* @throws AddressException
*/
public static ProvideDescriptor build(final SuConfigurationParameters extensions)
throws MessagingException, MissingElementException, AddressException {
final ProvideDescriptor provideDescriptor = new ProvideDescriptor();
// Retrieve user and password
provideDescriptor.setUsername(extensions.get(MailConstants.USER_PATHELEMENT));
provideDescriptor.setPassword(extensions.get(MailConstants.PASSWORD_PATHELEMENT));
// TLS support
final String tlsEnabledStr = extensions.get(MailConstants.STARTTLS_PATHELEMENT);
if (tlsEnabledStr != null && !tlsEnabledStr.trim().isEmpty()) {
provideDescriptor.setStartTlsEnabled(Boolean.parseBoolean(tlsEnabledStr));
}
// Retrieve protocol (smtp,..)
provideDescriptor.setScheme(extensions.get(MailConstants.SCHEME_PATHELEMENT));
// Retrieve host and port
provideDescriptor.setHostname(extensions.get(MailConstants.HOST_PATHELEMENT));
provideDescriptor.setPort(extensions.get(MailConstants.PORT_PATHELEMENT));
final String host;
if ((host = extensions.get(MailConstants.HELO_HOST_PATHELEMENT)) != null) {
provideDescriptor.setHeloHost(host);
}
// Retrieve "from" addresses
provideDescriptor.setFromAddress(extensions.get(MailConstants.FROM_PATHELEMENT));
// Retrieve "replyTo" addresses
provideDescriptor.setReplyAddress(extensions.get(MailConstants.REPLY_PATHELEMENT));
provideDescriptor.setToAddress(InternetAddress.parse(extensions.get(MailConstants.TO_PATHELEMENT)));
final String ccAddresses = extensions.get(MailConstants.CC_PATHELEMENT);
if (ccAddresses != null) {
provideDescriptor.setCcAddress(InternetAddress.parse(ccAddresses.trim()));
}
final String bccAddresses = extensions.get(MailConstants.BCC_PATHELEMENT);
if (bccAddresses != null) {
provideDescriptor.setBccAddress(InternetAddress.parse(bccAddresses.trim()));
}
// Retrieve "subject"
provideDescriptor.setSubject( fixMailSubject( extensions.get(MailConstants.SUBJECT_PATHELEMENT)));
// retrieve send mode
provideDescriptor.setSendMode(extensions.get(MailConstants.SEND_MODE_PATHELEMENT));
// retrieve content type
provideDescriptor.setContentType(extensions.get(MailConstants.CONTENTTYPE_PATHELEMENT));
// Check obligatory properties
checkProperties(provideDescriptor);
return provideDescriptor;
}
/**
* Extract mail session properties from the service unit for Consume node
*
* @param extensions
* extensions associated to the given message exchange
*
* @return {@link ConsumeDescriptor}
* @throws MessagingException
* @throws MissingElementException
*/
public static ConsumeDescriptor buildConsumeDescriptor(final SuConfigurationParameters extensions)
throws MessagingException, MissingElementException {
final ConsumeDescriptor sessionDescriptor = new ConsumeDescriptor();
// Retrieve user and password
sessionDescriptor.setUsername(extensions.get(MailConstants.USER_PATHELEMENT, null));
sessionDescriptor.setPassword(extensions.get(MailConstants.PASSWORD_PATHELEMENT, null));
// Retrieve protocol (smtp, imap, pop3)
final String scheme = extensions.get(MailConstants.SCHEME_PATHELEMENT);
sessionDescriptor.setScheme(scheme);
// Retrieve host and port
sessionDescriptor.setHostname(extensions.get(MailConstants.HOST_PATHELEMENT));
final String portStr = extensions.get(MailConstants.PORT_PATHELEMENT);
if (StringHelper.isNullOrEmpty(portStr)) {
if (MailConstants.MAIL_SCHEME_POP3.equals(scheme)) {
sessionDescriptor
.setPort(extensions.get(MailConstants.PORT_PATHELEMENT, MailConstants.MAIL_POP3_PORT_DEFAULT));
} else if (MailConstants.MAIL_SCHEME_IMAP.equals(scheme)) {
sessionDescriptor
.setPort(extensions.get(MailConstants.PORT_PATHELEMENT, MailConstants.MAIL_IMAP_PORT_DEFAULT));
}
} else {
sessionDescriptor.setPort(portStr);
}
// Retrieve if STARTTLS is enabled
final String startTlsEnabled = extensions.get(MailConstants.STARTTLS_PATHELEMENT);
if (StringHelper.isNullOrEmpty(startTlsEnabled)) {
sessionDescriptor.setStartTlsEnabled(false);
} else {
sessionDescriptor.setStartTlsEnabled(Boolean.parseBoolean(startTlsEnabled));
}
// Retrieve if SSL is enabled
final String sslEnabled = extensions.get(MailConstants.SSL_ENABLED_PATHELEMENT);
if (StringHelper.isNullOrEmpty(sslEnabled)) {
sessionDescriptor.setSslEnabled(false);
} else {
sessionDescriptor.setSslEnabled(Boolean.parseBoolean(sslEnabled));
}
// Retrieve if SSL is enabled
final String trustAllCertificatesEnabled = extensions.get(MailConstants.TRUST_ALL_CERTIFICATES_PATHELEMENT);
if (StringHelper.isNullOrEmpty(trustAllCertificatesEnabled)) {
sessionDescriptor.setTrustAllCertificatesEnabled(false);
} else {
sessionDescriptor.setTrustAllCertificatesEnabled(Boolean.parseBoolean(trustAllCertificatesEnabled));
}
// Retrieve period parameter ("checking for new mail" interval)
sessionDescriptor.setPeriod(extensions.get(MailConstants.PERIOD_QUERYELEMENT,
MailConstants.PERIOD_DEFAULT));
// Retrieve folder parameter (the folder to search for new mails)
sessionDescriptor.setFolder(extensions.get(MailConstants.FOLDER_QUERYELEMENT,
MailConstants.FOLDER_DEFAULT));
// Retrieve the Flag to set on read messages
final String expunge = extensions.get(MailConstants.EXPUNGE_PATHELEMENT);
if (StringHelper.isNullOrEmpty(expunge)) {
sessionDescriptor.setDelete(true);
} else {
sessionDescriptor.setDelete(Boolean.getBoolean(expunge));
}
// Check obligatory properties
checkProperties(sessionDescriptor);
return sessionDescriptor;
}
/**
* Build a descriptor by extracting all information from the associated JBI message payload.
*
* NOTE:
* Used when the component supplies its own service
*
*
* @param node
* the root node of the messsage payload
* @throws MissingElementException
* @throws MessagingException
* @throws AddressException
* @throws DOMException
*
*/
public static ProvideDescriptor buildFromPayload(final Node node) throws MissingElementException,
MessagingException, AddressException, DOMException {
final ProvideDescriptor sessionDescriptor = new ProvideDescriptor();
// find the send/mail xml element
if (node == null || !node.getLocalName().equalsIgnoreCase("mail")) {
throw new MissingElementException("mail");
}
// Set the host address
final Node hostNode = XMLHelper.findChild(node, null, MailConstants.HOST_PATHELEMENT, false);
if (hostNode != null) {
sessionDescriptor.setHostname(hostNode.getTextContent());
}
// set the scheme
final Node schemeNode = XMLHelper.findChild(node, null, MailConstants.SCHEME_PATHELEMENT,
false);
if (schemeNode != null) {
sessionDescriptor.setScheme(schemeNode.getTextContent());
}
sessionDescriptor.setScheme(MailConstants.MAIL_SCHEME_SMTP);
// set smtp port
final Node portNode = XMLHelper.findChild(node, null, MailConstants.PORT_PATHELEMENT, false);
final String port;
if (portNode != null && (port = portNode.getTextContent()) != null) {
sessionDescriptor.setPort(port);
} else {
sessionDescriptor.setPort(null);
}
// set smtp user name
final Node userNode = XMLHelper.findChild(node, null, MailConstants.USER_PATHELEMENT, false);
if (userNode != null) {
sessionDescriptor.setUsername(userNode.getTextContent());
}
// set smtp password
final Node pwdNode = XMLHelper.findChild(node, null, MailConstants.PASSWORD_PATHELEMENT,
false);
if (pwdNode != null) {
sessionDescriptor.setPassword(pwdNode.getTextContent());
}
// TLS support
final Node tlsEnabledNode = XMLHelper.findChild(node, null, MailConstants.STARTTLS_PATHELEMENT, false);
if (tlsEnabledNode != null) {
final String tlsEnabledStr = tlsEnabledNode.getTextContent();
if (tlsEnabledStr != null && !tlsEnabledStr.trim().isEmpty()) {
sessionDescriptor.setStartTlsEnabled(Boolean.parseBoolean(tlsEnabledStr));
}
}
// set smtp SEND MODE
final Node sendModeNode = XMLHelper.findChild(node, null, MailConstants.SEND_MODE_PATHELEMENT, false);
final String sendMode;
if (sendModeNode != null && (sendMode = sendModeNode.getTextContent()) != null) {
sessionDescriptor.setSendMode(sendMode);
} else {
sessionDescriptor.setSendMode(null);
}
// Set the from address
final Node fromNode = XMLHelper.findChild(node, null, MailConstants.FROM_PATHELEMENT, false);
if (fromNode != null) {
sessionDescriptor.setFromAddress(fromNode.getTextContent());
}
// Set the reply address
final Node replyNode = XMLHelper
.findChild(node, null, MailConstants.REPLY_PATHELEMENT, false);
if (replyNode != null) {
sessionDescriptor.setReplyAddress(replyNode.getTextContent());
}
// Build the recipient address "To"
final Node toNode = XMLHelper.findChild(node, null, MailConstants.TO_PATHELEMENT, false);
if (toNode != null) {
sessionDescriptor.setToAddress(InternetAddress.parse(toNode.getTextContent()));
}
// Build the recipient address "Cc"
final Node ccNode = XMLHelper.findChild(node, null, MailConstants.CC_PATHELEMENT, false);
if (ccNode != null) {
sessionDescriptor.setCcAddress(InternetAddress.parse(ccNode.getTextContent()));
}
// Build the recipient address "Bcc"
final Node bccNode = XMLHelper.findChild(node, null, MailConstants.BCC_PATHELEMENT, false);
if (bccNode != null) {
sessionDescriptor.setBccAddress(InternetAddress.parse(bccNode.getTextContent()));
}
// set the content type
final Node contentTypeNode = XMLHelper.findChild(node, null, MailConstants.CONTENTTYPE_PATHELEMENT, false);
final String contentType;
if (contentTypeNode != null && (contentType = contentTypeNode.getTextContent()) != null) {
sessionDescriptor.setContentType(contentType);
} else {
sessionDescriptor.setContentType(null);
}
// Set the subject
final Node subjectNode = XMLHelper.findChild(node, null, MailConstants.SUBJECT_PATHELEMENT,
false);
if (subjectNode != null) {
sessionDescriptor.setSubject( fixMailSubject( subjectNode.getTextContent()));
}
final Node heloHostNode = XMLHelper.findChild(node, null, MailConstants.HELO_HOST_PATHELEMENT,
false);
if (heloHostNode != null) {
sessionDescriptor.setHeloHost(heloHostNode.getTextContent());
}
checkProperties(sessionDescriptor);
return sessionDescriptor;
}
public static String extractMailBodyFromPayload(final Node node) throws MissingElementException,
MessagingException {
// Set the body
final Node bodyNode = XMLHelper.findChild(node, null, MailConstants.BODY_PATHELEMENT, false);
if (bodyNode == null) {
throw new MissingElementException(MailConstants.BODY_PATHELEMENT);
} else {
return XMLHelper.toString(bodyNode.getChildNodes());
}
}
/**
* Retrieve mail session properties from Normalized message properties.
*
* NOTE:
* Used when the component supplies its own service
*
*
* @param exchange
* the message exchange used to extract properties
* @param node
* the root node of the message payload to extract mail's body
* @return {@link ProvideDescriptor}
* @throws MissingElementException
* @throws MessagingException
* @throws AddressException
*/
public static ProvideDescriptor buildFromProperties(final Exchange exchange, final Node node)
throws MissingElementException, MessagingException, AddressException {
final ProvideDescriptor sessionDescriptor = new ProvideDescriptor();
final NormalizedMessage inNormalizedMessage = exchange.getInMessage();
if (node == null || !node.getLocalName().equalsIgnoreCase("mail")) {
throw new MissingElementException("mail");
}
// retrieve smtp host
final String host = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.HOST_QNAME.toString());
sessionDescriptor.setHostname(host);
// retrieve smtp port
String port = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.PORT_QNAME.toString());
sessionDescriptor.setPort(port);
// retrieve smtp username
final String username = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.USER_QNAME.toString());
sessionDescriptor.setUsername(username);
// retrieve smtp password
final String password = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.PASSWORD_QNAME.toString());
sessionDescriptor.setPassword(password);
// TLS support
final String tlsEnabledStr = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.STARTTLS_QNAME.toString());
if (tlsEnabledStr != null && !tlsEnabledStr.trim().isEmpty()) {
sessionDescriptor.setStartTlsEnabled(Boolean.parseBoolean(tlsEnabledStr));
}
// retrieve smtp send mode
final String sendMode = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.SENDMODE_QNAME.toString());
sessionDescriptor.setSendMode(sendMode);
// set scheme mode
final String scheme = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.SCHEME_QNAME.toString());
sessionDescriptor.setScheme(scheme);
// set smtp helo
final String heloHost = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.HELOHOST_QNAME.toString());
sessionDescriptor.setHeloHost(heloHost);
// Retrieve "from" address
final String fromAddress = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.FROM_QNAME.toString());
sessionDescriptor.setFromAddress(fromAddress);
// Retrieve "to" Address
final String toAddress = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.TO_QNAME.toString());
if (toAddress != null) {
sessionDescriptor.setToAddress(InternetAddress.parse(toAddress));
}
// Retrieve "cc" Address
final String ccAddress = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.CC_QNAME.toString());
if (ccAddress != null) {
sessionDescriptor.setCcAddress(InternetAddress.parse(ccAddress));
}
// Retrieve "bcc" Address
final String bccAddress = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.BCC_QNAME.toString());
if (bccAddress != null) {
sessionDescriptor.setBccAddress(InternetAddress.parse(bccAddress));
}
// Retrieve "replyTo" address
final String replyAddress = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.REPLY_TO_QNAME.toString());
sessionDescriptor.setReplyAddress(replyAddress);
// retrieve content-type
final String contentType = (String) inNormalizedMessage
.getProperty(MailConstants.MailWSAddressing.CONTENTTYPE_QNAME.toString());
sessionDescriptor.setContentType(contentType);
// Retrieve "subject"
String subject = (String) inNormalizedMessage.getProperty(MailConstants.MailWSAddressing.ACTION_QNAME.toString());
subject = fixMailSubject( subject );
sessionDescriptor.setSubject(subject);
// Check mandatory properties
checkProperties(sessionDescriptor);
return sessionDescriptor;
}
/**
* Check if the ws addressing properties are present
*
* @param exchange
* @return
*/
public static boolean checkWsaProperties(final Exchange exchange) {
// Retrieve "from" address
final String fromAddress = (String) exchange.getInMessage().getProperty(
MailConstants.MailWSAddressing.FROM_QNAME.toString());
// Retrieve "to" Address
final String toAddress = (String) exchange.getInMessage().getProperty(
MailConstants.MailWSAddressing.TO_QNAME.toString());
if (!StringHelper.isNullOrEmpty(fromAddress) || !StringHelper.isNullOrEmpty(toAddress)) {
return true;
}
return false;
}
/**
* Check the properties extracted from the address URI. Only hostname is
* obligatory for all schemes. Only SMTP, POP3 and IMAP schemes are
* supported. "toAddress" is need for SMTP scheme.
*
* @param provideDescriptor
* @throws MessagingException
* @throws MissingElementException
*/
public static void checkProperties(final ProvideDescriptor provideDescriptor)
throws MessagingException, MissingElementException {
final String msg;
if (StringHelper.isNullOrEmpty(provideDescriptor.getHostname())) {
throw new MissingElementException(MailConstants.HOST_PATHELEMENT);
}
try {
new InternetAddress(provideDescriptor.getFromAddress()).validate();
} catch (final Exception e) {
throw new MissingElementException(MailConstants.FROM_PATHELEMENT);
}
try {
for (final InternetAddress mailAddress : provideDescriptor.getToAddress()) {
mailAddress.validate();
}
} catch (final Exception e) {
throw new MissingElementException(MailConstants.TO_PATHELEMENT);
}
if (!MailConstants.MAIL_SCHEME_SMTP.equalsIgnoreCase(provideDescriptor.getScheme())) {
msg = "The specified scheme isn't supported : " + provideDescriptor.getScheme();
throw new MessagingException(msg);
}
}
/**
* Check the properties extracted from the address URI. Only hostname is
* obligatory for all schemes. Only SMTP, POP3 and IMAP schemes are
* supported. "toAddress" is need for SMTP scheme.
*
* @param consumeDescriptor
* @throws MissingElementException
* @throws MessagingException
* if a checking step failed
*/
protected static void checkProperties(final ConsumeDescriptor consumeDescriptor)
throws MessagingException, MissingElementException {
if (StringHelper.isNullOrEmpty(consumeDescriptor.getHostname())) {
throw new MissingElementException(MailConstants.HOST_PATHELEMENT);
}
if (!(MailConstants.MAIL_SCHEME_IMAP.equalsIgnoreCase(consumeDescriptor.getScheme()) || MailConstants.MAIL_SCHEME_POP3
.equalsIgnoreCase(consumeDescriptor.getScheme()))) {
throw new MessagingException("The specified scheme isn't supported : "
+ consumeDescriptor.getScheme());
}
}
/**
* Makes sure a mail subject does not contain line breaks.
* @param string a string (can be null)
* @return the fixed string (null if string
was null)
*/
public static String fixMailSubject(final String string) {
String result = string;
if( result != null )
result = result.replace( "\r\n", "" ).replace( "\n", "" );
return result;
}
}