View Javadoc

1   /*
2    * #%L
3    * Bitrepository Common
4    * %%
5    * Copyright (C) 2010 - 2012 The State and University Library, The Royal Library and The State Archives, Denmark
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as 
9    * published by the Free Software Foundation, either version 2.1 of the 
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public 
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
21   */
22  package org.bitrepository.service.database;
23  
24  import com.mchange.v2.c3p0.ComboPooledDataSource;
25  import com.mchange.v2.c3p0.DataSources;
26  import java.sql.Connection;
27  import java.sql.SQLException;
28  import java.util.Properties;
29  import org.bitrepository.common.ArgumentValidator;
30  import org.bitrepository.settings.referencesettings.DatabaseSpecifics;
31  import org.slf4j.Logger;
32  import org.slf4j.LoggerFactory;
33  
34  /**
35   * The connector to a database.
36   */
37  public class DBConnector {
38      /** The log.*/
39      private Logger log = LoggerFactory.getLogger(getClass());
40      /** The specifications for connection to the database.*/
41      private final DatabaseSpecifics databaseSpecifics;
42      /** The pool with data sources for the database connections.*/
43      private ComboPooledDataSource connectionPool;
44      
45      /**
46       * Constructor.
47       * @param databaseSpecifics The specifics for the configuration of the database.
48       */
49      public DBConnector(DatabaseSpecifics databaseSpecifics) {
50          ArgumentValidator.checkNotNull(databaseSpecifics, "DatabaseSpecifics specifics");
51  
52          silenceC3P0Logger();
53          this.databaseSpecifics = databaseSpecifics;
54          this.connectionPool = new ComboPooledDataSource();
55          initialiseConnectionPool();
56      }
57      
58      /**
59       * @return The class for the driver for the database.
60       */
61      public String getDatabaseDriverClass() {
62          return databaseSpecifics.getDriverClass();
63      }
64      
65      /**
66       * Initialises the ConnectionPool for the connections to the database.
67       */
68      private void initialiseConnectionPool() {
69          try {
70              log.info("Creating the connection to the database '" + databaseSpecifics + "'.");
71              connectionPool.setDriverClass(databaseSpecifics.getDriverClass());
72              connectionPool.setJdbcUrl(databaseSpecifics.getDatabaseURL());
73              if(databaseSpecifics.isSetUsername()) {
74                  connectionPool.setUser(databaseSpecifics.getUsername());
75              }
76              if(databaseSpecifics.isSetPassword()) {
77                  connectionPool.setPassword(databaseSpecifics.getPassword());
78              }
79          } catch (Exception e) {
80              throw new IllegalStateException("Could not connect to the database '" + databaseSpecifics + "'", e);
81          }
82      }
83  
84      /**
85       * Hack to kill com.mchange.v2 log spamming.
86       */
87      private void silenceC3P0Logger() {
88          Properties p = new Properties(System.getProperties());
89          p.put("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
90          p.put("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "OFF"); // or any other
91          System.setProperties(p);
92      }
93      
94      /**
95       * Creates and connects to the database.
96       * @return The connection to the database.
97       */
98      public Connection getConnection() {
99          try {
100             return connectionPool.getConnection();
101         } catch (SQLException e) {
102             throw new IllegalStateException("Could not establish connection to the database: '" + databaseSpecifics 
103                     + "'", e);
104         }
105     }
106     
107     /**
108      * Cleans up after use.
109      */
110     public void destroy() {
111         try {
112             DataSources.destroy(connectionPool);
113         } catch (SQLException e) {
114             log.error("Could not clean up the database '" + databaseSpecifics + "'.", e);
115         }
116     }
117 }