Package nexj.core.tools

Source Code of nexj.core.tools.DatabaseTool

// Copyright 2010 NexJ Systems Inc. This software is licensed under the terms of the Eclipse Public License 1.0
package nexj.core.tools;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.Locale;
import java.util.Properties;

import nexj.core.meta.Component;
import nexj.core.meta.Metadata;
import nexj.core.meta.Repository;
import nexj.core.meta.persistence.DataSource;
import nexj.core.meta.persistence.sql.RelationalDatabase;
import nexj.core.meta.persistence.sql.RelationalDatabaseFragment;
import nexj.core.meta.persistence.sql.RelationalSchema;
import nexj.core.persistence.sql.DefaultSQLSchemaManagerFactory;
import nexj.core.persistence.sql.SQLAdapter;
import nexj.core.persistence.sql.SQLConnectionFactory;
import nexj.core.persistence.sql.SQLSchemaManager;
import nexj.core.runtime.Context;
import nexj.core.runtime.InvocationContext;
import nexj.core.runtime.ThreadContextHolder;
import nexj.core.util.Logger;
import nexj.core.util.PropertyUtil;
import nexj.core.util.SysUtil;

/**
* Database command-line tool shell.
*/
public abstract class DatabaseTool extends GenericTool
{
   // associations

   /**
    * The SQL connection used by the tool.
    */
   private Connection m_connection;

   /**
    * The class logger.
    */
   private final static Logger s_logger = Logger.getLogger(DatabaseTool.class);

   // operations

   /**
    * @see nexj.core.tools.GenericTool#getOptionUsage()
    */
   protected final String[] getOptionUsage()
   {
      String[] usageArray = new String[]
      {
         "-Dmeta.datasource=<metadata data source name>",
         "-Ddb.driver=<driver class name>",
         "-Ddb.url=<URL>",
         "-Ddb.user=<user>",
         "-Ddb.password=<password>",
         "-Ddb.prop#=<value#>",
      };

      String[] usageArray2 = getAdditionalOptionUsage();

      if (usageArray2 != null)
      {
         String[] usageArray3 = new String[usageArray.length + usageArray2.length];
        
         System.arraycopy(usageArray, 0, usageArray3, 0, usageArray.length);
         System.arraycopy(usageArray2, 0, usageArray3, usageArray.length, usageArray2.length);
        
         return usageArray3;
      }

      return usageArray;
   }
  
   /**
    * The same as getOptionUsage(), but for additional options.
    * @see nexj.core.tools.GenericTool#getOptionUsage()
    */
   protected String[] getAdditionalOptionUsage()
   {
      return null;
   }
  
   /**
    * Gets an SQL connection based on the configuration properties.
    * @return The SQL connection.
    * @throws IllegalArgumentException if a required property is missing.
    * @throws SQLException if a connection opening error occurs.
    */
   protected final Connection getConnection() throws SQLException, IllegalArgumentException
   {
      if (m_connection == null)
      {
         String sDriver = getProperty("db.driver");
         String sURL = getProperty("db.url");
        
         if (sDriver != null && sURL != null)
         {
            String sUser = getRequiredProperty("db.user");
            String sPassword = getProperty("db.password", "");
            StringBuffer buf = new StringBuffer(128);
  
            for (int i = 1; ; ++i)
            {
               String sValue = getProperty("db.prop" + i);
              
               if (sValue == null)
               {
                  break;
               }
              
               buf.append(sValue);
               buf.append(SysUtil.LINE_SEP);
            }
           
            Properties connectionProperties;
           
            try
            {
               connectionProperties = PropertyUtil.fromString(buf.toString());
            }
            catch (IOException e)
            {
               connectionProperties = new Properties();
            }
           
            try
            {
               Class.forName(sDriver);
            }
            catch (ClassNotFoundException e)
            {
               throw new IllegalArgumentException("Cannot find the driver \"" + sDriver + "\"");
            }
  
            connectionProperties.setProperty("user", sUser);
            connectionProperties.setProperty("password", sPassword);
  
            m_connection = DriverManager.getConnection(sURL, connectionProperties);
         }
         else
         {
            SQLAdapter adapter = (SQLAdapter)getDatabase().getComponent().getInstance(null);
           
            m_connection = adapter.getConnectionFactory().getConnection(adapter);
         }
      }

      return m_connection;
   }
  
   /**
    * Closes the SQL connection, if it is still open.
    */
   protected final void closeConnection()
   {
      if (m_connection != null)
      {
         try
         {
            m_connection.close();
         }
         catch (SQLException e)
         {
            s_logger.debug("Error closing the SQL connection", e);
         }
        
         m_connection = null;
      }
   }

   /**
    * @return The relational database.
    */
   protected RelationalDatabase getDatabase()
   {
      return getDatabase(null);
   }

   /**
    * @return The relational database.
    * @param metatada The Metadata object to query (null == Repository.getMetadata()).
    * @throws IllegalArgumentException If no RelationalDatabase by that name was found.
    */
   protected RelationalDatabase getDatabase(Metadata metadata) throws IllegalArgumentException
   {
      metadata = (metadata == null) ? Repository.getMetadata() : metadata;

      DataSource ds = metadata.getDataSource(getRequiredProperty("meta.datasource"));

      if (ds instanceof RelationalDatabase)
      {
         return (RelationalDatabase)ds;
      }

      throw new IllegalArgumentException("Data source \"" + ds.getName() +
                                         "\" is not a relational database");
   }

   /**
    * @return The relational schema.
    */
   protected RelationalSchema getSchema()
   {
      return (RelationalSchema)getDatabase().getSchema();
   }

   /**
    * Instantiates a schema manager based on a property value or on a connection metadata.
    * @param connection The SQL connection. Can be null.
    */
   protected SQLSchemaManager getSchemaManager(Connection connection) throws SQLException
   {
      String sDataSource = (connection == null) ? getRequiredProperty("meta.datasource") : getProperty("meta.datasource") ;
      SQLSchemaManager manager;

      if (sDataSource == null)
      {
         manager = DefaultSQLSchemaManagerFactory.create(connection);
      }
      else
      {
         manager = ((SQLAdapter)getDatabase().getComponent().getInstance(null)).createSchemaManager(getDatabase());

         if (connection != null)
         {
            manager.setConnection(connection);
         }
      }

      String sOwner = getProperty("meta.owner");

      if (sOwner != null)
      {
         manager.setOwner((sOwner.equals(".")) ? "" : sOwner);
      }

      return manager;
   }

   /**
    * @see nexj.core.tools.GenericTool#dispose()
    */
   protected void dispose()
   {
      closeConnection();
      super.dispose();
   }

   /**
    * Test a data source connection.
    *
    * @param metadata The metadata.
    * @param sDataSource The data source name.
    * @return false if a SQL connection could not be obtained
    */
   public static void testConnection(Metadata metadata, String sDataSource) throws SQLException
   {
      InvocationContext context = null;
      Context contextSaved = ThreadContextHolder.getContext();

      try
      {
         DataSource db = metadata.getDataSource(sDataSource);
         Component comp = metadata.findComponent("System.InvocationContext");
         context = (comp != null) ? (InvocationContext)comp.getInstance(null) : new InvocationContext(metadata);

         context.initialize(null);
         context.setLocale(Locale.getDefault());
         context.setProtected(false);
         context.setSecure(false);
         context.setPartitioned(false);

         for (Iterator itr = db.getFragmentIterator(); itr.hasNext();)
         {
            Object o = itr.next();

            if (o instanceof RelationalDatabaseFragment)
            {
               ((SQLConnectionFactory)((RelationalDatabaseFragment)o).getConnectionFactory().getInstance(context))
                  .getConnection(null).close();
            }
         }
      }
      finally
      {
         if (context != null)
         {
            context.complete(false);
         }

         ThreadContextHolder.setContext(contextSaved);
      }
   }
}
TOP

Related Classes of nexj.core.tools.DatabaseTool

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.