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;
017
018import java.util.List;
019import java.util.Map;
020import java.util.Map.Entry;
021
022import org.springframework.batch.item.ItemWriter;
023import org.springframework.beans.factory.InitializingBean;
024import org.springframework.mail.MailException;
025import org.springframework.mail.MailSendException;
026import org.springframework.mail.MailSender;
027import org.springframework.mail.SimpleMailMessage;
028import org.springframework.util.Assert;
029
030/**
031 * <p>
032 * A simple {@link ItemWriter} that can send mail messages. If it fails there is
033 * no guarantee about which of the messages were sent, but the ones that failed
034 * can be picked up in the error handler. Because the mail protocol is not
035 * transactional, failures should be dealt with here if possible rather than
036 * allowing them to be rethrown (which is the default).
037 * </p>
038 * 
039 * <p>
040 * Delegates the actual sending of messages to a {@link MailSender}, using the
041 * batch method {@link MailSender#send(SimpleMailMessage[])}, which normally
042 * uses a single server connection for the whole batch (depending on the
043 * implementation). The efficiency of for large volumes of messages (repeated
044 * calls to the item writer) might be improved by the use of a special
045 * {@link MailSender} that caches connections to the server in between calls.
046 * </p>
047 * 
048 * <p>
049 * Stateless, so automatically restartable.
050 * </p>
051 * 
052 * @author Dave Syer
053 * 
054 * @since 2.1
055 * 
056 */
057public class SimpleMailMessageItemWriter implements ItemWriter<SimpleMailMessage>, InitializingBean {
058
059        private MailSender mailSender;
060
061        private MailErrorHandler mailErrorHandler = new DefaultMailErrorHandler();
062
063        /**
064         * A {@link MailSender} to be used to send messages in {@link #write(List)}.
065         * 
066         * @param mailSender The {@link MailSender} to be used.
067         */
068        public void setMailSender(MailSender mailSender) {
069                this.mailSender = mailSender;
070        }
071
072        /**
073         * The handler for failed messages. Defaults to a
074         * {@link DefaultMailErrorHandler}.
075         * 
076         * @param mailErrorHandler the mail error handler to set
077         */
078        public void setMailErrorHandler(MailErrorHandler mailErrorHandler) {
079                this.mailErrorHandler = mailErrorHandler;
080        }
081
082        /**
083         * Check mandatory properties (mailSender).
084         * 
085         * @throws IllegalStateException if the mandatory properties are not set
086         * 
087         * @see InitializingBean#afterPropertiesSet()
088         */
089    @Override
090        public void afterPropertiesSet() throws IllegalStateException {
091                Assert.state(mailSender != null, "A MailSender must be provided.");
092        }
093
094        /**
095         * @param items the items to send
096         * @see ItemWriter#write(List)
097         */
098    @Override
099        public void write(List<? extends SimpleMailMessage> items) throws MailException {
100                try {
101                        mailSender.send(items.toArray(new SimpleMailMessage[items.size()]));
102                }
103                catch (MailSendException e) {
104                        Map<Object, Exception> failedMessages = e.getFailedMessages();
105                        for (Entry<Object, Exception> entry : failedMessages.entrySet()) {
106                                mailErrorHandler.handle((SimpleMailMessage) entry.getKey(), entry.getValue());
107                        }
108                }
109        }
110
111}