/*
 * Copyright (C) 2013, 2014 Brett Wooldridge
 *
 * 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 com.zaxxer.hikari.util;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Enumeration;
import java.util.Map.Entry;
import java.util.Properties;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class DriverDataSource implements DataSource
{
   private final Logger LOGGER = LoggerFactory.getLogger(DriverDataSource.class);

   private final String jdbcUrl;
   private final Properties driverProperties;
   private Driver driver;

   public DriverDataSource(String jdbcUrl, String driverClassName, Properties properties, String username, String password)
   {
      this.jdbcUrl = jdbcUrl;
      this.driverProperties = new Properties();

      for (Entry<Object, Object> entry : properties.entrySet()) {
         driverProperties.setProperty(entry.getKey().toString(), entry.getValue().toString());
      }

      if (username != null) {
         driverProperties.put("user", driverProperties.getProperty("user", username));
      }
      if (password != null) {
         driverProperties.put("password", driverProperties.getProperty("password", password));
      }

      if (driverClassName != null) {
         Enumeration<Driver> drivers = DriverManager.getDrivers();
         while (drivers.hasMoreElements()) {
            Driver d = drivers.nextElement();
            if (d.getClass().getName().equals(driverClassName)) {
               this.driver = d;
               break;
            }
         }

         if (driver == null) {
            LOGGER.warn("Registered driver with driverClassName={} was not found, trying direct instantiation.", driverClassName);
            try {
               Class<?> driverClass = this.getClass().getClassLoader().loadClass(driverClassName);
               this.driver = (Driver) driverClass.newInstance();
            }
            catch (Exception e) {
               LOGGER.warn("Could not instantiate instance of driver class {}, trying JDBC URL resolution", driverClassName, e);
            }
         }
      }

      if (driver == null) {
         try {
            driver = DriverManager.getDriver(jdbcUrl);
         }
         catch (SQLException e) {
            throw new RuntimeException("Unable to get driver instance for jdbcUrl=" + jdbcUrl, e);
         }
      }
   }

   @Override
   public Connection getConnection() throws SQLException
   {
      return driver.connect(jdbcUrl, driverProperties);
   }

   @Override
   public Connection getConnection(String username, String password) throws SQLException
   {
      return getConnection();
   }

   @Override
   public PrintWriter getLogWriter() throws SQLException
   {
      throw new SQLFeatureNotSupportedException();
   }

   @Override
   public void setLogWriter(PrintWriter logWriter) throws SQLException
   {
      throw new SQLFeatureNotSupportedException();
   }

   @Override
   public void setLoginTimeout(int seconds) throws SQLException
   {
      DriverManager.setLoginTimeout(seconds);
   }

   @Override
   public int getLoginTimeout() throws SQLException
   {
      return DriverManager.getLoginTimeout();
   }

   public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException
   {
      return driver.getParentLogger();
   }

   @Override
   public <T> T unwrap(Class<T> iface) throws SQLException
   {
      throw new SQLFeatureNotSupportedException();
   }

   @Override
   public boolean isWrapperFor(Class<?> iface) throws SQLException
   {
      return false;
   }

   public void shutdown()
   {
   }
}

@@ -2152,37 +2152,32 @@
 %0A               
-this.
 driver = d;%0A    
@@ -2172,16 +2172,16 @@
 er = d;%0A
+
         
@@ -2510,29 +2510,24 @@
             
-this.
 driver = (Dr
@@ -2762,32 +2762,47 @@
      %7D%0A      %7D%0A%0A
+      try %7B%0A   
       if (driver
@@ -2813,31 +2813,16 @@
 null) %7B%0A
-         try %7B%0A
         
@@ -2878,24 +2878,204 @@
        %7D%0A   
+      else if (!driver.acceptsURL(jdbcUrl)) %7B%0A            throw new RuntimeException(%22Driver %22 + driverClassName + %22 claims to not accept JDBC URL %22 + jdbcUrl);%0A         %7D%0A      %7D%0A
       catch 
@@ -3085,35 +3085,32 @@
 LException e) %7B%0A
-   
          throw n
@@ -3189,27 +3189,16 @@
 rl, e);%0A
-         %7D%0A
       %7D%0A

Add driver.acceptsUrl() check.