You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2004/02/19 09:58:45 UTC

cvs commit: avalon/merlin/facilities/db/hsql/src/java/org/apache/avalon/db/hsql HsqldbServer.java

mcconnell    2004/02/19 00:58:45

  Added:       merlin/facilities/db README.TXT maven.xml merlin.properties
                        project.properties project.xml
               merlin/facilities/db/api maven.xml project.xml
               merlin/facilities/db/api/src/java/org/apache/avalon/db
                        DatabaseService.java
               merlin/facilities/db/hsql/conf block.xml
               merlin/facilities/db/hsql maven.xml project.xml
               merlin/facilities/db/hsql/src/java/org/apache/avalon/db/hsql
                        HsqldbServer.java
  Log:
  db addition
  
  Revision  Changes    Path
  1.1                  avalon/merlin/facilities/db/README.TXT
  
  Index: README.TXT
  ===================================================================
  
  Build instructions (relative to this directory):
  
  $ maven
  
  Execution instructions:
  
  $ merlinx hsql\target\*.jar
  
  
  
  
  1.1                  avalon/merlin/facilities/db/maven.xml
  
  Index: maven.xml
  ===================================================================
  <project default="avalon:build" xmlns:maven="jelly:maven" xmlns:j="jelly:core" xmlns:util="jelly:util" xmlns:ant="jelly:ant">
  
    <goal name="avalon:clean" prereqs="clean">
      <maven:reactor
        basedir="${basedir}"
        includes="*/project.xml"
        excludes="project.xml,target/**"
        goals="clean"
        banner="Cleaning:"
        ignoreFailures="true"/>
    </goal>
  
    <goal name="avalon:build">
      <maven:reactor basedir="${basedir}"
        includes="*/project.xml"
        excludes="project.xml,target/**"
        goals=""
        banner="Building:"
        ignoreFailures="false"
        postProcessing="true" />
      <ant:copy todir="${maven.build.dir}">
        <j:forEach var="child" items="${reactorProjects}">
          <ant:fileset dir="${child.file.parentFile}/target">
            <ant:include name="${child.artifactId}-${child.currentVersion}.jar"/>
          </ant:fileset>
        </j:forEach>
      </ant:copy>
    </goal>
  
    <goal name="avalon:site" prereqs="avalon:build,xjavadoc,site"/>
  
    <goal name="xjavadoc">
  
      <maven:reactor basedir="${basedir}"
        includes="*/project.xml"
        excludes="project.xml"
        banner="Site Prep:"
        ignoreFailures="false"
        postProcessing="true" />
  
      <ant:mkdir dir="${maven.build.dir}/docs/api" />
      <ant:property name="copyright"
        value="Copyright &amp;copy; ${year} ${pom.organization.name}. All Rights Reserved." />
  
      <ant:path id="template.classpath">
        <j:forEach var="child" items="${reactorProjects}">
          <j:set var="deps" value="${child.dependencies}"/>
          <j:forEach var="dep" items="${deps}">
            <ant:pathelement 
              path="${maven.repo.local}/${dep.getArtifactDirectory()}/jars/${dep.getArtifact()}"/>
          </j:forEach>
        </j:forEach>
      </ant:path>
      
      <util:tokenize var="links" delim="," trim="true">${maven.javadoc.links}</util:tokenize>
  
      <ant:property name="title" value="${pom.name} ${pom.currentVersion}"/>
      <ant:javadoc destdir="${maven.build.dir}/docs/api" 
  	doctitle="&lt;h1&gt;${title}&lt;/h1&gt;" 
        noindex="false" author="true" use="true"
  	windowtitle="${title}" 
        bottom="${copyright}"
        additionalparam="-breakiterator -J-Xmx128m "
        packagenames="*,org.*">
          <j:forEach var="packageGroup" items="${pom.packageGroups}">
            <group title="${packageGroup.title}" packages="${packageGroup.packages}"/>
          </j:forEach>
          <j:forEach var="child" items="${reactorProjects}">
            <sourcepath path="${child.file.parentFile}/src/java"/>
          </j:forEach>
          <j:forEach var="link" items="${links}">
            <ant:link href="${link.trim()}"/>
          </j:forEach>
          <classpath>
            <path refid="template.classpath"/>
  	  </classpath>
  	  <link href="http://java.sun.com/j2se/1.4.2/docs/api/" />
          <!-- allow custom tags -->    
          <util:tokenize var="listOfTags" delim=" ">${maven.javadoc.customtags}</util:tokenize>
          <j:forEach var="someTag" items="${listOfTags}">
            <j:set var="nameVar" value="${someTag}.name"/>
            <j:set var="name" value="${context.findVariable(nameVar)}"/>
            <j:set var="descriptionVar" value="${someTag}.description"/>
            <j:set var="description" value="${context.findVariable(descriptionVar)}"/>
            <j:set var="enabledVar" value="${someTag}.enabled"/>
            <j:set var="enabled" value="${context.findVariable(enabledVar)}"/>
            <j:set var="scopeVar" value="${someTag}.scope"/>
            <j:set var="scope" value="${context.findVariable(scopeVar)}"/>
            <ant:tag name="${name}" description="${description}"
                 enabled="${enabled}" scope="${scope}"/>
          </j:forEach>
      </ant:javadoc>
    </goal>
  
    <goal name="template">
      <ant:delete dir="${maven.build.dir}/template" />
      <ant:mkdir dir="${maven.build.dir}/template" />
      <ant:copy todir="${maven.build.dir}/template">
        <ant:fileset dir=".">
          <ant:include name="LICENSE*"/>
          <ant:include name="project.properties"/>
          <ant:include name="maven.xml"/>
          <ant:include name="project.xml"/>
          <ant:include name="master.xml"/>
        </ant:fileset>
      </ant:copy>
      <ant:copy todir="${maven.build.dir}/template">
        <ant:fileset dir="${basedir}">
          <include name="api/**"/>
          <include name="impl/**"/>
          <include name="xdocs/**"/>
          <exclude name="**/target/**"/>
          <exclude name="**/*.log"/>
        </ant:fileset>
      </ant:copy>
    </goal>
  
  </project>
  
  
  
  1.1                  avalon/merlin/facilities/db/merlin.properties
  
  Index: merlin.properties
  ===================================================================
  merlin.deployment.timeout = 60000
  
  
  
  1.1                  avalon/merlin/facilities/db/project.properties
  
  Index: project.properties
  ===================================================================
  
  #
  # custom tags spec
  #
  maven.javadoc.customtags = component service
  
  component.name = avalon.component
  component.description = Component:
  component.enabled = true
  component.scope = class
  
  service.name = avalon.service
  service.description = Service Export:
  service.enabled = true
  service.scope = class
  
  
  
  
  
  
  1.1                  avalon/merlin/facilities/db/project.xml
  
  Index: project.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <project>
  
    <groupId>avalon-db</groupId>
    <name>Avalon Database</name>
    <currentVersion>1.0</currentVersion>
    <shortDescription>Avalon Database Project Template.</shortDescription>
  
    <packageGroups>
      <packageGroup>
        <title>Avalon Database API</title>
        <packages>org.apache.avalon.db</packages>
      </packageGroup>
      <packageGroup>
        <title>Avalon Database Implementation</title>
        <packages>org.apache.avalon.db.*</packages>
      </packageGroup>
    </packageGroups>
  
    <build>
  
      <nagEmailAddress>dev@avalon.apache.org</nagEmailAddress>
      <sourceDirectory>${basedir}/src/java</sourceDirectory>
      <unitTestSourceDirectory>${basedir}/src/test</unitTestSourceDirectory>
  
      <unitTest>
        <includes>
          <include>**/*TestCase.*</include>
        </includes>
        <excludes>
          <exclude>**/Abstract*.*</exclude>
        </excludes>
        <resources>
          <resource>
            <directory>${basedir}/src/test</directory>
            <includes> 
              <include>**/*.dtd</include>
              <include>**/*.properties</include>
              <include>**/*.x*</include>
            </includes>
          </resource>
        </resources>
      </unitTest>
      
      <resources>
        <resource>
          <directory>${basedir}/src/java</directory>
          <includes>
            <include>**/*.dtd</include>
            <include>**/*.properties</include>
            <include>**/*.x*</include>
          </includes>
        </resource>
        <resource>
          <directory>${basedir}/conf</directory>
          <targetPath>BLOCK-INF</targetPath>
          <includes>
            <include>block.xml</include>
          </includes>
        </resource>
      </resources>
      
      <jars></jars>
    </build>
  
  </project>
  
  
  
  1.1                  avalon/merlin/facilities/db/api/maven.xml
  
  Index: maven.xml
  ===================================================================
  <project default="jar:install"/>
  
  
  
  1.1                  avalon/merlin/facilities/db/api/project.xml
  
  Index: project.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <project>
  
    <extend>${basedir}/../../../project.xml</extend>
  
    <groupId>avalon-db</groupId>
    <id>avalon-db-api</id>
    <name>Avalon Database API</name>
    <package>org.apache.avalon.db</package>
    <currentVersion>1.0-SNAPSHOT</currentVersion>
    <shortDescription>Avalon Database Server API</shortDescription>
  
  </project>
  
  
  
  1.1                  avalon/merlin/facilities/db/api/src/java/org/apache/avalon/db/DatabaseService.java
  
  Index: DatabaseService.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;
  
  /**
   * Defintion of the DatabaseService service contract.
   */
  public interface DatabaseService {
  	// TODO What services might database service provide?
  	// Pooled JDBC connections will be provided by another service...
  	// Dynamic starting/stopping?
  	// Monitoring hooks?
  }
  
  
  
  1.1                  avalon/merlin/facilities/db/hsql/conf/block.xml
  
  Index: block.xml
  ===================================================================
  <container name="avalon-hsql">
  
    <classloader>
      <classpath>
        <repository>
          <resource id="avalon-framework:avalon-framework-api" version="4.1.5"/>
          <resource id="avalon-framework:avalon-framework-impl" version="4.1.5"/>
          <resource id="avalon-db:avalon-db-api" version="1.0-SNAPSHOT"/>
          <resource id="hsqldb:hsqldb" version="1.7.2-rc1"/>
          <resource id="concurrent:concurrent" version="1.3.1"/>
        </repository>
      </classpath>
    </classloader>
    
    <component name="hsql-server" 
        class="org.apache.avalon.db.hsql.HsqldbServer" activation="startup">
      <configuration>
        <host>127.0.0.1</host>
        <port>9001</port>
        <db-name>avalon-hsql</db-name>
        <debug>true</debug>
        <silent>false</silent>
      </configuration>
    </component>
    
  </container>
  
  
  
  1.1                  avalon/merlin/facilities/db/hsql/maven.xml
  
  Index: maven.xml
  ===================================================================
  <project default="jar:install">
  
    <preGoal name="java:compile">
      <attainGoal name="avalon:meta"/>
    </preGoal>
  
  </project>
  
  
  
  1.1                  avalon/merlin/facilities/db/hsql/project.xml
  
  Index: project.xml
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <project>
  
    <extend>${basedir}/../../../project.xml</extend>
  
    <groupId>avalon-db</groupId>
    <id>avalon-db-hsql</id>
    <name>Avalon HSQLDB Database Implementation</name>
    <currentVersion>1.0-SNAPSHOT</currentVersion>
    <shortDescription>Avalon HSQLDB Database Implementation</shortDescription>
    <package>org.apache.avalon.db.impl</package>
  
    <dependencies>
      
      <dependency>
        <groupId>avalon-db</groupId>
        <artifactId>avalon-db-api</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
  
      <dependency>
        <groupId>avalon-framework</groupId>
        <artifactId>avalon-framework-api</artifactId>
        <version>4.1.5</version>
      </dependency>
  
      <dependency>
        <groupId>hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <version>1.7.2-rc1</version>
      </dependency>
  
      <dependency>
        <groupId>concurrent</groupId>
        <artifactId>concurrent</artifactId>
        <version>1.3.1</version>
      </dependency>
      
    </dependencies>
    
  </project>
  
  
  
  1.1                  avalon/merlin/facilities/db/hsql/src/java/org/apache/avalon/db/hsql/HsqldbServer.java
  
  Index: HsqldbServer.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.io.IOException;
  import java.io.InterruptedIOException;
  import java.net.InetAddress;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.net.UnknownHostException;
  import java.sql.SQLException;
  
  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.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.LogEnabled;
  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.
   *
   * @avalon.component name="server" lifestyle="singleton"
   * @avalon.service type="org.apache.avalon.db.DatabaseService"
   * @author  <a href="mailto:exterminatorx@comcast.net">Timothy Bennett</a>
   */
  public class HsqldbServer 
    implements Contextualizable, Configurable, Initializable,
    Startable, DatabaseService 
  {
      //---------------------------------------------------------
      // immutable state
      //---------------------------------------------------------
  
      private final Logger m_logger;
  
      //---------------------------------------------------------
      // state
      //---------------------------------------------------------
  
      /**
       * Main thread managing the server connection socket.
       */
      private Thread m_serverSocketThread;
  
      /**
       * The HSQLDB database server and socket request handler.
       */
      private HsqlSocketRequestHandler m_hsqlSocketRequestHandler;
  
      /**
       * 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
      //---------------------------------------------------------
  
      public HsqldbServer( 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:composition:dir" type="java.io.File"
      */
      public void contextualize(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(Configuration config) 
        throws ConfigurationException 
      {    
          // get the database listening port/host
          m_port = config.getChild("port").getValueAsInteger(9001);
          String host = config.getChild("host").getValue("127.0.0.1");
          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);
          
          // how are we configured?
          this.toString();
      }
  
      //---------------------------------------------------------
      // Initializable
      //---------------------------------------------------------
  
      /**
       * Initialization of the component by the container.
       */
      public void initialize() throws Exception 
      {
          // nothing yet to initialize        
      }
  
      //---------------------------------------------------------
      // Startable
      //---------------------------------------------------------
  
      /**
       * Start the server.
       */
      public void start() throws Exception 
      {
          // create the HSQLDB server and socket request handler
          try 
          {
              m_hsqlSocketRequestHandler = 
                HsqlServerFactory.createHsqlServer(
                  m_dbName.getAbsolutePath(), 
                  m_dbDebug, 
                  m_dbSilent);
          } 
          catch (SQLException sqle) 
          {
              if (m_logger.isErrorEnabled()) 
              {
                  final String error = 
                    "Error starting HSQL database: " 
                    + sqle.getMessage();
                  m_logger.error( error, sqle );
              }
              throw sqle;
          }
          
          // start up primary socket server 
          final ServerSocket serverSocket = new ServerSocket(m_port, 50, m_host);
          serverSocket.setSoTimeout(500);
          m_serverSocketThread = 
            new Thread(new Runnable() {
              public void run() { runServer(serverSocket); }
            });
          m_serverSocketThread.start();
          
          if (m_logger.isInfoEnabled()) 
          {
              m_logger.info("Hypersonic SQL listening on port " + m_port);
          }
      }
  
      /**
       * Stop the server.
       */
      public void stop() 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();
          }
      }
  
      /**
       * 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( getLogger().isWarnEnabled() ) 
                      {
                          getLogger().warn( e.getMessage(), e );
                      }
                  }
              }
          } 
          finally 
          {
              if (runner != null) 
              {
                  runner = null;
              }
              if (serverSocket != null) 
              {
                  try 
                  {
                      serverSocket.close();
                  } 
                  catch (IOException ignore) 
                  {
                      // ignore...
                  }
                  serverSocket = null;
              }
          }
      }
      
      /**
       * 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( Context context ) 
        throws ContextException 
      {
          return (File) context.get("urn:composition:dir");
      }
      
     /**
      * Return the assigned logging channel.
      * @return the logging channel
      */
      private Logger getLogger()
      {
          return m_logger;
      }
  
      /**
       * Returns a <code>String</code> representation of this component.
       * 
       * @return a <code>String</code> representation of this component
       */
      public String toString() 
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append("[HsqldbServer:");
          buffer.append(" m_logger: ");
          buffer.append(m_logger);
          buffer.append(" m_basedir: ");
          buffer.append(m_basedir);
          buffer.append(" m_port: ");
          buffer.append(m_port);
          buffer.append(" m_host: ");
          buffer.append(m_host);
          buffer.append(" m_dbName: ");
          buffer.append(m_dbName);
          buffer.append(" m_dbDebug: ");
          buffer.append(m_dbDebug);
          buffer.append(" m_dbSilent: ");
          buffer.append(m_dbSilent);
          buffer.append("]");
          return buffer.toString();
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org