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.mailrepository;
23
24 import org.apache.avalon.cornerstone.services.store.Store;
25 import org.apache.avalon.framework.activity.Initializable;
26 import org.apache.avalon.framework.configuration.Configurable;
27 import org.apache.avalon.framework.logger.AbstractLogEnabled;
28 import org.apache.avalon.framework.service.ServiceException;
29 import org.apache.avalon.framework.service.ServiceManager;
30 import org.apache.avalon.framework.service.Serviceable;
31 import org.apache.james.services.MailRepository;
32 import org.apache.james.util.Lock;
33 import org.apache.mailet.Mail;
34
35 import javax.mail.MessagingException;
36
37 import java.io.IOException;
38 import java.util.Collection;
39 import java.util.Iterator;
40
41
42
43
44 public abstract class AbstractMailRepository extends AbstractLogEnabled
45 implements MailRepository, Serviceable, Configurable, Initializable {
46
47
48
49
50 protected static final boolean DEEP_DEBUG = false;
51
52
53
54
55
56 private Lock lock;
57
58 protected Store store;
59
60
61
62
63
64
65 void setStore(Store store) {
66 this.store = store;
67 }
68
69
70
71
72
73 public void initialize() throws Exception {
74 lock = new Lock();
75 }
76
77
78
79
80
81 public void service( final ServiceManager componentManager )
82 throws ServiceException {
83 setStore((Store)componentManager.lookup( Store.ROLE ));
84 }
85
86
87
88
89 public boolean unlock(String key) {
90 if (lock.unlock(key)) {
91 if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
92 StringBuffer debugBuffer =
93 new StringBuffer(256)
94 .append("Unlocked ")
95 .append(key)
96 .append(" for ")
97 .append(Thread.currentThread().getName())
98 .append(" @ ")
99 .append(new java.util.Date(System.currentTimeMillis()));
100 getLogger().debug(debugBuffer.toString());
101 }
102 return true;
103 } else {
104 return false;
105 }
106 }
107
108
109
110
111 public boolean lock(String key) {
112 if (lock.lock(key)) {
113 if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
114 StringBuffer debugBuffer =
115 new StringBuffer(256)
116 .append("Locked ")
117 .append(key)
118 .append(" for ")
119 .append(Thread.currentThread().getName())
120 .append(" @ ")
121 .append(new java.util.Date(System.currentTimeMillis()));
122 getLogger().debug(debugBuffer.toString());
123 }
124 return true;
125 } else {
126 return false;
127 }
128 }
129
130
131
132
133
134 public void store(Mail mc) throws MessagingException {
135 boolean wasLocked = true;
136 String key = mc.getName();
137 try {
138 synchronized(this) {
139 wasLocked = lock.isLocked(key);
140 if (!wasLocked) {
141
142 lock(key);
143 }
144 }
145 internalStore(mc);
146 if ((DEEP_DEBUG) && (getLogger().isDebugEnabled())) {
147 StringBuffer logBuffer =
148 new StringBuffer(64)
149 .append("Mail ")
150 .append(key)
151 .append(" stored.");
152 getLogger().debug(logBuffer.toString());
153 }
154 } catch (MessagingException e) {
155 getLogger().error("Exception caught while storing mail "+key,e);
156 throw e;
157 } catch (Exception e) {
158 getLogger().error("Exception caught while storing mail "+key,e);
159 throw new MessagingException("Exception caught while storing mail "+key,e);
160 } finally {
161 if (!wasLocked) {
162
163 unlock(key);
164 synchronized (this) {
165 notify();
166 }
167 }
168 }
169 }
170
171
172
173
174
175 protected abstract void internalStore(Mail mc) throws MessagingException, IOException;
176
177
178
179
180
181 public void remove(Mail mail) throws MessagingException {
182 remove(mail.getName());
183 }
184
185
186
187
188
189 public void remove(Collection mails) throws MessagingException {
190 Iterator delList = mails.iterator();
191 while (delList.hasNext()) {
192 remove((Mail)delList.next());
193 }
194 }
195
196
197
198
199 public void remove(String key) throws MessagingException {
200 if (lock(key)) {
201 try {
202 internalRemove(key);
203 } finally {
204 unlock(key);
205 }
206 } else {
207 StringBuffer exceptionBuffer =
208 new StringBuffer(64)
209 .append("Cannot lock ")
210 .append(key)
211 .append(" to remove it");
212 throw new MessagingException(exceptionBuffer.toString());
213 }
214 }
215
216
217
218
219
220 protected abstract void internalRemove(String key) throws MessagingException;
221
222
223 }