KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > examples > mailreader > memory > MemoryUserDatabase


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

18
19 package org.apache.struts.examples.mailreader.memory;
20
21 import java.io.BufferedInputStream JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.OutputStreamWriter JavaDoc;
27 import java.io.PrintWriter JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import org.apache.commons.digester.Digester;
30 import org.apache.commons.digester.ObjectCreationFactory;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.struts.examples.mailreader.Subscription;
34 import org.apache.struts.examples.mailreader.User;
35 import org.apache.struts.examples.mailreader.UserDatabase;
36 import org.apache.struts.examples.mailreader.ExpiredPasswordException;
37 import org.xml.sax.Attributes JavaDoc;
38
39 /**
40  * <p>Concrete implementation of {@link UserDatabase} for an in-memory
41  * database backed by an XML data file.</p>
42  *
43  * @version $Rev: 54929 $ $Date: 2004-10-16 09:38:42 -0700 (Sat, 16 Oct 2004) $
44  * @since Struts 1.1
45  */

46
47 public class MemoryUserDatabase implements UserDatabase {
48
49
50     // ----------------------------------------------------------- Constructors
51

52
53     // ----------------------------------------------------- Instance Variables
54

55
56     /**
57      * Logging output for this user database instance.
58      */

59     private Log log = LogFactory.getLog(this.getClass());
60
61
62     /**
63      * The {@link User}s associated with this UserDatabase, keyed by username.
64      */

65     private HashMap JavaDoc users = new HashMap JavaDoc();
66
67
68     // ------------------------------------------------------------- Properties
69

70
71     /**
72      * Absolute pathname to the persistent file we use for loading and storing
73      * persistent data.
74      */

75     private String JavaDoc pathname = null;
76
77     private String JavaDoc pathnameOld = null;
78
79     private String JavaDoc pathnameNew = null;
80
81     public String JavaDoc getPathname() {
82         return (this.pathname);
83     }
84
85     public void setPathname(String JavaDoc pathname) {
86         this.pathname = pathname;
87         pathnameOld = pathname + ".old";
88         pathnameNew = pathname + ".new";
89     }
90
91
92     // --------------------------------------------------------- Public Methods
93

94
95     // See interface for Javadoc
96
public void close() throws Exception JavaDoc {
97
98         save();
99
100     }
101
102
103     // See interface for Javadoc
104
public User createUser(String JavaDoc username) {
105
106         synchronized (users) {
107             if (users.get(username) != null) {
108                 throw new IllegalArgumentException JavaDoc("Duplicate user '" +
109                                                    username + "'");
110             }
111             if (log.isTraceEnabled()) {
112                 log.trace("Creating user '" + username + "'");
113             }
114             MemoryUser user = new MemoryUser(this, username);
115             synchronized (users) {
116                 users.put(username, user);
117             }
118             return (user);
119         }
120
121     }
122
123
124     // See interface for Javadoc
125
public User findUser(String JavaDoc username) throws ExpiredPasswordException {
126
127         synchronized (users) {
128             return ((User) users.get(username));
129         }
130
131     }
132
133
134     // See interface for Javadoc
135
public User[] findUsers() {
136
137         synchronized (users) {
138             User results[] = new User[users.size()];
139             return ((User[]) users.values().toArray(results));
140         }
141
142     }
143
144
145     // See interface for Javadoc
146
public void open() throws Exception JavaDoc {
147
148         FileInputStream JavaDoc fis = null;
149         BufferedInputStream JavaDoc bis = null;
150
151         try {
152
153             // Acquire an input stream to our database file
154
if (log.isDebugEnabled()) {
155                 log.debug("Loading database from '" + pathname + "'");
156             }
157             fis = new FileInputStream JavaDoc(pathname);
158             bis = new BufferedInputStream JavaDoc(fis);
159
160             // Construct a digester to use for parsing
161
Digester digester = new Digester();
162             digester.push(this);
163             digester.setValidating(false);
164             digester.addFactoryCreate
165                 ("database/user",
166                  new MemoryUserCreationFactory(this));
167             digester.addFactoryCreate
168                 ("database/user/subscription",
169                  new MemorySubscriptionCreationFactory());
170
171             // Parse the input stream to initialize our database
172
digester.parse(bis);
173             bis.close();
174             bis = null;
175             fis = null;
176
177         } catch (Exception JavaDoc e) {
178
179             log.error("Loading database from '" + pathname + "':", e);
180             throw e;
181
182         } finally {
183
184             if (bis != null) {
185                 try {
186                     bis.close();
187                 } catch (Throwable JavaDoc t) {
188                     ;
189                 }
190                 bis = null;
191                 fis = null;
192             }
193
194         }
195
196     }
197
198
199     // See interface for Javadoc
200
public void removeUser(User user) {
201
202         if (!(this == user.getDatabase())) {
203             throw new IllegalArgumentException JavaDoc
204                 ("User not associated with this database");
205         }
206         if (log.isTraceEnabled()) {
207             log.trace("Removing user '" + user.getUsername() + "'");
208         }
209         synchronized (users) {
210             users.remove(user.getUsername());
211         }
212
213     }
214
215
216     // See interface for Javadoc
217
public void save() throws Exception JavaDoc {
218
219         if (log.isDebugEnabled()) {
220             log.debug("Saving database to '" + pathname + "'");
221         }
222         File JavaDoc fileNew = new File JavaDoc(pathnameNew);
223         PrintWriter JavaDoc writer = null;
224
225         try {
226
227             // Configure our PrintWriter
228
FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(fileNew);
229             OutputStreamWriter JavaDoc osw = new OutputStreamWriter JavaDoc(fos);
230             writer = new PrintWriter JavaDoc(osw);
231
232             // Print the file prolog
233
writer.println("<?xml version='1.0'?>");
234             writer.println("<database>");
235
236             // Print entries for each defined user and associated subscriptions
237
User users[] = findUsers();
238             for (int i = 0; i < users.length; i++) {
239                 writer.print(" ");
240                 writer.println(users[i]);
241                 Subscription subscriptions[] =
242                     users[i].getSubscriptions();
243                 for (int j = 0; j < subscriptions.length; j++) {
244                     writer.print(" ");
245                     writer.println(subscriptions[j]);
246                     writer.print(" ");
247                     writer.println("</subscription>");
248                 }
249                 writer.print(" ");
250                 writer.println("</user>");
251             }
252
253             // Print the file epilog
254
writer.println("</database>");
255
256             // Check for errors that occurred while printing
257
if (writer.checkError()) {
258                 writer.close();
259                 fileNew.delete();
260                 throw new IOException JavaDoc
261                     ("Saving database to '" + pathname + "'");
262             }
263             writer.close();
264             writer = null;
265
266         } catch (IOException JavaDoc e) {
267
268             if (writer != null) {
269                 writer.close();
270             }
271             fileNew.delete();
272             throw e;
273
274         }
275
276
277         // Perform the required renames to permanently save this file
278
File JavaDoc fileOrig = new File JavaDoc(pathname);
279         File JavaDoc fileOld = new File JavaDoc(pathnameOld);
280         if (fileOrig.exists()) {
281             fileOld.delete();
282             if (!fileOrig.renameTo(fileOld)) {
283                 throw new IOException JavaDoc
284                     ("Renaming '" + pathname + "' to '" + pathnameOld + "'");
285             }
286         }
287         if (!fileNew.renameTo(fileOrig)) {
288             if (fileOld.exists()) {
289                 fileOld.renameTo(fileOrig);
290             }
291             throw new IOException JavaDoc
292                 ("Renaming '" + pathnameNew + "' to '" + pathname + "'");
293         }
294         fileOld.delete();
295
296     }
297
298
299 }
300
301
302 /**
303  * Digester object creation factory for subscription instances.
304  */

305 class MemorySubscriptionCreationFactory implements ObjectCreationFactory {
306
307     private Digester digester = null;
308
309     public Digester getDigester() {
310         return (this.digester);
311     }
312
313     public void setDigester(Digester digester) {
314         this.digester = digester;
315     }
316
317     public Object JavaDoc createObject(Attributes JavaDoc attributes) {
318         String JavaDoc host = attributes.getValue("host");
319         User user = (User) digester.peek();
320         Subscription subscription = user.createSubscription(host);
321         String JavaDoc autoConnect = attributes.getValue("autoConnect");
322         if (autoConnect == null) {
323             autoConnect = "false";
324         }
325         if ("true".equalsIgnoreCase(autoConnect) ||
326             "yes".equalsIgnoreCase(autoConnect)) {
327             subscription.setAutoConnect(true);
328         } else {
329             subscription.setAutoConnect(false);
330         }
331         subscription.setPassword(attributes.getValue("password"));
332         subscription.setType(attributes.getValue("type"));
333         subscription.setUsername(attributes.getValue("username"));
334         return (subscription);
335     }
336
337 }
338
339
340 /**
341  * Digester object creation factory for user instances.
342  */

343 class MemoryUserCreationFactory implements ObjectCreationFactory {
344
345     public MemoryUserCreationFactory(MemoryUserDatabase database) {
346         this.database = database;
347     }
348
349     private MemoryUserDatabase database = null;
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 JavaDoc createObject(Attributes JavaDoc attributes) {
362         String JavaDoc username = attributes.getValue("username");
363         User user = database.createUser(username);
364         user.setFromAddress(attributes.getValue("fromAddress"));
365         user.setFullName(attributes.getValue("fullName"));
366         user.setPassword(attributes.getValue("password"));
367         user.setReplyToAddress(attributes.getValue("replyToAddress"));
368         return (user);
369     }
370
371 }
372
Popular Tags