All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.molindo.notify.channel.mail.AbstractMailClient Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2010 Molindo GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package at.molindo.notify.channel.mail;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.UUID;

import javax.mail.Address;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
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;

import org.springframework.beans.factory.InitializingBean;

import at.molindo.notify.INotifyService.NotifyRuntimeException;
import at.molindo.notify.model.Dispatch;
import at.molindo.notify.model.Message;
import at.molindo.notify.render.IRenderService.Type;
import at.molindo.utils.io.CharsetUtils;

public abstract class AbstractMailClient implements IMailClient, InitializingBean {

	public enum Security {
		NONE(25), SSL(465), TLS(587);

		private final int _defaultPort;

		private Security(int defaultPort) {
			_defaultPort = defaultPort;
		}

		public int getDefaultPort() {
			return _defaultPort;
		}

	}

	public enum Format {
		MULTI, HTML, TEXT;
	}

	// sender config
	private InternetAddress _from;
	private InternetAddress _replyTo;

	// message config
	private Format _format = Format.MULTI;

	@Override
	public final void afterPropertiesSet() throws Exception {
		init();
	}

	public AbstractMailClient init() throws MailException {
		if (_from == null) {
			throw new MailException("from address is not configured", true);
		}

		return this;
	}

	@Override
	public synchronized void send(Dispatch dispatch) throws MailException {

		Message message = dispatch.getMessage();

		String recipient = dispatch.getParams().get(MailChannel.RECIPIENT);
		String recipientName = dispatch.getParams().get(MailChannel.RECIPIENT_NAME);
		String subject = message.getSubject();

		try {
			MimeMessage mm = new MimeMessage(getSmtpSession(recipient)) {
				@Override
				protected void updateMessageID() throws MessagingException {
					String domain = _from.getAddress();
					int idx = _from.getAddress().indexOf('@');
					if (idx >= 0) {
						domain = domain.substring(idx + 1);
					}
					setHeader("Message-ID", "<" + UUID.randomUUID() + "@" + domain + ">");
				}
			};
			mm.setFrom(_from);
			mm.setSender(_from);

			InternetAddress replyTo = getReplyTo();
			if (replyTo != null) {
				mm.setReplyTo(new Address[] { replyTo });
			}
			mm.setHeader("X-Mailer", "molindo-notify");
			mm.setSentDate(new Date());

			mm.setRecipient(RecipientType.TO,
					new InternetAddress(recipient, recipientName, CharsetUtils.UTF_8.displayName()));
			mm.setSubject(subject, CharsetUtils.UTF_8.displayName());

			if (_format == Format.HTML) {
				if (message.getType() == Type.TEXT) {
					throw new MailException("can't send HTML mail from TEXT message", false);
				}
				mm.setText(message.getHtml(), CharsetUtils.UTF_8.displayName(), "html");
			} else if (_format == Format.TEXT || _format == Format.MULTI && message.getType() == Type.TEXT) {
				mm.setText(message.getText(), CharsetUtils.UTF_8.displayName());
			} else if (_format == Format.MULTI) {
				MimeBodyPart html = new MimeBodyPart();
				html.setText(message.getHtml(), CharsetUtils.UTF_8.displayName(), "html");

				MimeBodyPart text = new MimeBodyPart();
				text.setText(message.getText(), CharsetUtils.UTF_8.displayName());

				/*
				 * The formats are ordered by how faithful they are to the
				 * original, with the least faithful first and the most faithful
				 * last. (http://en.wikipedia.org/wiki/MIME#Alternative)
				 */
				MimeMultipart mmp = new MimeMultipart();
				mmp.setSubType("alternative");

				mmp.addBodyPart(text);
				mmp.addBodyPart(html);

				mm.setContent(mmp);
			} else {
				throw new NotifyRuntimeException("unexpected format (" + _format + ") or type (" + message.getType()
						+ ")");
			}

			send(mm);

		} catch (final MessagingException e) {
			throw new MailException("could not send mail from " + _from + " to " + recipient + " (" + toErrorMessage(e)
					+ ")", e, isTemporary(e));
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("utf8 unknown?", e);
		}
	}

	/**
	 * override for testing
	 */
	protected void send(MimeMessage mm) throws MessagingException {
		Transport.send(mm);
	}

	protected String toErrorMessage(MessagingException e) {
		return e == null ? null : e.getMessage();
	}

	protected boolean isTemporary(MessagingException e) {
		return true;
	}

	protected abstract Session getSmtpSession(String recipient) throws MailException;

	public InternetAddress getFrom() {
		return _from;
	}

	public AbstractMailClient setFrom(InternetAddress from) {
		_from = from;
		return this;
	}

	public AbstractMailClient setFrom(String address) throws AddressException {
		return setFrom(new InternetAddress(address));
	}

	public AbstractMailClient setFrom(String address, String personal) throws AddressException {
		try {
			return setFrom(new InternetAddress(address, personal, CharsetUtils.UTF_8.displayName()));
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("utf8 not supported?", e);
		}
	}

	public InternetAddress getReplyTo() {
		return _replyTo;
	}

	public AbstractMailClient setReplyTo(InternetAddress replyTo) {
		_replyTo = replyTo;
		return this;
	}

	public AbstractMailClient setReplyTo(String address) throws AddressException {
		return setReplyTo(new InternetAddress(address));
	}

	public AbstractMailClient setReplyTo(String address, String personal) throws AddressException {
		try {
			return setReplyTo(new InternetAddress(address, personal, CharsetUtils.UTF_8.displayName()));
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("utf8 not supported?", e);
		}
	}

	public Format getFormat() {
		return _format;
	}

	public AbstractMailClient setFormat(Format format) {
		if (format == null) {
			throw new NullPointerException("format");
		}
		_format = format;
		return this;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy