001/*
002 * Copyright 2006-2010 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.springframework.batch.item.mail.javamail;
017
018import org.springframework.batch.item.ItemWriter;
019import org.springframework.batch.item.mail.DefaultMailErrorHandler;
020import org.springframework.batch.item.mail.MailErrorHandler;
021import org.springframework.beans.factory.InitializingBean;
022import org.springframework.mail.MailException;
023import org.springframework.mail.MailSendException;
024import org.springframework.mail.javamail.JavaMailSender;
025import org.springframework.mail.javamail.MimeMailMessage;
026import org.springframework.util.Assert;
027
028import javax.mail.internet.MimeMessage;
029import java.util.List;
030import java.util.Map;
031import java.util.Map.Entry;
032
033/**
034 * <p>
035 * A simple {@link ItemWriter} that can send mail messages. If it fails there is
036 * no guarantee about which of the messages were sent, but the ones that failed
037 * can be picked up in the error handler. Because the mail protocol is not
038 * transactional, failures should be dealt with here if possible rather than
039 * allowing them to be rethrown (which is the default).
040 * </p>
041 * 
042 * <p>
043 * Delegates the actual sending of messages to a {@link JavaMailSender}, using the
044 * batch method {@link JavaMailSender#send(MimeMessage[])}, which normally uses
045 * a single server connection for the whole batch (depending on the
046 * implementation). The efficiency of for large volumes of messages (repeated
047 * calls to the item writer) might be improved by the use of a special
048 * {@link JavaMailSender} that caches connections to the server in between
049 * calls.
050 * </p>
051 * 
052 * <p>
053 * Stateless, so automatically restartable.
054 * </p>
055 * 
056 * @author Dave Syer
057 * 
058 * @since 2.1
059 * 
060 */
061public class MimeMessageItemWriter implements ItemWriter<MimeMessage> {
062
063        private JavaMailSender mailSender;
064
065        private MailErrorHandler mailErrorHandler = new DefaultMailErrorHandler();
066
067        /**
068         * A {@link JavaMailSender} to be used to send messages in {@link #write(List)}.
069         * 
070         * @param mailSender service for doing the work of sending a MIME message
071         */
072        public void setJavaMailSender(JavaMailSender mailSender) {
073                this.mailSender = mailSender;
074        }
075
076        /**
077         * The handler for failed messages. Defaults to a
078         * {@link DefaultMailErrorHandler}.
079         * 
080         * @param mailErrorHandler the mail error handler to set
081         */
082        public void setMailErrorHandler(MailErrorHandler mailErrorHandler) {
083                this.mailErrorHandler = mailErrorHandler;
084        }
085
086        /**
087         * Check mandatory properties (mailSender).
088         * 
089         * @throws IllegalStateException if the mandatory properties are not set
090         * 
091         * @see InitializingBean#afterPropertiesSet()
092         */
093        public void afterPropertiesSet() throws IllegalStateException {
094                Assert.state(mailSender != null, "A MailSender must be provided.");
095        }
096
097        /**
098         * @param items the items to send
099         * @see ItemWriter#write(List)
100         */
101    @Override
102        public void write(List<? extends MimeMessage> items) throws MailException {
103                try {
104                        mailSender.send(items.toArray(new MimeMessage[items.size()]));
105                }
106                catch (MailSendException e) {
107                        Map<Object, Exception> failedMessages = e.getFailedMessages();
108                        for (Entry<Object, Exception> entry : failedMessages.entrySet()) {
109                                mailErrorHandler.handle(new MimeMailMessage((MimeMessage)entry.getKey()), entry.getValue());
110                        }
111                }
112        }
113
114}