Package org.ow2.easybeans.component.hsqldb

Source Code of org.ow2.easybeans.component.hsqldb.HSQLDBComponent

/**
* EasyBeans
* Copyright (C) 2006 Bull S.A.S.
* Contact: easybeans@ow2.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
* USA
*
* --------------------------------------------------------------------------
* $Id: HSQLDBComponent.java 5752 2011-03-01 12:48:22Z benoitf $
* --------------------------------------------------------------------------
*/

package org.ow2.easybeans.component.hsqldb;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;

import org.hsqldb.DatabaseManager;
import org.hsqldb.Server;
import org.hsqldb.ServerConstants;
import org.ow2.easybeans.component.api.EZBComponentException;
import org.ow2.easybeans.component.itf.EmbeddedDBComponent;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
* Allows to start an embedded HSQLDB server.
* @author Florent Benoit
*/
public class HSQLDBComponent implements EmbeddedDBComponent {

    /**
     * Logger.
     */
    private static Log logger = LogFactory.getLog(HSQLDBComponent.class);

    /**
     * List of users.
     */
    private List<User> users = null;

    /**
     * Name of database.
     */
    private String databaseName = null;

    /**
     * Default port number.
     */
    private static final String DEFAULT_PORT = "9001";

    /**
     * Default port number.
     */
    private static final String DEFAULT_HOST = "localhost";

    /**
     * Sleep value.
     */
    private static final int SLEEP_VALUE = 100;

    /**
     * Max retry number.
     */
    private static final int MAX_RETRY_NB = 50;

    /**
     * port number used.
     */
    private String portNumber = null;

    /**
     * Hostname to use.
     */
    private String hostname = null;

    /**
     * HsqlDB server.
     */
    private Server server = null;

    /**
     * String path.
     */
    private String path = null;

    /**
     * Default constructor.<br>
     * Use default port number + hostname.
     */
    public HSQLDBComponent() {
        this.portNumber = DEFAULT_PORT;
        this.hostname = DEFAULT_HOST;
    }

    /**
     * Init method.<br/> This method is called before the start method.
     * @throws EZBComponentException if the initialization has failed.
     */
    public void init() throws EZBComponentException {

        this.server = new Server();
        // Remove all traces if level != DEBUG
        if (!logger.isDebugEnabled()) {
            this.server.setLogWriter(null);
            this.server.setErrWriter(null);
            this.server.setSilent(true);
            this.server.setTrace(false);
            this.server.setLogWriter(null);
        } else {
            // Enable all traces : verbose mode (as user needs DEBUG)
            this.server.setSilent(false);
            this.server.setTrace(true);
        }

        // Use a specified path or go in temp directory ?
        String baseDir = null;
        if (this.path != null) {
            baseDir = this.path + File.separator + this.databaseName;
        } else {
            baseDir = System.getProperty("java.io.tmpdir") + File.separator + "easybeans" + File.separator + "hsqldb"
            + File.separator + this.databaseName;
        }

        String pString = "";
        if (this.portNumber != null) {
            pString = ";port=" + this.portNumber;
        }
        String serverProps = "database.0=" + baseDir + ";dbname.0=" + this.databaseName + pString;
        logger.debug("Server properties = {0}", serverProps);
        this.server.putPropertiesFromString(serverProps);

        // Specify hostname to use
        this.server.setAddress(this.hostname);

        try {
            Class.forName("org.hsqldb.jdbcDriver");
        } catch (ClassNotFoundException e) {
            throw new EZBComponentException("Cannot access to HSQL Driver 'org.hsqldb.jdbcDriver'.", e);
        }

    }

    /**
     * Start method.<br/> This method is called after the init method.
     * @throws EZBComponentException if the start has failed.
     */
    @SuppressWarnings("boxing")
    public void start() throws EZBComponentException {

        logger.info("Starting ''{0}'' ''{1}'' on port ''{2}''", this.server.getProductName(), this.server.getProductVersion(),
                this.portNumber);

        this.server.start();

        // Wait the start
        int retryNb = 0;
        while (this.server.getState() != ServerConstants.SERVER_STATE_ONLINE) {
            try {
                Thread.sleep(SLEEP_VALUE);
            } catch (InterruptedException ie) {
                logger.error("Cannot wait that the service is online", ie);
            }
            // Error if server state is "SHUTDOWN" during a long period
            // Maybe strange but 'SHUTDOWN' state seems to be an intermediate
            // state during startup
            retryNb++;
            if (this.server.getState() == ServerConstants.SERVER_STATE_SHUTDOWN && retryNb >= MAX_RETRY_NB) {
                Throwable t = this.server.getServerError();
                throw new EZBComponentException("Cannot start the server. The server has not started and is shutdown.", t);
            }
            logger.debug("retry= {0}, serverState= {1}", retryNb, this.server.getState());
        }

        String connURL = "jdbc:hsqldb:hsql://" + this.hostname + ":" + this.portNumber + "/" + this.databaseName;
        logger.info("{0} started with URL {1}", this.server.getProductName(), connURL);

        Connection conn = null;
        Statement st = null;

        try {
            conn = DriverManager.getConnection(connURL, "sa", "");
        } catch (SQLException e) {
            throw new EZBComponentException("Cannot access to HSQL", e);
        }

        try {
            st = conn.createStatement();
        } catch (SQLException e) {
            try {
                conn.close();
            } catch (SQLException connEx) {
                logger.error("Error while closing connection object", connEx);
            }
            throw new EZBComponentException("Cannot access to HSQL", e);
        }



        // Drop users before recreating it
        User user = null;
        String userName = null;
        String password = null;
        ResultSet rs = null;
        for (Iterator<User> it = this.users.iterator(); it.hasNext();) {
            user = it.next();
            try {
                password = user.getPassword();
                userName = user.getUserName();
                logger.debug("Dropping and adding user {0} with password {1}.", userName, password);
                try {
                    rs = st.executeQuery("DROP USER " + userName);
                } catch (SQLException e) {
                    logger.debug("User {0} doesn't exists", userName, e);
                }
                rs = st.executeQuery("Create USER " + userName + " PASSWORD " + password + " ADMIN");
                rs.close();
            } catch (SQLException e) {
                logger.error("Error while creating/adding user", e);
            }

        }

        try {
            st.close();
            conn.close();
        } catch (SQLException e) {
            logger.error("Error while closing statement object", e);
        }

    }

    /**
     * Gets the list of users.
     * @return the list of users.
     */
    public List<User> getUsers() {
        return this.users;
    }

    /**
     * Set the list of users.
     * @param users the list of users.
     */
    public void setUsers(final List<User> users) {
        this.users = users;
    }

    /**
     * Stop method.<br/> This method is called when component needs to be
     * stopped.
     * @throws EZBComponentException if the stop is failing.
     */
    public void stop() throws EZBComponentException {
        this.server.shutdown();
        DatabaseManager.getTimer().shutDown();
    }

    /**
     * Sets the port number.
     * @param portNumber the port number to use.
     */
    public void setPortNumber(final String portNumber) {
        this.portNumber = portNumber;
    }

    /**
     * Sets the hostname.
     * @param hostname the hostname to use.
     */
    public void setHostname(final String hostname) {
        this.hostname = hostname;
    }

    /**
     * Sets the database name.
     * @param databaseName the name of the database.
     */
    public void setDatabaseName(final String databaseName) {
        this.databaseName = databaseName;
    }

    /**
     * Allows to change the path of the database files.
     * @param path the path of the files for storing the database.
     */
    public void setPath(final String path) {
        this.path = path;
    }

}
TOP

Related Classes of org.ow2.easybeans.component.hsqldb.HSQLDBComponent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.