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