/**
 * Copyright 2005-2014 The Kuali Foundation
 *
 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
 *
 * 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.kuali.rice.krad.data.platform;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Contains constants and utilities related to the supported database platforms.
 *
 * <p>
 * We use a String to represent the platform name as opposed to an Enum because this allows for the potential to
 * configure and use custom platforms at runtime without requiring internal code modification to support a new platform.
 * </p>
 *
 * @author Kuali Rice Team (rice.collab@kuali.org)
 */
public final class DatabasePlatforms {

    /**
     * The name of the Oracle platform.
     */
    public static final String ORACLE = "Oracle";

    /**
     * The name of the MySQL platform.
     */
    public static final String MYSQL = "MySQL";

    private static final ConcurrentMap<DataSource, DatabasePlatformInfo> platformCache =
            new ConcurrentHashMap<DataSource, DatabasePlatformInfo>();

    /**
     * Gets the platform information from the {@link DataSource}.
     *
     * @param dataSource the {@link DataSource} to consult.
     * @return the platform information from the {@link DataSource}.
     */
    public static DatabasePlatformInfo detectPlatform(DataSource dataSource) {
        if (dataSource == null) {
            throw new IllegalArgumentException("DataSource must not be null.");
        }
        DatabasePlatformInfo platformInfo = platformCache.get(dataSource);
        if (platformInfo == null) {
            JdbcTemplate template = new JdbcTemplate(dataSource);
            platformInfo = platformCache.putIfAbsent(dataSource, template.execute(
                    new ConnectionCallback<DatabasePlatformInfo>() {
                        @Override
                        public DatabasePlatformInfo doInConnection(
                                Connection connection) throws SQLException, DataAccessException {
                            DatabaseMetaData metadata = connection.getMetaData();
                            String vendorName = metadata.getDatabaseProductName();
                            int version = metadata.getDatabaseMajorVersion();
                            return new DatabasePlatformInfo(vendorName, version);
                        }
                    }));
            if (platformInfo == null) {
                platformInfo = platformCache.get(dataSource);
            }
        }
        return platformInfo;
    }

    /**
     * No-op constructor for final class.
     */
    private DatabasePlatforms() {}

}

@@ -937,24 +937,110 @@
 LException;%0A
+import java.util.Collections;%0Aimport java.util.IdentityHashMap;%0Aimport java.util.Map;%0A
 import java.
@@ -1066,32 +1066,32 @@
 currentHashMap;%0A
-
 import java.util
@@ -1789,26 +1789,16 @@
 c final 
-Concurrent
 Map%3CData
@@ -1840,18 +1840,16 @@
 ormCache
- =
 %0A       
@@ -1857,22 +1857,50 @@
     
-new Concurrent
+= Collections.synchronizedMap(new Identity
 Hash
@@ -1937,16 +1937,18 @@
 rmInfo%3E(
+8)
 );%0A%0A    
@@ -2549,38 +2549,27 @@
             
-platformInfo =
+   
  platformCac
@@ -2578,16 +2578,8 @@
 .put
-IfAbsent
 (dat
@@ -2604,37 +2604,16 @@
 execute(
-%0A                    
 new Conn
@@ -2649,24 +2649,28 @@
 rmInfo%3E() %7B%0A
+    
             
@@ -2711,24 +2711,28 @@
             
+    
 public Datab
@@ -2763,16 +2763,20 @@
 ection(%0A
+    
         
@@ -2885,32 +2885,36 @@
                 
+ 
+   
 DatabaseMetaData
@@ -2947,24 +2947,28 @@
 MetaData();%0A
+    
             
@@ -3066,16 +3066,20 @@
         
+   
+ 
 int vers
@@ -3116,24 +3116,28 @@
 rVersion();%0A
+    
             
@@ -3206,16 +3206,20 @@
 rsion);%0A
+    
         

Update to use identityHashMap