2009/05/20 - Apache Shale has been retired.

For more information, please explore the Attic.

View Javadoc

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  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      private ServletContext context = null;
82  
83  
84      /***
85       * The {@link MemoryUserDatabase} object we construct and make available.
86       */
87      private MemoryUserDatabase database = null;
88  
89  
90      /***
91       * Logging output for this plug in instance.
92       */
93      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     private String pathname = "/WEB-INF/database.xml";
104 
105     public String getPathname() {
106         return (this.pathname);
107     }
108 
109     public void setPathname(String pathname) {
110         this.pathname = pathname;
111     }
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         log.info("Finalizing memory database plug in");
126 
127         if (database != null) {
128             try {
129                 database.close();
130             } catch (Exception e) {
131                 log.error("Closing memory database", e);
132             }
133         }
134 
135 	context.removeAttribute(DATABASE_KEY);
136         context.removeAttribute(PROTOCOLS_KEY);
137         database = null;
138         context = null;
139 
140     }
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         log.info("Initializing memory database plug in from '" +
153                  pathname + "'");
154 
155         // Remember our associated ServletContext
156         this.context = event.getServletContext();
157 
158         // Construct a new database and make it available
159         database = new MemoryUserDatabase();
160         try {
161             String path = calculatePath();
162             if (log.isDebugEnabled()) {
163                 log.debug(" Loading database from '" + path + "'");
164             }
165             database.setPathname(path);
166             database.open();
167         } catch (Exception e) {
168             log.error("Opening memory database", e);
169             throw new IllegalStateException("Cannot load database from '" +
170                                             pathname + "': " + e);
171         }
172         context.setAttribute(DATABASE_KEY, database);
173 
174         // Cache the selection items for protocols
175         SelectItem protocols[] = new SelectItem[2];
176         protocols[0] = new SelectItem("imap", "IMAP Protocol");
177         protocols[1] = new SelectItem("pop3", "POP3 Protocol");
178         context.setAttribute(PROTOCOLS_KEY, protocols);
179 
180     }
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         String path = context.getRealPath(pathname);
196         if (path != null) {
197             return (path);
198         }
199 
200         // Does a copy of this file already exist in our temporary directory
201         File dir = (File)
202             context.getAttribute("javax.servlet.context.tempdir");
203         File file = new File(dir, "struts-example-database.xml");
204         if (file.exists()) {
205             return (file.getAbsolutePath());
206         }
207 
208         // Copy the static resource to a temporary file and return its path
209         InputStream is =
210             context.getResourceAsStream(pathname);
211         BufferedInputStream bis = new BufferedInputStream(is, 1024);
212         FileOutputStream os =
213             new FileOutputStream(file);
214         BufferedOutputStream bos = new BufferedOutputStream(os, 1024);
215         byte buffer[] = new byte[1024];
216         while (true) {
217             int n = bis.read(buffer);
218             if (n <= 0) {
219                 break;
220             }
221             bos.write(buffer, 0, n);
222         }
223         bos.close();
224         bis.close();
225         return (file.getAbsolutePath());
226 
227     }
228 
229 
230 }