/** * Copyright (C) Alejandro Ayuso * * This file is part of Amforeas. Amforeas is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the License, or any later version. * * Amforeas is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with Amforeas. If not, see <http://www.gnu.org/licenses/>. */ package amforeas.jdbc; import java.sql.Connection; import java.sql.SQLException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.sql.DataSource; import org.apache.commons.dbcp.ConnectionFactory; import org.apache.commons.dbcp.DriverManagerConnectionFactory; import org.apache.commons.dbcp.PoolableConnectionFactory; import org.apache.commons.dbcp.PoolingDataSource; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.pool.impl.GenericObjectPool; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import amforeas.SingletonFactoryImpl; import amforeas.SingletonFactory; import amforeas.config.AmforeasConfiguration; import amforeas.config.DatabaseConfiguration; /** * Class in charge of registering a pool of connections for each database * and provide access to this connections. */ public class JDBCConnectionFactory { private static final Logger l = LoggerFactory.getLogger(JDBCConnectionFactory.class); private final AmforeasConfiguration configuration; private final Map<String, GenericObjectPool> connectionPool = new ConcurrentHashMap<String, GenericObjectPool>(); public JDBCConnectionFactory() { SingletonFactory factory = new SingletonFactoryImpl(); this.configuration = factory.getConfiguration(); } public JDBCConnectionFactory(SingletonFactory factory) { this.configuration = factory.getConfiguration(); } /** * Instantiates a new JDBCConnectionFactory if required and creates a connections pool for every database. * @return the instance of the singleton. */ public void load () { for (DatabaseConfiguration db : configuration.getDatabases()) { l.debug("Registering Connection Pool for {}", db.getDatabase()); GenericObjectPool pool = new GenericObjectPool(null, db.getMaxConnections()); ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(db.toJdbcURL(), db.getUsername(), db.getPassword()); PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, pool, null, null, db.isReadOnly(), true); poolableConnectionFactory.hashCode(); this.connectionPool.put(db.getDatabase(), pool); } } /** * Gives access to a {@link java.sql.Connection} for the given database. * @param dbcfg a registered {@link amforeas.config.DatabaseConfiguration} * @return a {@link java.sql.Connection} * @throws SQLException */ public Connection getConnection (final DatabaseConfiguration dbcfg) throws SQLException { l.debug("Obtaining a connection from the datasource"); DataSource ds = getDataSource(dbcfg); return ds.getConnection(); } /** * Gives access to a {@link java.sql.DataSource} for the given database. * @param dbcfg a registered {@link amforeas.config.DatabaseConfiguration} * @return a {@link java.sql.DataSource} */ public DataSource getDataSource (final DatabaseConfiguration dbcfg) { PoolingDataSource dataSource = new PoolingDataSource(this.connectionPool.get(dbcfg.getDatabase())); return dataSource; } /** * Instantiates a new {@linkplain org.apache.commons.dbutils.QueryRunner} for the given database. * @param dbcfg a registered {@link amforeas.config.DatabaseConfiguration} * @return a new {@linkplain org.apache.commons.dbutils.QueryRunner} */ public QueryRunner getQueryRunner (final DatabaseConfiguration dbcfg) { DataSource ds = getDataSource(dbcfg); return new QueryRunner(ds); } /** * Close all connections in the pool. * @throws SQLException */ public void closeConnections () throws SQLException { for (DatabaseConfiguration dbcfg : configuration.getDatabases()) { l.debug("Shutting down JDBC connection {}", dbcfg.getDatabase()); getConnection(dbcfg).close(); } } }