1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.mailrepository.javamail;
21
22 import java.io.File;
23 import java.io.FileNotFoundException;
24 import java.net.MalformedURLException;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.Properties;
28 import java.util.Random;
29
30 import javax.mail.Folder;
31 import javax.mail.MessagingException;
32 import javax.mail.NoSuchProviderException;
33 import javax.mail.Session;
34 import javax.mail.Store;
35 import javax.mail.URLName;
36
37 import org.apache.avalon.framework.activity.Initializable;
38 import org.apache.avalon.framework.configuration.Configurable;
39 import org.apache.avalon.framework.configuration.Configuration;
40 import org.apache.avalon.framework.configuration.ConfigurationException;
41 import org.apache.avalon.framework.logger.AbstractLogEnabled;
42 import org.apache.avalon.framework.logger.Logger;
43 import org.apache.avalon.framework.service.ServiceException;
44 import org.apache.avalon.framework.service.ServiceManager;
45 import org.apache.avalon.framework.service.Serviceable;
46 import org.apache.james.services.FileSystem;
47 import org.apache.james.services.MailRepository;
48 import org.apache.mailet.Mail;
49
50
51
52
53
54
55
56
57
58 public abstract class AbstractJavamailStoreMailRepository extends
59 AbstractLogEnabled implements MailRepository, StoreGateKeeperAware, FolderAdapterFactory, Configurable,
60 Initializable,Serviceable {
61
62
63
64
65 protected final static boolean DEEP_DEBUG = true;
66
67 private static final String TYPE = "MAIL";
68
69
70
71
72
73 private String destination;
74
75 protected Logger log;
76
77
78
79
80
81 private StoreGateKeeper storeGateKeeper = null;
82
83
84
85
86 private static Random random;
87
88
89
90
91
92 protected boolean cacheMessages = false;
93
94
95
96
97
98 private LockInterface lock;
99
100
101
102
103 private FolderGateKeeper folderGateKeeper;
104
105
106
107
108 private File home;
109
110
111
112
113 public void service(ServiceManager serviceManager) throws ServiceException {
114 try {
115 home = ((FileSystem) serviceManager.lookup(FileSystem.ROLE)).getBasedir();
116 } catch (FileNotFoundException e) {
117 throw new ServiceException(FileSystem.ROLE, "Cannot find the base directory of the application", e);
118 }
119 }
120
121
122
123
124
125
126
127
128 public void configure(Configuration conf) throws ConfigurationException {
129 log.debug("JavamailStoreMailRepository configure");
130 destination = conf.getAttribute("destinationURL");
131 log.debug("JavamailStoreMailRepository.destinationURL: " + destination);
132 if (!destination.endsWith("/")) {
133 destination += "/";
134 }
135 String postfix = conf.getAttribute("postfix", "");
136 if (postfix.length() > 0) {
137 if (postfix.startsWith("/")) {
138 postfix = postfix.substring(1);
139 }
140 if (!postfix.endsWith("/")) {
141 postfix += "/";
142 }
143 destination += postfix;
144
145 }
146
147
148
149
150
151 final int pi = destination.indexOf(':');
152 if (pi < 0) {
153 throw new ConfigurationException("protocol prefix is missing "
154 + destination);
155 }
156 String withoutProtocol = destination.substring(pi);
157 final String protocol = destination.substring(0, pi);
158 try {
159 if (!withoutProtocol.startsWith(":///")) {
160 withoutProtocol = "://"+ getDirAsUrl(home + "/" +withoutProtocol.substring(3));
161 } else {
162 withoutProtocol = "://" + getDirAsUrl("/" + withoutProtocol.substring(3));
163 }
164 } catch (MalformedURLException e) {
165 throw new ConfigurationException("Invalid url: " + destination);
166 }
167
168
169 destination = protocol + withoutProtocol;
170 log.debug("destination: " + destination);
171 Properties mailSessionProps = new Properties();
172
173
174
175 Session mailSession = Session.getDefaultInstance(mailSessionProps);
176 try {
177 Store store=mailSession.getStore(new URLName(destination));
178 store.connect();
179 storeGateKeeper = new StoreGateKeeperImpl(store);
180 storeGateKeeper.setFolderAdapterFactory(this);
181 } catch (NoSuchProviderException e) {
182 throw new ConfigurationException("cannot find store provider for "
183 + destination, e);
184 } catch (MessagingException e) {
185 throw new ConfigurationException("Error connecting store: "
186 + destination, e);
187 }
188
189 String checkType = conf.getAttribute("type");
190 if (!checkType.equals(TYPE)) {
191 String exceptionString = "Attempt to configure JavaMailStoreMailRepository as "
192 + checkType;
193 log.warn(exceptionString);
194 throw new ConfigurationException(exceptionString);
195 }
196 log.debug("JavaMailStoreMailRepository configured");
197 }
198
199
200
201
202
203 public void initialize() throws Exception {
204 log.debug("JavaMailStoreMailRepository initialized");
205 }
206
207 private String getDirAsUrl(String dir) throws MalformedURLException {
208 File f = new File(dir);
209 return f.toURL().toString();
210 }
211
212
213
214
215
216
217
218
219 protected LockInterface getLock() {
220 if (lock==null) {
221 lock = new LockAdapter();
222 }
223 return lock;
224 }
225
226
227
228
229
230
231 void setLock(LockInterface lock) {
232 this.lock=lock;
233 }
234
235
236
237
238
239
240 String getDestination() {
241 return destination;
242 }
243
244
245
246
247
248
249
250
251
252 public boolean lock(String key) {
253 if (getLock().lock(key)) {
254 if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
255 StringBuffer debugBuffer = new StringBuffer(256).append(
256 "Locked ").append(key).append(" for ").append(
257 Thread.currentThread().getName()).append(" @ ").append(
258 new java.util.Date(System.currentTimeMillis()));
259 getLogger().debug(debugBuffer.toString());
260 }
261 return true;
262 } else {
263 return false;
264 }
265 }
266
267
268
269
270
271
272
273
274
275 public boolean unlock(String key) {
276 if (getLock().unlock(key)) {
277 if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
278 StringBuffer debugBuffer = new StringBuffer(256).append(
279 "Unlocked ").append(key).append(" for ").append(
280 Thread.currentThread().getName()).append(" @ ").append(
281 new java.util.Date(System.currentTimeMillis()));
282 getLogger().debug(debugBuffer.toString());
283 }
284 return true;
285 } else {
286 return false;
287 }
288 }
289
290
291
292
293
294
295
296
297 public void remove(Mail mail) throws MessagingException {
298 log.debug("UIDPlusFolder remove by Mail");
299 remove(mail.getName());
300 }
301
302
303
304
305
306
307
308
309 public void remove(final Collection mails) throws MessagingException {
310 log.debug("UIDPlusFolder remove by Collection " + mails.size());
311 if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
312 StringBuffer logBuffer = new StringBuffer(128).append(
313 this.getClass().getName()).append(
314 " Removing entry for key ").append(mails);
315
316 getLogger().debug(logBuffer.toString());
317 }
318 Iterator mailList = mails.iterator();
319
320
321
322
323 while (mailList.hasNext()) {
324 remove(((Mail) mailList.next()).getName());
325 }
326 }
327
328
329
330
331
332
333 public StoreGateKeeper getStore() {
334 return storeGateKeeper;
335 }
336
337
338
339
340
341
342 protected static synchronized Random getRandom() {
343 if (random == null) {
344 random = new Random();
345 }
346 return random;
347
348 }
349
350
351
352
353
354
355 public void enableLogging(Logger log) {
356 super.enableLogging(log);
357 this.log=log;
358
359 }
360
361
362
363
364
365
366
367 void setFolderGateKeeper(FolderGateKeeper gk) {
368 this.folderGateKeeper=gk;
369
370 }
371
372
373
374
375
376
377 protected FolderGateKeeper getFolderGateKeeper() {
378 if (folderGateKeeper == null) {
379 try {
380 folderGateKeeper = getStore().getFolder("INBOX");
381
382
383
384 folderGateKeeper.use();
385 if (folderGateKeeper.getFolder().exists() == false) {
386 folderGateKeeper.getFolder().create(Folder.HOLDS_MESSAGES);
387 }
388 folderGateKeeper.free();
389 } catch (MessagingException e) {
390 throw new RuntimeException(
391 "cannot retrieve inbox for this repository", e);
392 }
393 }
394 return folderGateKeeper;
395 }
396 }