KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > mailrepository > AvalonSpoolRepository


1 /***********************************************************************
2  * Copyright (c) 1999-2004 The Apache Software Foundation. *
3  * All rights reserved. *
4  * ------------------------------------------------------------------- *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you *
6  * may not use this file except in compliance with the License. You *
7  * may obtain a copy of the License at: *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
14  * implied. See the License for the specific language governing *
15  * permissions and limitations under the License. *
16  ***********************************************************************/

17
18 package org.apache.james.mailrepository;
19
20 import org.apache.james.core.MailImpl;
21 import org.apache.james.services.SpoolRepository;
22 import org.apache.mailet.Mail;
23
24 import java.util.ConcurrentModificationException JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 /**
28  * Implementation of a MailRepository on a FileSystem.
29  *
30  * Requires a configuration element in the .conf.xml file of the form:
31  * <repository destinationURL="file://path-to-root-dir-for-repository"
32  * type="MAIL"
33  * model="SYNCHRONOUS"/>
34  * Requires a logger called MailRepository.
35  *
36  * @version 1.0.0, 24/04/1999
37  */

38 public class AvalonSpoolRepository
39     extends AvalonMailRepository
40     implements SpoolRepository {
41
42     /**
43      * <p>Returns an arbitrarily selected mail deposited in this Repository.
44      * Usage: SpoolManager calls accept() to see if there are any unprocessed
45      * mails in the spool repository.</p>
46      *
47      * <p>Synchronized to ensure thread safe access to the underlying spool.</p>
48      *
49      * @return the mail
50      */

51     public synchronized Mail accept() throws InterruptedException JavaDoc {
52         if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
53             getLogger().debug("Method accept() called");
54         }
55         return accept(new SpoolRepository.AcceptFilter () {
56             public boolean accept (String JavaDoc _, String JavaDoc __, long ___, String JavaDoc ____) {
57                 return true;
58             }
59
60             public long getWaitTime () {
61                 return 0;
62             }
63         });
64     }
65
66     /**
67      * <p>Returns an arbitrarily selected mail deposited in this Repository that
68      * is either ready immediately for delivery, or is younger than it's last_updated plus
69      * the number of failed attempts times the delay time.
70      * Usage: RemoteDeliverySpool calls accept() with some delay and should block until an
71      * unprocessed mail is available.</p>
72      *
73      * <p>Synchronized to ensure thread safe access to the underlying spool.</p>
74      *
75      * @return the mail
76      */

77     public synchronized Mail accept(final long delay) throws InterruptedException JavaDoc
78     {
79         if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
80             getLogger().debug("Method accept(delay) called");
81         }
82         return accept(new SpoolRepository.AcceptFilter () {
83             long youngest = 0;
84                 
85                 public boolean accept (String JavaDoc key, String JavaDoc state, long lastUpdated, String JavaDoc errorMessage) {
86                     if (state.equals(Mail.ERROR)) {
87                         //Test the time...
88
long timeToProcess = delay + lastUpdated;
89                 
90                         if (System.currentTimeMillis() > timeToProcess) {
91                             //We're ready to process this again
92
return true;
93                         } else {
94                             //We're not ready to process this.
95
if (youngest == 0 || youngest > timeToProcess) {
96                                 //Mark this as the next most likely possible mail to process
97
youngest = timeToProcess;
98                             }
99                             return false;
100                         }
101                     } else {
102                         //This mail is good to go... return the key
103
return true;
104                     }
105                 }
106         
107                 public long getWaitTime () {
108                     if (youngest == 0) {
109                         return 0;
110                     } else {
111                         long duration = youngest - System.currentTimeMillis();
112                         youngest = 0; //get ready for next round
113
return duration <= 0 ? 1 : duration;
114                     }
115                 }
116             });
117     }
118
119
120     /**
121      * Returns an arbitrarily select mail deposited in this Repository for
122      * which the supplied filter's accept method returns true.
123      * Usage: RemoteDeliverySpool calls accept(filter) with some a filter which determines
124      * based on number of retries if the mail is ready for processing.
125      * If no message is ready the method will block until one is, the amount of time to block is
126      * determined by calling the filters getWaitTime method.
127      *
128      * <p>Synchronized to ensure thread safe access to the underlying spool.</p>
129      *
130      * @return the mail
131      */

132     public synchronized Mail accept(SpoolRepository.AcceptFilter filter) throws InterruptedException JavaDoc {
133         if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
134             getLogger().debug("Method accept(Filter) called");
135         }
136         while (!Thread.currentThread().isInterrupted()) try {
137             for (Iterator JavaDoc it = list(); it.hasNext(); ) {
138                 String JavaDoc s = it.next().toString();
139                 if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
140                     StringBuffer JavaDoc logBuffer =
141                         new StringBuffer JavaDoc(64)
142                                 .append("Found item ")
143                                 .append(s)
144                                 .append(" in spool.");
145                     getLogger().debug(logBuffer.toString());
146                 }
147                 if (lock(s)) {
148                     if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
149                         getLogger().debug("accept(Filter) has locked: " + s);
150                     }
151                     try {
152                         MailImpl mail = retrieve(s);
153                         // Retrieve can return null if the mail is no longer on the spool
154
// (i.e. another thread has gotten to it first).
155
// In this case we simply continue to the next key
156
if (mail == null || !filter.accept (mail.getName(),
157                                                             mail.getState(),
158                                                             mail.getLastUpdated().getTime(),
159                                                             mail.getErrorMessage())) {
160                             unlock(s);
161                             continue;
162                         }
163                         return mail;
164                     } catch (javax.mail.MessagingException JavaDoc e) {
165                         unlock(s);
166                         getLogger().error("Exception during retrieve -- skipping item " + s, e);
167                     }
168                 }
169             }
170
171             //We did not find any... let's wait for a certain amount of time
172
wait (filter.getWaitTime());
173         } catch (InterruptedException JavaDoc ex) {
174             throw ex;
175         } catch (ConcurrentModificationException JavaDoc cme) {
176             // Should never get here now that list methods clones keyset for iterator
177
getLogger().error("CME in spooler - please report to http://james.apache.org", cme);
178         }
179         throw new InterruptedException JavaDoc();
180     }
181     
182 }
183
Popular Tags