Package org.jboss.soa.bpel.runtime.db

Source Code of org.jboss.soa.bpel.runtime.db.H2Database

/*
* JBoss, Home of Professional Open Source.
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This 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 (at your option) any later version.
*
* This software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.soa.bpel.runtime.db;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import org.h2.tools.Server;
import org.jboss.system.ServiceMBeanSupport;

/**
* Integration with H2.
*
* @author <a href="mailto:rickard.oberg@telkel.com">Rickard �berg</a>
* @author <a href="mailto:Scott_Stark@displayscape.com">Scott Stark</a>.
* @author <a href="mailto:pf@iprobot.com">Peter Fagerlund</a>
* @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
* @author <a href="mailto:vesco.claudio@previnet.it">Claudio Vesco</a>
* @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
* @author <a href="mailto:kevin.conner@jboss.org">Kevin Conner</a>
* @author <a href="mailto:dbevenius@redhat.com">Daniel Bevenius</a>
* @version $Revision: 27106 $
*/
public class H2Database extends ServiceMBeanSupport implements H2DatabaseMBean
{
    /** Default password: <code>empty string</code>. */
    private static final String DEFAULT_PASSWORD = "";
      
    /** Default user: <code>sa</code>. */
    private static final String DEFAULT_USER = "sa";
      
    /** JDBC Driver class: <code>org.h2.Driver</code>. */
    private static final String JDBC_DRIVER_CLASS = "org.h2.Driver";
      
    /** JDBC URL common prefix: <code>jdbc:h2:</code>. */
    private static final String JDBC_URL_PREFIX = "jdbc:h2:";
  
    /** JDBC in memory URL prefix: <code>jdbc:h2:mem:</code>. */
    private static final String JDBC_MEM_URL_PREFIX = JDBC_URL_PREFIX + "mem:";
      
    /** JDBC flags */
    private static final String DEFAULT_FLAGS = ";MVCC=TRUE;DB_CLOSE_ON_EXIT=FALSE";
      
    /** Default data subdir: <code>h2</code>. */
    private static final String H2_DATA_DIR = "h2";
      
    /** Default database name: <code>default</code>. */
    private static final String DEFAULT_DATABASE_NAME = "default";
      
    /** Default address for remote h2: <code>0.0.0.0</code>. */
    private static final String DEFAULT_ADDRESS = "0.0.0.0";
      
    /** Default port for remote h2: <code>9092</code>. */
    private static final int DEFAULT_PORT = 9092;
   
    /** Default delay for remote hypersonic initialisation (ms): <code>5000</code>. */
    private static final long DEFAULT_DELAY = 5000;
   
    // Private Data --------------------------------------------------
          
    /** Full path to db/h2. */
    private File dbPath;
   
    /** Database name. */
    private String name = DEFAULT_DATABASE_NAME;
      
    /** In memory mode. */
    private boolean inMemoryMode ;
      
    /** Database user. */
    private String user = DEFAULT_USER;
      
    /** Database password. */
    private String password = DEFAULT_PASSWORD;
      
    /** Database flags */
    private String flags = DEFAULT_FLAGS ;
      
    /** Hold a connection for in memory h2. */
    private Connection connection;
      
    /** Default address. */
    private String address = DEFAULT_ADDRESS;
      
    /** Default port. */
    private int port = DEFAULT_PORT;
      
    /** Server/remote mode. */
    private boolean serverMode = false;
  
    /** Server thread for remote h2. */
    private Thread serverThread;
   
    /** The remote server instance */
    private Server remoteServer ;
   
    /** Server thread delay for remote H2. */
    private long delay = DEFAULT_DELAY ;

    private String datadir;

    // Attributes ----------------------------------------------------
  
    /**
     * Set the database name.
     *
     * @jmx.managed-attribute
     */
    public void setDatabase(String name)
    {
        if (name == null)
        {
            name = DEFAULT_DATABASE_NAME;
        }
        this.name = name;
   }

    /**
     * Get the database name.
     *
     * @jmx.managed-attribute
     */
    public String getDatabase()
    {
        return name;
    }
   
    /**
     * Get the full database path.
     *
     * @jmx.managed-attribute
     */
    public String getDatabasePath()
    {
        if (dbPath != null)
        {
            return dbPath.toString();
        }
        else
        {
            return null;
        }
    }
   
    /**
     * @return the <code>inMemoryMode</code> flag.
     *
     * @jmx.managed-attribute
     */
    public boolean isInMemoryMode()
    {
        return inMemoryMode;
    }

    /**
     * If <b>true</b> the h2 is in memory mode otherwise embedded mode.
     *
     * @param b in memory mode.
     *
     * @jmx.managed-attribute
     */
    public void setInMemoryMode( boolean b )
    {
        inMemoryMode = b;
    }
   
    /**
     * @return the password
     *
     * @jmx.managed-attribute
     */
    public String getPassword()
    {
        return password;
    }

    /**
     * @return the user
     *
     * @jmx.managed-attribute
     */
    public String getUser()
    {
        return user;
    }
   
    /**
     * @return the flags
     *
     * @jmx.managed-attribute
     */
    public String getFlags()
    {
        return flags;
    }
   
    /**
     * @param password
     *
     * @jmx.managed-attribute
     */
    public void setPassword(String password)
    {
        if (password == null)
        {
            password = DEFAULT_PASSWORD;
        }
        this.password = password;
    }
   
    /**
     * @param user
     *
     * @jmx.managed-attribute
     */
    public void setUser(String user)
    {
        if (user == null)
        {
            user = DEFAULT_USER;
        }
        this.user = user;
    }
       
    /**
     * @param flags
     *
     * @jmx.managed-attribute
     */
    public void setFlags(String flags)
    {
        if (flags == null)
        {
            flags = DEFAULT_FLAGS;
        }
      this.flags = flags;
    }
  
    /**
     * @return the serverMode
     *
     * @jmx.managed-attribute
     */
    public boolean isServerMode()
    {
        return serverMode;
    }

    /**
     * @param serverMode
     *
     * @jmx.managed-attribute
     */
    public void setServerMode( boolean serverMode )
  {
         this.serverMode = serverMode;
    }

    /**
     * @return the address
     *
     * @jmx.managed-attribute
     */
  public String getBindAddress()
  {
    return address;
  }

    /**
     * @return the port
     *
     * @jmx.managed-attribute
     */
  public int getPort()
  {
    return port;
  }

    /**
     * @param address
     *
     * @jmx.managed-attribute
     */
    public void setBindAddress(String address)
    {
    this.address = address;
  }

    /**
     * @param port
     *
     * @jmx.managed-attribute
     */
    public void setPort(int port)
    {
        this.port = port;
    }
   
    /**
     * Set the delay for remote hypersonic initialisation.
     *
     * @jmx.managed-attribute
     */
    public void setDelay(final long delay)
    {
        this.delay = delay;
    }
   
    /**
     * Get the delay for remote hypersonic initialisation.
     *
     * @jmx.managed-attribute
     */
    public long getDelay()
    {
        return delay;
    }
   
    // Lifecycle -----------------------------------------------------
  
    /**
     * Start the database
     */
    protected void startService() throws Exception
    {
        if (serverMode)
        {
            startRemoteDatabase();
        }
        else if (inMemoryMode)
        {
            startInMemoryDatabase();
        }
        else
        {
            startStandaloneDatabase();
        }
    }

    /**
     * We now close the connection clean by calling the
     * serverSocket throught jdbc. The MBeanServer calls this
     * method at closing time.
     */
    protected void stopService() throws Exception
    {
        if (serverMode)
        {
            stopRemoteDatabase();
        }
        else if (inMemoryMode)
        {
            stopInMemoryDatabase();
        }
        else
        {
            stopStandaloneDatabase();
        }
    }

    // Private -------------------------------------------------------
  
    /**
     * Start the standalone (in process) database.
     */
    private void startStandaloneDatabase() throws Exception
    {
        final File h2Dir = checkDataDir() ;
              
        dbPath = new File(h2Dir, name);
       
        final String dbURL = JDBC_URL_PREFIX + dbPath.toURI().toString() + flags ;
        log.info(dbURL);
       
        // Check we have connectivity
        connection = getConnection(dbURL);
    }

    /**
    * Start the only in memory database.
    */
    private void startInMemoryDatabase() throws Exception
    {
        final String dbURL = JDBC_MEM_URL_PREFIX + name + flags ;

        // hold a connection so h2 does not close the database
        connection = getConnection(dbURL);
    }
  
    /**
     * Start a remote/server database
     * @throws Exception
     */
    private void startRemoteDatabase() throws Exception
    {
        final File h2Dir = checkDataDir() ;
        dbPath = new File(h2Dir, name);
      
        // Start DB in new thread, or else it will block us
        serverThread = new Thread("h2-" + name)
        {
            public void run()
            {
                try
                {
                  log.debug( "Starting remote h2 db with port : " + port );
                  final String[] args = new String[] {
                      "-baseDir", dbPath.getAbsolutePath(),
                      "-tcpPort", String.valueOf(port),
                      "-tcpAllowOthers","" }; //  need the extra empty string or a exception is thrown by H2
                  final Server server = Server.createTcpServer(args) ;
                  server.start() ;
                  setRemoteServer(server);
              }
              catch (Exception e)
              {
                 log.error("Failed to start database", e);
                }
            }
        };
       
        serverThread.start();
       
        if (delay > 0)
        {
            log.debug("Waiting for Database initialisation: maximum " + delay + " milliseconds") ;
            try
            {
                serverThread.join(delay) ;
            }
            catch (final InterruptedException ie)
            {
                Thread.currentThread().interrupt() ;
            }
           
            if (serverThread.isAlive())
            {
                log.warn("Database initialisation is still active") ;
            }
            else
            {
                log.debug("Database initialisation completed") ;
            }
        }
    }

   /**
    * Stop the standalone (in process) database.
    */
   private void stopStandaloneDatabase() throws Exception
   {
       try
       {
           final Statement stmt = connection.createStatement() ;
           stmt.execute("shutdown") ;
       }
       finally
       {
           connection = null;
       }
       log.info("Database standalone closed clean");
   }

   /**
    * Stop the in memory database.
    */
   private void stopInMemoryDatabase() throws Exception
   {
       try
       {
           connection.close() ;
       }
       finally
       {
           connection = null;
       }
       log.info("Database in memory closed clean");
   }
  
   /**
    * Stop the remote database.
    */
   private void stopRemoteDatabase() throws SQLException
   {
       final Server server = getRemoteServer() ;
       if (server != null)
       {
           server.stop() ;
       }
   }
  
   /**
    * Set the remote server instance.
    * @param remoteServer The remote server instance.
    */
   private synchronized void setRemoteServer(final Server remoteServer)
   {
       this.remoteServer = remoteServer ;
   }
  
   /**
    * Get the remote server instance.
    * @return The remote server instance.
    */
   private synchronized Server getRemoteServer()
   {
       return remoteServer ;
   }
  
    /**
     * Get the connection.
     *
     * @param dbURL jdbc url.
     * @return the connection, allocate one if needed.
     * @throws Exception
     */
    private synchronized Connection getConnection(String dbURL) throws Exception
    {
        if (connection == null)
        {
            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            Class.forName(JDBC_DRIVER_CLASS, true, cl).newInstance();
            connection = DriverManager.getConnection(dbURL, user, password);
        }
        return connection;
    }
  
    /**
     * Check the existence of the h2 data directory.
     * @return The h2 data directory.
     * @throws IOException For errors checking/creating the h2 data directory.
     */
    private File checkDataDir() throws IOException
    {
        // Get the server data directory
        final File dataDir = getDataDir();

        // Get DB directory
        final File h2Dir = new File(dataDir, H2_DATA_DIR);

        if (!h2Dir.exists())
        {
            h2Dir.mkdirs();
        }
        else if (!h2Dir.isDirectory())
        {
            throw new IOException("Failed to create directory: " + h2Dir);
        }
        return h2Dir ;
    }
  
    File getDataDir()
    {
        if (datadir == null)
        {
            //final ServerConfigImpl serverConfig = (ServerConfigImpl) MBeanProxyExt.create(ServerConfigImplMBean.class,ServerConfigImplMBean.OBJECT_NAME);
            //return serverConfig.getServerDataDir();
          org.jboss.soa.dsp.server.ServerConfig serverConfig=
            org.jboss.soa.bpel.runtime.JBossDSPFactory.getServerConfig();
          return(serverConfig.getServerDeployDir());
        }
        return new File(datadir);
    }

    public void setDataDir(String datadir)
    {
        this.datadir = datadir;
    }

}
TOP

Related Classes of org.jboss.soa.bpel.runtime.db.H2Database

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.