You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by tb...@apache.org on 2004/05/06 02:01:40 UTC
cvs commit: avalon-components/facilities/db/hsql/src/java/org/apache/avalon/db/hsql HsqlServer.java HsqlServiceProvider.java
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: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org