/*
 *
 * Derby - Class org.apache.derbyTesting.junit.JDBCDataSource
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.derbyTesting.junit;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;

import junit.framework.Assert;

/**
 * Utility methods related to JDBC DataSource objects.
 *
 */
public class JDBCDataSource {
    
    /**
     * Return a DataSource corresponding to the current
     * configuration. The getConnection() method will return
     * a connection identical to TestConfiguration.openDefaultConnection().
     */
    public static javax.sql.DataSource getDataSource()
    {
        return getDataSource(TestConfiguration.getCurrent(), (HashMap) null);
    }
    
    /**
     * Create a new DataSource object setup from the passed in TestConfiguration.
     * The getConnection() method will return a connection identical to
     * TestConfiguration.openDefaultConnection().
     */
    static javax.sql.DataSource getDataSource(TestConfiguration config,
            HashMap beanProperties)
    {
        if (beanProperties == null)
             beanProperties = getDataSourceProperties(config);
        
        String dataSourceClass = config.getJDBCClient().getDataSourceClassName();
        
        return (javax.sql.DataSource) getDataSourceObject(dataSourceClass,
                beanProperties);
    }
    
    /**
     * Create a HashMap with the set of Derby DataSource
     * Java bean properties corresponding to the configuration.
     */
    static HashMap getDataSourceProperties(TestConfiguration config) 
    {
        HashMap beanProperties = new HashMap();
        
        if (!config.getJDBCClient().isEmbedded()) {
            beanProperties.put("serverName", config.getHostName());
            beanProperties.put("portNumber", new Integer(config.getPort()));
        }
        
        beanProperties.put("databaseName", config.getDatabaseName());
        beanProperties.put("user", config.getUserName());
        beanProperties.put("password", config.getUserPassword());

        
        return beanProperties;
    }
    
    /**
     * Return a DataSource object of the passsed in type
     * configured with the passed in Java bean properties.
     * This will actually work with an object that has Java bean
     * setter methods.
     */
    static Object getDataSourceObject(String classname, HashMap beanProperties)
    {

        Object ds;
        try {
            ds = Class.forName(classname).newInstance();
            
            for (Iterator i = beanProperties.keySet().iterator();
                i.hasNext(); )
            {
                String property = (String) i.next();
                Object value = beanProperties.get(property);
                
                setBeanProperty(ds, property, value);
            }
            return ds;
        } catch (Exception e) {
            Assert.fail(e.getMessage());
            return null;
        }
    }
    
    /**
     * Set a bean property for a data source. This code can be used
     * on any data source type.
     * @param ds DataSource to have property set
     * @param property name of property.
     * @param value Value, type is derived from value's class.
     */
    public static void setBeanProperty(Object ds, String property, Object value)
    {
        String setterName = getSetterName(property);
        
        // Base the type of the setter method from the value's class.
        Class clazz = value.getClass();      
        if (Integer.class.equals(clazz))
            clazz = Integer.TYPE;
        else if (Boolean.class.equals(clazz))
            clazz = Boolean.TYPE;

        try {
            Method setter = ds.getClass().getMethod(setterName,
                    new Class[] {clazz});
            setter.invoke(ds, new Object[] {value});
        } catch (Exception e) {
            Assert.fail(e.getMessage());
        }   
    }
    
    private static String getSetterName(String attribute) {
        return "set" + Character.toUpperCase(attribute.charAt(0))
                + attribute.substring(1);
    }
}

@@ -939,16 +939,46 @@
 Method;%0A
+import java.sql.SQLException;%0A
 import j
@@ -1515,32 +1515,462 @@
  %7D%0A    %0A    /**%0A
+     * Return a DataSource corresponding to the current%0A     * configuration except that the databse name is different.%0A     */%0A    public static javax.sql.DataSource getDataSource(String dbName)%0A    %7B%0A        // default DataSource%0A        javax.sql.DataSource ds = getDataSource();%0A        %0A        // Override the database name%0A        setBeanProperty(ds, %22databaseName%22, dbName);%0A        %0A        return ds;%0A    %7D%0A    %0A    /**%0A
      * Create a 
@@ -5325,10 +5325,597 @@
 ;%0A    %7D%0A
+    %0A    /**%0A     * Shutdown the database described by this data source.%0A     * The shutdownDatabase property is cleared by this method.%0A     */%0A    public static void shutdownDatabase(javax.sql.DataSource ds)%0A    %7B%0A        setBeanProperty(ds, %22shutdownDatabase%22, %22shutdown%22);%0A        try %7B%0A            ds.getConnection();%0A            Assert.fail(%22Database failed to shut down%22);%0A        %7D catch (SQLException e) %7B%0A             BaseJDBCTestCase.assertSQLState(%22Database shutdown%22, %2208006%22, e);%0A        %7D finally %7B%0A            setBeanProperty(ds, %22shutdownDatabase%22, %22%22);%0A        %7D%0A    %7D%0A
 %7D%0A

Add utility methods for JUnit tests to get a DataSource based upon the current configuration but pointing to a different database and to shutdown a database from a data source.