1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts.apps.mailreader.dao.impl.memory;
22
23
24 import java.io.BufferedInputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.OutputStreamWriter;
30 import java.io.PrintWriter;
31 import java.util.HashMap;
32
33 import org.apache.commons.digester.Digester;
34 import org.apache.commons.digester.ObjectCreationFactory;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.struts.apps.mailreader.dao.Subscription;
38 import org.apache.struts.apps.mailreader.dao.User;
39 import org.apache.struts.apps.mailreader.dao.UserDatabase;
40 import org.xml.sax.Attributes;
41
42
43
44
45
46
47
48
49
50
51 public class MemoryUserDatabase implements UserDatabase {
52
53
54
55
56
57
58
59
60
61
62
63 private Log log = LogFactory.getLog(this.getClass());
64
65
66
67
68
69 private HashMap users = new HashMap();
70
71 private boolean open = false;
72
73
74
75
76
77
78
79
80
81 private String pathname = null;
82
83 private String pathnameOld = null;
84
85 private String pathnameNew = null;
86
87 public String getPathname() {
88 return (this.pathname);
89 }
90
91 public void setPathname(String pathname) {
92 this.pathname = pathname;
93 pathnameOld = pathname + ".old";
94 pathnameNew = pathname + ".new";
95 }
96
97
98
99
100
101
102 public void close() throws Exception {
103
104 save();
105 this.open = false;
106
107 }
108
109
110
111 public User createUser(String username) {
112
113 synchronized (users) {
114 if (users.get(username) != null) {
115 throw new IllegalArgumentException("Duplicate user '" +
116 username + "'");
117 }
118 if (log.isTraceEnabled()) {
119 log.trace("Creating user '" + username + "'");
120 }
121 MemoryUser user = new MemoryUser(this, username);
122 synchronized (users) {
123 users.put(username, user);
124 }
125 return (user);
126 }
127
128 }
129
130
131
132 public User findUser(String username) {
133
134 synchronized (users) {
135 return ((User) users.get(username));
136 }
137
138 }
139
140
141
142 public User[] findUsers() {
143
144 synchronized (users) {
145 User results[] = new User[users.size()];
146 return ((User[]) users.values().toArray(results));
147 }
148
149 }
150
151
152
153 public void open() throws Exception {
154
155 FileInputStream fis = null;
156 BufferedInputStream bis = null;
157
158 try {
159
160
161 if (log.isDebugEnabled()) {
162 log.debug("Loading database from '" + pathname + "'");
163 }
164 fis = new FileInputStream(pathname);
165 bis = new BufferedInputStream(fis);
166
167
168 Digester digester = new Digester();
169 digester.push(this);
170 digester.setValidating(false);
171 digester.addFactoryCreate
172 ("database/user",
173 new MemoryUserCreationFactory(this));
174 digester.addFactoryCreate
175 ("database/user/subscription",
176 new MemorySubscriptionCreationFactory());
177
178
179 digester.parse(bis);
180 bis.close();
181 bis = null;
182 fis = null;
183 this.open = true;
184
185 } catch (Exception e) {
186
187 log.error("Loading database from '" + pathname + "':", e);
188 throw e;
189
190 } finally {
191
192 if (bis != null) {
193 try {
194 bis.close();
195 } catch (Throwable t) {
196
197 }
198 bis = null;
199 fis = null;
200 }
201
202 }
203
204 }
205
206
207
208 public void removeUser(User user) {
209
210 if (!(this == user.getDatabase())) {
211 throw new IllegalArgumentException
212 ("User not associated with this database");
213 }
214 if (log.isTraceEnabled()) {
215 log.trace("Removing user '" + user.getUsername() + "'");
216 }
217 synchronized (users) {
218 users.remove(user.getUsername());
219 }
220
221 }
222
223
224
225 public void save() throws Exception {
226
227 if (log.isDebugEnabled()) {
228 log.debug("Saving database to '" + pathname + "'");
229 }
230 File fileNew = new File(pathnameNew);
231 PrintWriter writer = null;
232
233 try {
234
235
236 FileOutputStream fos = new FileOutputStream(fileNew);
237 OutputStreamWriter osw = new OutputStreamWriter(fos);
238 writer = new PrintWriter(osw);
239
240
241 writer.println("<?xml version='1.0'?>");
242 writer.println("<database>");
243
244
245 User yusers[] = findUsers();
246 for (int i = 0; i < yusers.length; i++) {
247 writer.print(" ");
248 writer.println(yusers[i]);
249 Subscription subscriptions[] =
250 yusers[i].getSubscriptions();
251 for (int j = 0; j < subscriptions.length; j++) {
252 writer.print(" ");
253 writer.println(subscriptions[j]);
254 writer.print(" ");
255 writer.println("</subscription>");
256 }
257 writer.print(" ");
258 writer.println("</user>");
259 }
260
261
262 writer.println("</database>");
263
264
265 if (writer.checkError()) {
266 writer.close();
267 fileNew.delete();
268 throw new IOException
269 ("Saving database to '" + pathname + "'");
270 }
271 writer.close();
272 writer = null;
273
274 } catch (IOException e) {
275
276 if (writer != null) {
277 writer.close();
278 }
279 fileNew.delete();
280 throw e;
281
282 }
283
284
285
286 File fileOrig = new File(pathname);
287 File fileOld = new File(pathnameOld);
288 if (fileOrig.exists()) {
289 fileOld.delete();
290 if (!fileOrig.renameTo(fileOld)) {
291 throw new IOException
292 ("Renaming '" + pathname + "' to '" + pathnameOld + "'");
293 }
294 }
295 if (!fileNew.renameTo(fileOrig)) {
296 if (fileOld.exists()) {
297 fileOld.renameTo(fileOrig);
298 }
299 throw new IOException
300 ("Renaming '" + pathnameNew + "' to '" + pathname + "'");
301 }
302 fileOld.delete();
303
304 }
305
306 public boolean isOpen() {
307 return this.open;
308 }
309
310
311
312
313 }
314
315
316
317
318
319 class MemorySubscriptionCreationFactory implements ObjectCreationFactory {
320
321 private Digester digester = null;
322
323 public Digester getDigester() {
324 return (this.digester);
325 }
326
327 public void setDigester(Digester digester) {
328 this.digester = digester;
329 }
330
331 public Object createObject(Attributes attributes) {
332 String host = attributes.getValue("host");
333 User user = (User) digester.peek();
334 Subscription subscription = user.createSubscription(host);
335 String autoConnect = attributes.getValue("autoConnect");
336 if (autoConnect == null) {
337 autoConnect = "false";
338 }
339 if ("true".equalsIgnoreCase(autoConnect) ||
340 "yes".equalsIgnoreCase(autoConnect)) {
341 subscription.setAutoConnect(true);
342 } else {
343 subscription.setAutoConnect(false);
344 }
345 subscription.setPassword(attributes.getValue("password"));
346 subscription.setType(attributes.getValue("type"));
347 subscription.setUsername(attributes.getValue("username"));
348 return (subscription);
349 }
350
351 }
352
353
354
355
356
357 class MemoryUserCreationFactory implements ObjectCreationFactory {
358
359 public MemoryUserCreationFactory(MemoryUserDatabase database) {
360 this.database = database;
361 }
362
363 private MemoryUserDatabase database = null;
364
365 private Digester digester = null;
366
367 public Digester getDigester() {
368 return (this.digester);
369 }
370
371 public void setDigester(Digester digester) {
372 this.digester = digester;
373 }
374
375 public Object createObject(Attributes attributes) {
376 String username = attributes.getValue("username");
377 User user = database.createUser(username);
378 user.setFromAddress(attributes.getValue("fromAddress"));
379 user.setFullName(attributes.getValue("fullName"));
380 user.setPassword(attributes.getValue("password"));
381 user.setReplyToAddress(attributes.getValue("replyToAddress"));
382 return (user);
383 }
384
385 }