View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.data.platform;
17  
18  import org.springframework.dao.DataAccessException;
19  import org.springframework.jdbc.core.ConnectionCallback;
20  import org.springframework.jdbc.core.JdbcTemplate;
21  
22  import javax.sql.DataSource;
23  import java.sql.Connection;
24  import java.sql.DatabaseMetaData;
25  import java.sql.SQLException;
26  import java.util.concurrent.ConcurrentHashMap;
27  import java.util.concurrent.ConcurrentMap;
28  
29  /**
30   * Contains constants and utilities related to the supported database platforms.
31   *
32   * <p>
33   * We use a String to represent the platform name as opposed to an Enum because this allows for the potential to
34   * configure and use custom platforms at runtime without requiring internal code modification to support a new platform.
35   * </p>
36   *
37   * @author Kuali Rice Team (rice.collab@kuali.org)
38   */
39  public final class DatabasePlatforms {
40  
41      /**
42       * The name of the Oracle platform.
43       */
44      public static final String ORACLE = "Oracle";
45  
46      /**
47       * The name of the MySQL platform.
48       */
49      public static final String MYSQL = "MySQL";
50  
51      private static final ConcurrentMap<DataSource, DatabasePlatformInfo> platformCache =
52              new ConcurrentHashMap<DataSource, DatabasePlatformInfo>();
53  
54      /**
55       * Gets the platform information from the {@link DataSource}.
56       *
57       * @param dataSource the {@link DataSource} to consult.
58       * @return the platform information from the {@link DataSource}.
59       */
60      public static DatabasePlatformInfo detectPlatform(DataSource dataSource) {
61          if (dataSource == null) {
62              throw new IllegalArgumentException("DataSource must not be null.");
63          }
64          DatabasePlatformInfo platformInfo = platformCache.get(dataSource);
65          if (platformInfo == null) {
66              JdbcTemplate template = new JdbcTemplate(dataSource);
67              platformInfo = platformCache.putIfAbsent(dataSource, template.execute(
68                      new ConnectionCallback<DatabasePlatformInfo>() {
69                          @Override
70                          public DatabasePlatformInfo doInConnection(
71                                  Connection connection) throws SQLException, DataAccessException {
72                              DatabaseMetaData metadata = connection.getMetaData();
73                              String vendorName = metadata.getDatabaseProductName();
74                              int version = metadata.getDatabaseMajorVersion();
75                              return new DatabasePlatformInfo(vendorName, version);
76                          }
77                      }));
78              if (platformInfo == null) {
79                  platformInfo = platformCache.get(dataSource);
80              }
81          }
82          return platformInfo;
83      }
84  
85      /**
86       * No-op constructor for final class.
87       */
88      private DatabasePlatforms() {}
89  
90  }