/*
 * 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 $
 */

package mailreader2;

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 ApplicationListener 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>
     *
     * @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());

    }


}
