1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts.webapp.example2.memory;
19
20
21 import java.io.BufferedInputStream;
22 import java.io.BufferedOutputStream;
23 import java.io.File;
24 import java.io.FileOutputStream;
25 import java.io.InputStream;
26 import java.util.ArrayList;
27 import javax.servlet.ServletException;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.struts.action.ActionServlet;
31 import org.apache.struts.action.PlugIn;
32 import org.apache.struts.config.ModuleConfig;
33 import org.apache.struts.util.LabelValueBean;
34 import org.apache.struts.webapp.example2.Constants;
35
36 /***
37 * <p><strong>MemoryDatabasePlugIn</strong> initializes and finalizes the
38 * persistent storage of User and Subscription information for the Struts
39 * Demonstration Application, using an in-memory database backed by an
40 * XML file.</p>
41 *
42 * <p><strong>IMPLEMENTATION WARNING</strong> - If this web application is run
43 * from a WAR file, or in another environment where reading and writing of the
44 * web application resource is impossible, the initial contents will be copied
45 * to a file in the web application temporary directory provided by the
46 * container. This is for demonstration purposes only - you should
47 * <strong>NOT</strong> assume that files written here will survive a restart
48 * of your servlet container.</p>
49 *
50 * @author Craig R. McClanahan
51 * @version $Rev: 421494 $ $Date: 2006-07-12 20:55:17 -0700 (Wed, 12 Jul 2006) $
52 */
53
54 public final class MemoryDatabasePlugIn implements PlugIn {
55
56
57
58
59
60 /***
61 * The {@link MemoryUserDatabase} object we construct and make available.
62 */
63 private MemoryUserDatabase database = null;
64
65
66 /***
67 * Logging output for this plug in instance.
68 */
69 private Log log = LogFactory.getLog(this.getClass());
70
71
72 /***
73 * The {@link ActionServlet} owning this application.
74 */
75 private ActionServlet servlet = null;
76
77
78
79
80
81 /***
82 * The web application resource path of our persistent database
83 * storage file.
84 */
85 private String pathname = "/WEB-INF/database.xml";
86
87 public String getPathname() {
88 return (this.pathname);
89 }
90
91 public void setPathname(String pathname) {
92 this.pathname = pathname;
93 }
94
95
96
97
98
99 /***
100 * Gracefully shut down this database, releasing any resources
101 * that were allocated at initialization.
102 */
103 public void destroy() {
104
105 log.info("Finalizing memory database plug in");
106
107 if (database != null) {
108 try {
109 database.close();
110 } catch (Exception e) {
111 log.error("Closing memory database", e);
112 }
113 }
114
115 servlet.getServletContext().removeAttribute(Constants.DATABASE_KEY);
116 database = null;
117 servlet = null;
118 database = null;
119
120 }
121
122
123 /***
124 * Initialize and load our initial database from persistent storage.
125 *
126 * @param servlet The ActionServlet for this web application
127 * @param config The ApplicationConfig for our owning module
128 *
129 * @exception ServletException if we cannot configure ourselves correctly
130 */
131 public void init(ActionServlet servlet, ModuleConfig config)
132 throws ServletException {
133
134 log.info("Initializing memory database plug in from '" +
135 pathname + "'");
136
137
138 this.servlet = servlet;
139
140
141 database = new MemoryUserDatabase();
142 try {
143 String path = calculatePath();
144 if (log.isDebugEnabled()) {
145 log.debug(" Loading database from '" + path + "'");
146 }
147 database.setPathname(path);
148 database.open();
149 } catch (Exception e) {
150 log.error("Opening memory database", e);
151 throw new ServletException("Cannot load database from '" +
152 pathname + "'", e);
153 }
154
155
156 servlet.getServletContext().setAttribute(Constants.DATABASE_KEY,
157 database);
158
159
160 setupCache(servlet, config);
161
162 }
163
164
165
166
167
168
169
170
171 /***
172 * <p>Cache commonly required data as servlet context attributes.</p>
173 *
174 * @param servlet The <code>ActionServlet</code> instance running
175 * this webapp
176 * @param config The <code>ModuleConfig</code> for this application module
177 */
178 protected void setupCache(ActionServlet servlet, ModuleConfig config) {
179
180
181 ArrayList serverTypes = new ArrayList();
182 serverTypes.add(new LabelValueBean("IMAP Protocol", "imap"));
183 serverTypes.add(new LabelValueBean("POP3 Protocol", "pop3"));
184 servlet.getServletContext().setAttribute("serverTypes", serverTypes);
185
186 }
187
188
189
190
191
192
193
194 /***
195 * Calculate and return an absolute pathname to the XML file to contain
196 * our persistent storage information.
197 *
198 * @exception Exception if an input/output error occurs
199 */
200 private String calculatePath() throws Exception {
201
202
203 String path = servlet.getServletContext().getRealPath(pathname);
204 if (path != null) {
205 return (path);
206 }
207
208
209 File dir = (File)
210 servlet.getServletContext().getAttribute
211 ("javax.servlet.context.tempdir");
212 File file = new File(dir, "struts-example-database.xml");
213 if (file.exists()) {
214 return (file.getAbsolutePath());
215 }
216
217
218 InputStream is =
219 servlet.getServletContext().getResourceAsStream(pathname);
220 BufferedInputStream bis = new BufferedInputStream(is, 1024);
221 FileOutputStream os =
222 new FileOutputStream(file);
223 BufferedOutputStream bos = new BufferedOutputStream(os, 1024);
224 byte buffer[] = new byte[1024];
225 while (true) {
226 int n = bis.read(buffer);
227 if (n <= 0) {
228 break;
229 }
230 bos.write(buffer, 0, n);
231 }
232 bos.close();
233 bis.close();
234 return (file.getAbsolutePath());
235
236 }
237
238
239 }