Differences between revisions 7 and 8
Revision 7 as of 2006-10-04 22:25:22
Size: 9159
Editor: DonaldMcLean
Comment: Added new initialization feature
Revision 8 as of 2009-09-20 22:12:40
Size: 9159
Editor: localhost
Comment: converted to 1.6 markup
No differences found!

Source for DatabaseManager class

/*
 *  Copyright (c) 2006, Donald McLean
 *
 *  This software is provided 'as-is', without any express or implied warranty.
 *  In no event will the authors be held liable for any damages arising from the
 *  use of this software.
 *
 *  Permission is granted to anyone to use this software for any purpose, including
 *  commercial applications, and to alter it and redistribute it freely, subject to
 *  the following restrictions:
 *
 *     1. The origin of this software must not be misrepresented; you must not claim
 *        that you wrote the original software. If you use this software in a product,
 *        an acknowledgment in the product documentation would be appreciated but is
 *        not required.
 *
 *    2. Altered source versions must be plainly marked as such, and must not be
 *       misrepresented as being the original software.
 *
 *    3. This notice may not be removed or altered from any source distribution.
 *
 */
package your.package.here;

import org.jdom.Document;
import org.jdom.Element;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.Driver;
import java.sql.PreparedStatement;
import java.util.List;
import java.util.HashSet;
import java.util.Properties;

public class DatabaseManager
{
    public DatabaseManager(String databaseName)
    {
        instance = this;

        Document document = StaugUtilities.getXMLResource(getClass());
        Element root = document.getRootElement();

        String dbRoot = root.getChildText("Root");
        File dbFile = new File(dbRoot + databaseName);

        connectToDatabase(dbFile);

        if (createFlag)
        {
            createTables(root);
            runInitializations(root);
        }
        createHibernateSessionFactory(root);
    }

    public static DatabaseManager getInstance()
    {
        if (instance == null)
        {
            new DatabaseManager("LunchtimeDB");
        }

        return instance;
    }

    public Connection getConnection()
    {
        return connection;
    }

    public Session getMainSession()
    {
        if (mainSession == null)
        {
            mainSession = (Session)sessions.openSession(connection);
        }

        return mainSession;
    }

    public void addListener (DBEventListener listener)
    {
        listeners.add(listener);
    }

    public void close()
    {
        sessions.close();
        sessions = null;
        try
        {
            connection.close();
            connection = null;
        }
        catch (SQLException e)
        {
            System.out.println("[DatabaseManager.close] Unable to close connection.");
        }

        instance = null;

        fireEvent();
        listeners = null;
    }

    private Connection connection;
    private SessionFactory sessions;
    private Session mainSession = null;
    private boolean createFlag = false;

    private HashSet<DBEventListener> listeners = new HashSet<DBEventListener>();

    private void createTables(Element root)
    {
        Element createElement = root.getChild("createSql");
        List createElements = createElement.getChildren();

        String sql = null;
        try
        {
            Statement statement = connection.createStatement();
            connection.setAutoCommit(false);
            for (int i = 0; i < createElements.size(); i++)
            {
                Element element = (Element) createElements.get(i);
                sql = element.getText();
                statement.execute(sql);
            }

            connection.commit();
            connection.setAutoCommit(true);
        }
        catch (SQLException e)
        {
            System.out.println("[DatabaseManager.createTables] Failed to execute: '" +
                               sql + "'.");
            e.printStackTrace();
        }
    }

    private void runInitializations(Element root)
    {
        try
        {
            connection.setAutoCommit(false);
            PreparedStatement statement = connection.prepareStatement("call SYSCS_UTIL.SYSCS_IMPORT_DATA " +
                    "(null, ?, ?, null, ?, null, null, null, 0)");

            Element initializations = root.getChild("Initialization");

            List loadEntries = initializations.getChildren("Load");
            for (int i = 0; i < loadEntries.size(); i++)
            {
                Element next = (Element) loadEntries.get(i);

                statement.setString(1, next.getChildText("Table"));
                statement.setString(2, next.getChildText("Columns"));
                String fileName = next.getChildText("File");
                File file = new File(initDirectory, fileName);
                if (! file.exists())
                {
                    System.out.println("[DatabaseManager.runInitializations] file '" +
                                       file.getAbsolutePath() + "' not found.");
                    continue;
                }
                statement.setString(3, file.getAbsolutePath());

                boolean result = statement.execute();
                connection.commit();
            }

            connection.commit();
            connection.setAutoCommit(true);
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    private void connectToDatabase(File dbFile)
    {
        try
        {
            String url = createURL(dbFile);
            connection = driver.connect(url, null);
        }
        catch (Exception e)
        {
            System.out.println("[ApplicationDatabase : ApplicationDatabase]: unable to create database.");
            e.printStackTrace();
        }
    }

    /**
     * @param dbFile file where the database will be opened.
     * @throws java.io.IOException - shouldn't occur.
     * @return String URL for the given file.
     */
    private String createURL(File dbFile)
            throws IOException
    {
        String dbURL = "jdbc:derby:" + dbFile.getCanonicalPath();
        if (!dbFile.exists())
        {
            createFlag = true;
            dbURL += ";create=true";
        }

        System.out.println("[ApplicationDatabase.createURL] URL is '" + dbURL + "'.cn");
        return dbURL;
    }

    private void createHibernateSessionFactory(Element root)
    {
        HashSet<Class> classes = collectFeatureClasses(root);

        Properties properties = new Properties();
        properties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
        properties.put("hibernate.show_sql", "true");

        Configuration cfg = new Configuration();
        cfg.addProperties(properties);

        for(Class aClass : classes)
        {
            System.out.println("[ApplicationDatabase.createHibernateSessionFactory] adding clas '" +
                               aClass.getName() + "'.");
            cfg.addClass(aClass);
        }

        sessions = cfg.buildSessionFactory();
    }

    private HashSet<Class> collectFeatureClasses(Element root)
    {
        HashSet<Class> result = new HashSet<Class>();

        Element classesElement = root.getChild("Classes");
        List classElements = classesElement.getChildren();

        for (int i = 0; i < classElements.size(); i++)
        {
            Element element = (Element) classElements.get(i);
            result.add(StaugUtilities.loadClass(element.getText()));
        }

        return result;
    }

    private void fireEvent()
    {
        for(DBEventListener listener : listeners)
        {
            listener.dbClose();
        }
    }

    static private File initDirectory;
    static private Driver driver;
    static private DatabaseManager instance = null;

    public static void setContext(String contextName)
    {
        // this function set the 'initDirectory' to the location of the Inititialization files.
        throw new IllegalStateException("You must implement this function.");
    }

    static
    {
        try
        {
            driver = (Driver) Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
            System.out.println("[ApplicationDatabase : static]: driver loaded successfuly.");
        }
        catch (Exception e)
        {
            System.out.println("[ApplicationDatabase : static]: unable to load driver.");
            e.printStackTrace();
        }
    }
}

DatabaseManagerSource (last edited 2009-09-20 22:12:40 by localhost)