tbennett 2004/05/05 17:01:40 Added: facilities/db/hsql/src/java/org/apache/avalon/db/hsql HsqlServer.java HsqlServiceProvider.java Log: HSQL component update Revision Changes Path 1.1 avalon-components/facilities/db/hsql/src/java/org/apache/avalon/db/hsql/HsqlServer.java Index: HsqlServer.java =================================================================== /* * Copyright 2004 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. */ package org.apache.avalon.db.hsql; import java.io.IOException; import java.io.InterruptedIOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.sql.SQLException; import org.apache.avalon.framework.logger.Logger; import org.hsqldb.HsqlServerFactory; import org.hsqldb.HsqlSocketRequestHandler; import EDU.oswego.cs.dl.util.concurrent.ThreadedExecutor; /** * This is a database server facility for the HypersonicSQL database. * * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a> * @version $Revision: 1.1 $ $Date: 2004/05/06 00:01:40 $ */ public class HsqlServer { /** * TCP listening socket backlog. */ private static final int BACKLOG = 50; /** * Default host name to bind the HSQL database server TCP socket * to. The default value is the localhost, that is 127.0.0.1. */ private static final String DEFAULT_HOST = "127.0.0.1"; //--------------------------------------------------------- // static //--------------------------------------------------------- /** * Default HSQL database server TCP socket listening port. * The default value is the HSQL standard port 9001. */ private static final int DEFAULT_PORT = 9001; /** * TCP listening socket connection timeout (msecs). */ private static final int TIMEOUT = 500; /** * Flag indicating if the HSQL database server will operate in * a debug logging mode. */ private boolean m_debug; /** * Host to bind the database TCP/IP listener to. Default is localhost. */ private InetAddress m_host; /** * The HSQLDB database server and socket request handler. */ private HsqlSocketRequestHandler m_hsqlSocketRequestHandler; //--------------------------------------------------------- // immutable state //--------------------------------------------------------- /** * The logging channel for this component. */ private final Logger m_logger; //--------------------------------------------------------- // state //--------------------------------------------------------- /** * Alias of the HSQL database server. */ private String m_name; /** * TCP listening port of the HSQL database server. */ private int m_port; /** * Main thread managing the server connection socket. */ private Thread m_serverSocketThread; /** * Flag indicating if the HSQL database server will operate in * a silent logging mode. */ private boolean m_silent; /** * Creates a new instance of an <code>HsqlServer</code> object. * * @param name alias of the HSQL database server instance * @param port listening port of the HSQL database server * @param host <code>InetAddress</code> to bind the HSQL database * server to * @param debug if <b>true</b>, the HSQL database server will be * started in debug mode * @param silent if <b>true</b>, the HSQL database server will * operate in a silent logging mode */ public HsqlServer( String name, int port, InetAddress host, boolean debug, boolean silent, Logger logger) { logger.info("Entering constructor"); m_name = name; m_port = port; m_host = host; m_debug = debug; m_silent = silent; m_logger = logger; logger.info("Exiting constructor"); } /** * Starts the socket server and hands off connections to * the thread pool for processing by a worker thread. * * @param serverSocket the serverSocket to manage */ private void runServer( ServerSocket serverSocket ) { if ( m_logger.isInfoEnabled() ) { m_logger.info( "Running database connection server..." ); } ThreadedExecutor runner = new ThreadedExecutor(); try { // accept connections until this thread is interrupted... while ( !Thread.interrupted() ) { try { // when a connection is made, spin off a thread to // process the connection, and immediately go back to // listening for other connections final Socket connection = serverSocket.accept(); runner.execute( new Runnable() { public void run() { // who connected to us? final String remoteHost = connection.getInetAddress().getHostName(); final String remoteIP = connection.getInetAddress().getHostAddress(); // hand-off the socket connection to HSQLDB... m_hsqlSocketRequestHandler.handleConnection( connection ); if ( m_logger.isDebugEnabled() ) { final String message = "database connection from " + remoteHost + " (" + remoteIP + ")"; m_logger.debug( message ); } } } ); } catch ( InterruptedIOException iioe ) { // Ignore these - thrown when accept() times out } catch ( Exception e ) { // IOException - if an I/O error occurs when waiting // for a connection. // SecurityException - if a security manager exists // and its checkListen method doesn't allow the operation. if ( m_logger.isWarnEnabled() ) { m_logger.warn( e.getMessage(), e ); } } } } finally { if ( runner != null ) { runner = null; } if ( serverSocket != null ) { try { serverSocket.close(); } catch ( IOException ignore ) { // ignore... } serverSocket = null; } } } /** * Starts the HSQL database server instance. * * @throws Exception if an error occurs while starting the server */ public void startServer() throws Exception { m_logger.info("Entering startServer()"); // create the HSQLDB server and socket request handler try { m_hsqlSocketRequestHandler = HsqlServerFactory.createHsqlServer( m_name, m_debug, m_silent ); } catch ( SQLException sqle ) { if ( m_logger.isErrorEnabled() ) { final String error = "Error starting HSQL database: " + sqle.getMessage(); m_logger.error( error, sqle ); } throw sqle; } m_logger.info("Waypoint 1"); // start up primary socket server final ServerSocket serverSocket = new ServerSocket( m_port, BACKLOG, m_host ); m_logger.info("Waypoint 2"); serverSocket.setSoTimeout( TIMEOUT ); m_serverSocketThread = new Thread( new Runnable() { public void run() { runServer( serverSocket ); } } ); m_logger.info("Waypoint 3"); m_serverSocketThread.start(); m_logger.info("Waypoint 4"); if ( m_logger.isInfoEnabled() ) { m_logger.info( "Hypersonic SQL listening on port " + m_port ); } m_logger.info("Exiting startServer()"); } /** * Shuts down the HSQL database server instance. * * @throws Exception if an error occurs while shutting down the server */ public void stopServer() throws Exception { // tell HSQLDB that all connections are being shutdown... if ( m_hsqlSocketRequestHandler != null ) { m_hsqlSocketRequestHandler.signalCloseAllServerConnections(); } // shutdown server socket... if ( m_serverSocketThread != null ) { m_serverSocketThread.interrupt(); } } } 1.1 avalon-components/facilities/db/hsql/src/java/org/apache/avalon/db/hsql/HsqlServiceProvider.java Index: HsqlServiceProvider.java =================================================================== /* * Copyright 2004 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. */ package org.apache.avalon.db.hsql; import java.io.File; import java.net.InetAddress; import java.net.UnknownHostException; import org.apache.avalon.db.DatabaseService; import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.activity.Startable; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.Contextualizable; import org.apache.avalon.framework.logger.Logger; /** * Database service provider implementing an embedded HypersonicSQL * database server. * * @avalon.component name="server" lifestyle="singleton" * @avalon.service type="org.apache.avalon.db.DatabaseService" * * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a> * @version $Revision: 1.1 $ $Date: 2004/05/06 00:01:40 $ */ public class HsqlServiceProvider implements Contextualizable, Configurable, Initializable, Startable, DatabaseService { //--------------------------------------------------------- // static //--------------------------------------------------------- /** * Default HSQL database server TCP socket listening port. * The default value is the HSQL standard port 9001. */ private static final int DEFAULT_PORT = 9001; /** * Default host name to bind the HSQL database server TCP socket * to. The default value is the localhost, that is 127.0.0.1. */ private static final String DEFAULT_HOST = "127.0.0.1"; //--------------------------------------------------------- // immutable state //--------------------------------------------------------- /** * The logging channel for this component. */ private final Logger m_logger; //--------------------------------------------------------- // state //--------------------------------------------------------- /** * HSQL server wrapper object. */ private HsqlServer m_server; /** * The working base directory. */ private File m_basedir; /** * Listening port for database connections. Default is 9001; */ private int m_port; /** * Host to bind the database TCP/IP listener to. Default is localhost. */ private InetAddress m_host; /** * Fully qualified filepath to the database file artifacts. */ private File m_dbName; /** * Run the HSQLDB server in debug mode? */ private boolean m_dbDebug; /** * Run the HSQLDB server silently? */ private boolean m_dbSilent; //--------------------------------------------------------- // constructor //--------------------------------------------------------- /** * Creates a new instance of the HSQL database server with the * logging channel supplied by the container. * * @param logger the container-supplied logging channel */ public HsqlServiceProvider( final Logger logger ) { m_logger = logger; } //--------------------------------------------------------- // Contextualizable //--------------------------------------------------------- /** * Contextualization of the server by the container. * * @param context the supplied server context * @exception ContextException if a contextualization error occurs * @avalon.entry key="urn:avalon:home" type="java.io.File" */ public void contextualize( final Context context ) throws ContextException { // cache the working base directory m_basedir = getBaseDirectory( context ); } //--------------------------------------------------------- // Configurable //--------------------------------------------------------- /** * Configuration of the server by the container. * * @param config the supplied server configuration * @exception ConfigurationException if a configuration error occurs */ public void configure( final Configuration config ) throws ConfigurationException { // get the database listening port/host m_port = config.getChild( "port" ).getValueAsInteger( DEFAULT_PORT ); String host = config.getChild( "host" ).getValue( DEFAULT_HOST ); try { m_host = InetAddress.getByName( host ); } catch ( UnknownHostException uhe ) { if ( getLogger().isErrorEnabled() ) { getLogger().error( "Error configuring HSQLDB component: " + uhe.getMessage(), uhe ); } throw new ConfigurationException( uhe.getMessage(), uhe ); } // get the HSQLDB server parameters... m_dbName = new File( m_basedir, config.getChild( "db-name" ).getValue( "avalon-hsqldb" ) ); m_dbDebug = config.getChild( "debug" ).getValueAsBoolean( false ); m_dbSilent = config.getChild( "silent" ).getValueAsBoolean( true ); } //--------------------------------------------------------- // Initializable //--------------------------------------------------------- /** * Initialization of the component by the container. * * @throws Exception if an error occurs while initializing * the component */ public void initialize() throws Exception { m_server = new HsqlServer( m_dbName.getAbsolutePath(), m_port, m_host, m_dbDebug, m_dbSilent, m_logger ); } //--------------------------------------------------------- // Startable //--------------------------------------------------------- /** * Start the server. * * @throws Exception if an error occurs while starting the * component */ public void start() throws Exception { m_logger.info("Entering start()"); if (m_server != null) { m_server.startServer(); } else { throw new Exception("Server instance not instantiated!!"); } m_logger.info("Exiting start()"); } /** * Stop the server. * * @throws Exception if an error occurs while stopping the component */ public void stop() throws Exception { m_logger.info("Entering stop()"); m_server.stopServer(); m_logger.info("Exiting stop()"); } /** * Return the working base directory. * * @param context the supplied server context * @return a <code>File</code> object representing the working * base directory * @exception ContextException if a contextualization error occurs */ private File getBaseDirectory( final Context context ) throws ContextException { File home = (File) context.get( "urn:avalon:home" ); if ( !home.exists() ) { boolean success = home.mkdirs(); if ( !success ) { throw new ContextException( "Unable to create component " + "home directory: " + home.getAbsolutePath() ); } } if ( getLogger().isInfoEnabled() ) { getLogger().info( "Setting home directory to: " + home ); } return home; } /** * Return the assigned logging channel. * @return the logging channel */ private Logger getLogger() { return m_logger; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]