Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ApplicationListener |
|
| 3.2;3.2 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to you under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | * | |
17 | * $Id: ApplicationListener.java 464373 2006-10-16 04:21:54Z rahul $ | |
18 | */ | |
19 | ||
20 | package org.apache.shale.examples.mailreader; | |
21 | ||
22 | import java.io.BufferedInputStream; | |
23 | import java.io.BufferedOutputStream; | |
24 | import java.io.File; | |
25 | import java.io.FileOutputStream; | |
26 | import java.io.InputStream; | |
27 | ||
28 | import javax.faces.model.SelectItem; | |
29 | ||
30 | import javax.servlet.ServletContext; | |
31 | import javax.servlet.ServletContextEvent; | |
32 | import javax.servlet.ServletContextListener; | |
33 | import javax.servlet.ServletException; | |
34 | ||
35 | import org.apache.commons.logging.Log; | |
36 | import org.apache.commons.logging.LogFactory; | |
37 | ||
38 | import org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUserDatabase; | |
39 | ||
40 | /** | |
41 | * <p><code>ServletContextListener</code> that initializes and finalizes the | |
42 | * persistent storage of User and Subscription information for the Struts | |
43 | * Demonstration Application, using an in-memory database backed by an | |
44 | * XML file.</p> | |
45 | * | |
46 | * <p><strong>IMPLEMENTATION WARNING</strong> - If this web application is run | |
47 | * from a WAR file, or in another environment where reading and writing of the | |
48 | * web application resource is impossible, the initial contents will be copied | |
49 | * to a file in the web application temporary directory provided by the | |
50 | * container. This is for demonstration purposes only - you should | |
51 | * <strong>NOT</strong> assume that files written here will survive a restart | |
52 | * of your servlet container.</p> | |
53 | */ | |
54 | ||
55 | 0 | public final class ApplicationListener implements ServletContextListener { |
56 | ||
57 | ||
58 | // ------------------------------------------------------ Manifest Constants | |
59 | ||
60 | ||
61 | /** | |
62 | * <p>Appication scope attribute key under which the in-memory | |
63 | * version of our database is stored.</p> | |
64 | */ | |
65 | public static final String DATABASE_KEY = "database"; | |
66 | ||
67 | ||
68 | /** | |
69 | * <p>Application scope attribute key under which the valid | |
70 | * selection items for the protocol property is stored.</p> | |
71 | */ | |
72 | public static final String PROTOCOLS_KEY = "protocols"; | |
73 | ||
74 | ||
75 | // ------------------------------------------------------ Instance Variables | |
76 | ||
77 | ||
78 | /** | |
79 | * <p>The <code>ServletContext</code> for this web application.</p> | |
80 | */ | |
81 | 0 | private ServletContext context = null; |
82 | ||
83 | ||
84 | /** | |
85 | * The {@link MemoryUserDatabase} object we construct and make available. | |
86 | */ | |
87 | 0 | private MemoryUserDatabase database = null; |
88 | ||
89 | ||
90 | /** | |
91 | * Logging output for this plug in instance. | |
92 | */ | |
93 | 0 | private Log log = LogFactory.getLog(this.getClass()); |
94 | ||
95 | ||
96 | // ------------------------------------------------------------- Properties | |
97 | ||
98 | ||
99 | /** | |
100 | * The web application resource path of our persistent database | |
101 | * storage file. | |
102 | */ | |
103 | 0 | private String pathname = "/WEB-INF/database.xml"; |
104 | ||
105 | public String getPathname() { | |
106 | 0 | return (this.pathname); |
107 | } | |
108 | ||
109 | public void setPathname(String pathname) { | |
110 | 0 | this.pathname = pathname; |
111 | 0 | } |
112 | ||
113 | ||
114 | // ------------------------------------------ ServletContextListener Methods | |
115 | ||
116 | ||
117 | /** | |
118 | * <p>Gracefully shut down this database, releasing any resources | |
119 | * that were allocated at initialization.</p> | |
120 | * | |
121 | * @param event ServletContextEvent to process | |
122 | */ | |
123 | public void contextDestroyed(ServletContextEvent event) { | |
124 | ||
125 | 0 | log.info("Finalizing memory database plug in"); |
126 | ||
127 | 0 | if (database != null) { |
128 | try { | |
129 | 0 | database.close(); |
130 | 0 | } catch (Exception e) { |
131 | 0 | log.error("Closing memory database", e); |
132 | 0 | } |
133 | } | |
134 | ||
135 | 0 | context.removeAttribute(DATABASE_KEY); |
136 | 0 | context.removeAttribute(PROTOCOLS_KEY); |
137 | 0 | database = null; |
138 | 0 | context = null; |
139 | ||
140 | 0 | } |
141 | ||
142 | ||
143 | /** | |
144 | * <p>Initialize and load our initial database from persistent storage.</p> | |
145 | * | |
146 | * @param event The context initialization event | |
147 | * | |
148 | * @exception ServletException if we cannot configure ourselves correctly | |
149 | */ | |
150 | public void contextInitialized(ServletContextEvent event) { | |
151 | ||
152 | 0 | log.info("Initializing memory database plug in from '" + |
153 | pathname + "'"); | |
154 | ||
155 | // Remember our associated ServletContext | |
156 | 0 | this.context = event.getServletContext(); |
157 | ||
158 | // Construct a new database and make it available | |
159 | 0 | database = new MemoryUserDatabase(); |
160 | try { | |
161 | 0 | String path = calculatePath(); |
162 | 0 | if (log.isDebugEnabled()) { |
163 | 0 | log.debug(" Loading database from '" + path + "'"); |
164 | } | |
165 | 0 | database.setPathname(path); |
166 | 0 | database.open(); |
167 | 0 | } catch (Exception e) { |
168 | 0 | log.error("Opening memory database", e); |
169 | 0 | throw new IllegalStateException("Cannot load database from '" + |
170 | pathname + "': " + e); | |
171 | 0 | } |
172 | 0 | context.setAttribute(DATABASE_KEY, database); |
173 | ||
174 | // Cache the selection items for protocols | |
175 | 0 | SelectItem protocols[] = new SelectItem[2]; |
176 | 0 | protocols[0] = new SelectItem("imap", "IMAP Protocol"); |
177 | 0 | protocols[1] = new SelectItem("pop3", "POP3 Protocol"); |
178 | 0 | context.setAttribute(PROTOCOLS_KEY, protocols); |
179 | ||
180 | 0 | } |
181 | ||
182 | ||
183 | // -------------------------------------------------------- Private Methods | |
184 | ||
185 | ||
186 | /** | |
187 | * Calculate and return an absolute pathname to the XML file to contain | |
188 | * our persistent storage information. | |
189 | * | |
190 | * @exception Exception if an input/output error occurs | |
191 | */ | |
192 | private String calculatePath() throws Exception { | |
193 | ||
194 | // Can we access the database via file I/O? | |
195 | 0 | String path = context.getRealPath(pathname); |
196 | 0 | if (path != null) { |
197 | 0 | return (path); |
198 | } | |
199 | ||
200 | // Does a copy of this file already exist in our temporary directory | |
201 | 0 | File dir = (File) |
202 | context.getAttribute("javax.servlet.context.tempdir"); | |
203 | 0 | File file = new File(dir, "struts-example-database.xml"); |
204 | 0 | if (file.exists()) { |
205 | 0 | return (file.getAbsolutePath()); |
206 | } | |
207 | ||
208 | // Copy the static resource to a temporary file and return its path | |
209 | 0 | InputStream is = |
210 | context.getResourceAsStream(pathname); | |
211 | 0 | BufferedInputStream bis = new BufferedInputStream(is, 1024); |
212 | 0 | FileOutputStream os = |
213 | new FileOutputStream(file); | |
214 | 0 | BufferedOutputStream bos = new BufferedOutputStream(os, 1024); |
215 | 0 | byte buffer[] = new byte[1024]; |
216 | while (true) { | |
217 | 0 | int n = bis.read(buffer); |
218 | 0 | if (n <= 0) { |
219 | 0 | break; |
220 | } | |
221 | 0 | bos.write(buffer, 0, n); |
222 | 0 | } |
223 | 0 | bos.close(); |
224 | 0 | bis.close(); |
225 | 0 | return (file.getAbsolutePath()); |
226 | ||
227 | } | |
228 | ||
229 | ||
230 | } |