| /* |
| * Copyright 1999-2002,2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * $Id: ApplicationListener.java 372087 2006-01-25 03:38:42Z craigmcc $ |
| */ |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUserDatabase; |
| |
| import javax.servlet.ServletContext; |
| import javax.servlet.ServletContextEvent; |
| import javax.servlet.ServletContextListener; |
| import java.io.*; |
| |
| /** |
| * <p><code>ServletContextListener</code> that initializes and finalizes the |
| * persistent storage of User and Subscription information for the Struts |
| * Demonstration Application, using an in-memory database backed by an XML |
| * file.</p> |
| * <p/> |
| * <p><strong>IMPLEMENTATION WARNING</strong> - If this web application is run |
| * from a WAR file, or in another environment where reading and writing of the |
| * web application resource is impossible, the initial contents will be copied |
| * to a file in the web application temporary directory provided by the |
| * container. This is for demonstration purposes only - you should |
| * <strong>NOT</strong> assume that files written here will survive a restart |
| * of your servlet container.</p> |
| * <p/> |
| * <p>This class was borrowed from the Shale Mailreader. Changes were:</p> |
| * <p/> |
| * <ul> |
| * <p/> |
| * <li>Path to database.xml (under classes here). </li> |
| * <p/> |
| * <li>Class to store protocol list (an array here). </li> |
| * <p/> |
| * </ul> |
| * <p/> |
| * DEVELOPMENT NOTE - Another approach would be to instantiate the database via Spring. |
| * </p> |
| */ |
| |
| public final class DatabaseListener implements ServletContextListener { |
| |
| // ------------------------------------------------------ Manifest Constants |
| |
| |
| /** |
| * <p>Appication scope attribute key under which the in-memory version of |
| * our database is stored.</p> |
| */ |
| public static final String DATABASE_KEY = "database"; |
| |
| |
| /** |
| * <p>Application scope attribute key under which the valid selection |
| * items for the protocol property is stored.</p> |
| */ |
| public static final String PROTOCOLS_KEY = "protocols"; |
| |
| // ------------------------------------------------------ Instance Variables |
| |
| |
| /** |
| * <p>The <code>ServletContext</code> for this web application.</p> |
| */ |
| private ServletContext context = null; |
| |
| |
| /** |
| * The {@link MemoryUserDatabase} object we construct and make available. |
| */ |
| private MemoryUserDatabase database = null; |
| |
| |
| /** |
| * <p>Logging output for this plug in instance.</p> |
| */ |
| private Log log = LogFactory.getLog(this.getClass()); |
| |
| // ------------------------------------------------------------- Properties |
| |
| |
| /** |
| * <p>The web application resource path of our persistent database storage |
| * file.</p> |
| */ |
| private String pathname = "/WEB-INF/classes/database.xml"; |
| |
| /** |
| * <p>Return the application resource path to the database.</p> |
| * |
| * @return application resource path path to the database |
| */ |
| public String getPathname() { |
| return (this.pathname); |
| } |
| |
| /** |
| * <p>Set the application resource path to the database.</p> |
| * |
| * @param pathname to the database |
| */ |
| public void setPathname(String pathname) { |
| this.pathname = pathname; |
| } |
| |
| // ------------------------------------------ ServletContextListener Methods |
| |
| |
| /** |
| * <p>Gracefully shut down this database, releasing any resources that |
| * were allocated at initialization.</p> |
| * |
| * @param event ServletContextEvent to process |
| */ |
| public void contextDestroyed(ServletContextEvent event) { |
| |
| log.info("Finalizing memory database plug in"); |
| |
| if (database != null) { |
| try { |
| database.close(); |
| } catch (Exception e) { |
| log.error("Closing memory database", e); |
| } |
| } |
| |
| context.removeAttribute(DATABASE_KEY); |
| context.removeAttribute(PROTOCOLS_KEY); |
| database = null; |
| context = null; |
| |
| } |
| |
| |
| /** |
| * <p>Initialize and load our initial database from persistent |
| * storage.</p> |
| * |
| * @param event The context initialization event |
| */ |
| public void contextInitialized(ServletContextEvent event) { |
| |
| log.info("Initializing memory database plug in from '" + |
| pathname + "'"); |
| |
| // Remember our associated ServletContext |
| this.context = event.getServletContext(); |
| |
| // Construct a new database and make it available |
| database = new MemoryUserDatabase(); |
| try { |
| String path = calculatePath(); |
| if (log.isDebugEnabled()) { |
| log.debug(" Loading database from '" + path + "'"); |
| } |
| database.setPathname(path); |
| database.open(); |
| } catch (Exception e) { |
| log.error("Opening memory database", e); |
| throw new IllegalStateException("Cannot load database from '" + |
| pathname + "': " + e); |
| } |
| context.setAttribute(DATABASE_KEY, database); |
| |
| } |
| |
| // -------------------------------------------------------- Private Methods |
| |
| |
| /** |
| * <p>Calculate and return an absolute pathname to the XML file to contain |
| * our persistent storage information.</p> |
| * |
| * @return Absolute path to XML file. |
| * @throws Exception if an input/output error occurs |
| */ |
| private String calculatePath() throws Exception { |
| |
| // Can we access the database via file I/O? |
| String path = context.getRealPath(pathname); |
| if (path != null) { |
| return (path); |
| } |
| |
| // Does a copy of this file already exist in our temporary directory |
| File dir = (File) |
| context.getAttribute("javax.servlet.context.tempdir"); |
| File file = new File(dir, "struts-example-database.xml"); |
| if (file.exists()) { |
| return (file.getAbsolutePath()); |
| } |
| |
| // Copy the static resource to a temporary file and return its path |
| InputStream is = |
| context.getResourceAsStream(pathname); |
| BufferedInputStream bis = new BufferedInputStream(is, 1024); |
| FileOutputStream os = |
| new FileOutputStream(file); |
| BufferedOutputStream bos = new BufferedOutputStream(os, 1024); |
| byte buffer[] = new byte[1024]; |
| while (true) { |
| int n = bis.read(buffer); |
| if (n <= 0) { |
| break; |
| } |
| bos.write(buffer, 0, n); |
| } |
| bos.close(); |
| bis.close(); |
| return (file.getAbsolutePath()); |
| |
| } |
| |
| |
| } |