/* * Copyright 2002-2005 the original author or authors. * * 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. */ package org.springmodules.db.hsqldb; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hsqldb.ServerConfiguration; import org.hsqldb.ServerConstants; import org.hsqldb.persist.HsqlProperties; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; /** * Bean that will start an instance of an HSQL database. This class is primarily intended * to be used in demo applications. It allows for a self contained distribution including * a database instance. The DataSource reference is necessary for proper shutdown. * * This is an example of a bean configuration: * * <pre> * <bean id="dataBase" class="org.springmodules.db.hsqldb.ServerBean" singleton="true" lazy-init="false"> * <property name="dataSource"><ref local="dataSource"/></property> * <property name="serverProperties"> * <props> * <prop key="server.port">9101</prop> * <prop key="server.database.0">webapps/myapp/db/test</prop> * <prop key="server.dbname.0">test</prop> * </props> * </property> * </bean> * </pre> * * * @author Thomas Risberg * @see org.hsqldb.Server */ public class ServerBean implements InitializingBean, DisposableBean { /** * Commons Logging instance. */ private static final Log log = LogFactory.getLog(ServerBean.class); /** * Properties used to customize instance. */ private Properties serverProperties; /** * The actual server instance. */ private org.hsqldb.Server server; /** * DataSource used for shutdown. */ private DataSource dataSource; public Properties getServerProperties() { return serverProperties; } public void setServerProperties(Properties serverProperties) { this.serverProperties = serverProperties; } public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void afterPropertiesSet() throws Exception { HsqlProperties configProps = new HsqlProperties(serverProperties); if (configProps == null) { configProps = new HsqlProperties(); } ServerConfiguration.translateDefaultDatabaseProperty(configProps); // finished setting up properties - set some important behaviors as well; server = new org.hsqldb.Server(); server.setRestartOnShutdown(false); server.setNoSystemExit(true); server.setProperties(configProps); log.info("HSQL Server Startup sequence initiated"); server.start(); String portMsg = "port " + server.getPort(); log.info("HSQL Server listening on " + portMsg); } public void destroy() { log.info("HSQL Server Shutdown sequence initiated"); if (dataSource != null) { Connection con = null; try { con = dataSource.getConnection(); con.createStatement().execute("SHUTDOWN"); } catch (SQLException e) { log.error("HSQL Server Shutdown failed: " + e.getMessage()); } finally { try { if (con != null) con.close(); } catch (Exception ignore) {} } } else { log.warn("HSQL ServerBean needs a dataSource property set to shutdown database safely."); } server.signalCloseAllServerConnections(); int status = server.stop(); long timeout = System.currentTimeMillis() + 5000; while (status != ServerConstants.SERVER_STATE_SHUTDOWN && System.currentTimeMillis() < timeout) { try { Thread.sleep(100); status = server.getState(); } catch (InterruptedException e) { log.error("Error while shutting down HSQL Server: " + e.getMessage()); break; } } if (status != ServerConstants.SERVER_STATE_SHUTDOWN) { log.warn("HSQL Server failed to shutdown properly."); } else { log.info("HSQL Server Shutdown completed"); } server = null; } }