1 /*
2 * Copyright 2006-2010 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.springframework.batch.item.mail;
17
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Map.Entry;
21
22 import org.springframework.batch.item.ItemWriter;
23 import org.springframework.beans.factory.InitializingBean;
24 import org.springframework.mail.MailException;
25 import org.springframework.mail.MailSendException;
26 import org.springframework.mail.MailSender;
27 import org.springframework.mail.SimpleMailMessage;
28 import org.springframework.util.Assert;
29
30 /**
31 * <p>
32 * A simple {@link ItemWriter} that can send mail messages. If it fails there is
33 * no guarantee about which of the messages were sent, but the ones that failed
34 * can be picked up in the error handler. Because the mail protocol is not
35 * transactional, failures should be dealt with here if possible rather than
36 * allowing them to be rethrown (which is the default).
37 * </p>
38 *
39 * <p>
40 * Delegates the actual sending of messages to a {@link MailSender}, using the
41 * batch method {@link MailSender#send(SimpleMailMessage[])}, which normally
42 * uses a single server connection for the whole batch (depending on the
43 * implementation). The efficiency of for large volumes of messages (repeated
44 * calls to the item writer) might be improved by the use of a special
45 * {@link MailSender} that caches connections to the server in between calls.
46 * </p>
47 *
48 * <p>
49 * Stateless, so automatically restartable.
50 * </p>
51 *
52 * @author Dave Syer
53 *
54 * @since 2.1
55 *
56 */
57 public class SimpleMailMessageItemWriter implements ItemWriter<SimpleMailMessage>, InitializingBean {
58
59 private MailSender mailSender;
60
61 private MailErrorHandler mailErrorHandler = new DefaultMailErrorHandler();
62
63 /**
64 * A {@link MailSender} to be used to send messages in {@link #write(List)}.
65 *
66 * @param mailSender
67 */
68 public void setMailSender(MailSender mailSender) {
69 this.mailSender = mailSender;
70 }
71
72 /**
73 * The handler for failed messages. Defaults to a
74 * {@link DefaultMailErrorHandler}.
75 *
76 * @param mailErrorHandler the mail error handler to set
77 */
78 public void setMailErrorHandler(MailErrorHandler mailErrorHandler) {
79 this.mailErrorHandler = mailErrorHandler;
80 }
81
82 /**
83 * Check mandatory properties (mailSender).
84 *
85 * @throws IllegalStateException if the mandatory properties are not set
86 *
87 * @see InitializingBean#afterPropertiesSet()
88 */
89 @Override
90 public void afterPropertiesSet() throws IllegalStateException {
91 Assert.state(mailSender != null, "A MailSender must be provided.");
92 }
93
94 /**
95 * @param items the items to send
96 * @see ItemWriter#write(List)
97 */
98 @Override
99 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 @SuppressWarnings("unchecked")
105 Map<Object, Exception> failedMessages = e.getFailedMessages();
106 for (Entry<Object, Exception> entry : failedMessages.entrySet()) {
107 mailErrorHandler.handle((SimpleMailMessage) entry.getKey(), entry.getValue());
108 }
109 }
110 }
111
112 }