1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.apache.james.transport.mailets;
23
24 import org.apache.avalon.cornerstone.services.store.Store;
25 import org.apache.avalon.framework.configuration.DefaultConfiguration;
26 import org.apache.avalon.framework.service.ServiceException;
27 import org.apache.avalon.framework.service.ServiceManager;
28 import org.apache.james.Constants;
29 import org.apache.james.core.MailImpl;
30 import org.apache.james.services.MailRepository;
31 import org.apache.james.services.MailServer;
32 import org.apache.mailet.base.GenericMailet;
33 import org.apache.mailet.Mail;
34 import org.apache.mailet.MailAddress;
35 import org.apache.mailet.base.RFC2822Headers;
36
37 import javax.mail.Header;
38 import javax.mail.MessagingException;
39 import javax.mail.internet.InternetHeaders;
40 import javax.mail.internet.MimeMessage;
41
42 import java.util.Collection;
43 import java.util.Enumeration;
44 import java.util.HashSet;
45 import java.util.Iterator;
46 import java.util.Vector;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public class ToMultiRepository extends GenericMailet {
72
73
74
75
76 private static int count = 0;
77 private static final Object countLock = new Object();
78
79
80
81
82 private MailServer mailServer;
83
84
85
86
87 private Store store;
88
89
90
91
92 private String repositoryUrl;
93
94
95
96
97 private String repositoryType;
98
99 private final static String SELECTOR_LOCALPART = "localpart";
100 private final static String SELECTOR_FULL = "full";
101
102
103
104
105 private String repositorySelector;
106
107
108
109
110 private String deliveryHeader;
111
112
113
114
115 private boolean resetReturnPath;
116
117
118
119
120
121
122
123
124
125
126 public void service(Mail mail) throws MessagingException {
127 Collection recipients = mail.getRecipients();
128 Collection errors = new Vector();
129
130 MimeMessage message = mail.getMessage();
131
132 if (resetReturnPath) {
133
134
135
136
137 message.setHeader(RFC2822Headers.RETURN_PATH,
138 (mail.getSender() == null ? "<>" : "<" + mail.getSender()
139 + ">"));
140 }
141
142 Enumeration headers;
143 InternetHeaders deliveredTo = new InternetHeaders();
144 if (deliveryHeader != null) {
145
146 headers = message
147 .getMatchingHeaders(new String[] { deliveryHeader });
148 while (headers.hasMoreElements()) {
149 Header header = (Header) headers.nextElement();
150 deliveredTo.addHeader(header.getName(), header.getValue());
151 }
152 }
153
154 for (Iterator i = recipients.iterator(); i.hasNext();) {
155 MailAddress recipient = (MailAddress) i.next();
156 try {
157 if (deliveryHeader != null) {
158
159 message.addHeader(deliveryHeader, recipient.toString());
160 }
161
162 storeMail(mail.getSender(), recipient, message);
163
164 if (deliveryHeader != null) {
165 if (i.hasNext()) {
166
167 message.removeHeader(deliveryHeader);
168 headers = deliveredTo.getAllHeaders();
169
170 while (headers.hasMoreElements()) {
171 Header header = (Header) headers.nextElement();
172 message.addHeader(header.getName(), header
173 .getValue());
174 }
175 }
176 }
177 } catch (Exception ex) {
178 getMailetContext().log("Error while storing mail.", ex);
179 errors.add(recipient);
180 }
181 }
182
183 if (!errors.isEmpty()) {
184
185
186
187
188
189
190
191 getMailetContext().sendMail(mail.getSender(), errors, mail.getMessage(),
192 Mail.ERROR);
193 }
194
195 mail.setState(Mail.GHOST);
196 }
197
198
199
200
201
202
203 public String getMailetInfo() {
204 return "ToMultiRepository Mailet";
205 }
206
207
208
209
210
211
212
213
214 public void storeMail(MailAddress sender, MailAddress recipient,
215 MimeMessage message) throws MessagingException {
216 String username;
217 if (recipient == null) {
218 throw new IllegalArgumentException(
219 "Recipient for mail to be spooled cannot be null.");
220 }
221 if (message == null) {
222 throw new IllegalArgumentException(
223 "Mail message to be spooled cannot be null.");
224 }
225 username = recipient.toString();
226
227 Collection recipients = new HashSet();
228 recipients.add(recipient);
229 MailImpl mail = new MailImpl(getId(), sender, recipients, message);
230 try {
231 MailRepository userInbox = getRepository(username);
232 if (userInbox == null) {
233 StringBuffer errorBuffer = new StringBuffer(128).append(
234 "The repository for user ").append(username).append(
235 " was not found on this server.");
236 throw new MessagingException(errorBuffer.toString());
237 }
238 userInbox.store(mail);
239 } finally {
240 mail.dispose();
241 }
242 }
243
244
245
246
247
248
249 public String getId() {
250 final long localCount;
251 synchronized (countLock) {
252 localCount = count++;
253 }
254 StringBuffer idBuffer = new StringBuffer(64).append("Mail").append(
255 System.currentTimeMillis()).append("-").append(localCount).append('L');
256 return idBuffer.toString();
257 }
258
259
260
261
262 public void init() throws MessagingException {
263 super.init();
264 ServiceManager compMgr = (ServiceManager) getMailetContext()
265 .getAttribute(Constants.AVALON_COMPONENT_MANAGER);
266
267 try {
268
269 store = (Store) compMgr.lookup(Store.ROLE);
270 } catch (ServiceException cnfe) {
271 log("Failed to retrieve Store component:" + cnfe.getMessage());
272 } catch (Exception e) {
273 log("Failed to retrieve Store component:" + e.getMessage());
274 }
275
276 repositoryUrl = getInitParameter("repositoryUrl");
277 if (repositoryUrl != null) {
278 if (!repositoryUrl.endsWith("/"))
279 repositoryUrl += "/";
280 repositoryType = getInitParameter("repositoryType");
281 if (repositoryType == null)
282 repositoryType = "MAIL";
283 repositorySelector = getInitParameter("repositorySelector");
284 if (repositorySelector == null)
285 repositorySelector = SELECTOR_LOCALPART;
286 if (!SELECTOR_LOCALPART.equals(repositorySelector) && !SELECTOR_FULL.equals(repositorySelector)) {
287 throw new MessagingException("repositorySelector valid options are "+SELECTOR_FULL+" or "+SELECTOR_LOCALPART);
288 }
289 } else {
290
291 try {
292
293 mailServer = (MailServer) compMgr.lookup(MailServer.ROLE);
294 } catch (ServiceException cnfe) {
295 log("Failed to retrieve MailServer component:" + cnfe.getMessage());
296 } catch (Exception e) {
297 log("Failed to retrieve MailServer component:" + e.getMessage());
298 }
299
300 }
301
302 deliveryHeader = getInitParameter("addDeliveryHeader");
303 String resetReturnPathString = getInitParameter("resetReturnPath");
304 resetReturnPath = "true".equalsIgnoreCase(resetReturnPathString);
305 }
306
307
308
309
310
311
312
313
314 private MailRepository getRepository(String userName) {
315 MailRepository userInbox;
316 if (repositoryUrl == null) {
317 userInbox = mailServer.getUserInbox(userName);
318 } else {
319 if (SELECTOR_LOCALPART.equals(repositorySelector)) {
320
321 String[] addressParts = userName.split("@");
322 userName = addressParts[0];
323 }
324
325 StringBuffer destinationBuffer = new StringBuffer(192).append(
326 repositoryUrl).append(userName).append("/");
327 String destination = destinationBuffer.toString();
328 DefaultConfiguration mboxConf = new DefaultConfiguration(
329 "repository", "generated:ToMultiRepository.getUserInbox()");
330 mboxConf.setAttribute("destinationURL", destination);
331 mboxConf.setAttribute("type", repositoryType);
332 try {
333 userInbox = (MailRepository) store.select(mboxConf);
334 } catch (Exception e) {
335 log("Cannot open repository " + e);
336 userInbox = null;
337 }
338 }
339 return userInbox;
340 }
341
342 }