/* * Copyright 2013 Simon Thiel * * This file is part of SitJar. * * SitJar is free software: you can redistribute it and/or modify * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SitJar 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SitJar. If not, see <http://www.gnu.org/licenses/lgpl.txt>. */ package sit.db; import java.lang.reflect.Method; import java.sql.Driver; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Enumeration; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; public class ConnectionManager { public static final int MAX_DB_CONNECTIONS_BEFORE_WARNING = 10; private final String databaseUrl; private final String user; private final String password; private int connectionCounter = 0; private final Vector<Connection> connections = new Vector(); private final DatabaseSetup dbSetup; /** * Constructor * * @param dbSetup * */ public ConnectionManager(DatabaseSetup dbSetup) { this.dbSetup = dbSetup; this.databaseUrl = dbSetup.getJdbcConnector() + dbSetup.getDatabaseName(); this.user = dbSetup.getUserName(); this.password = dbSetup.getPassword(); try { Class.forName(dbSetup.getDatabaseDriver()); } catch (ClassNotFoundException e) { throw new RuntimeException("Cannot find the driver in the classpath!", e); } } private Connection createConnection() { try { connectionCounter++; if (connectionCounter > MAX_DB_CONNECTIONS_BEFORE_WARNING) { Logger.getLogger(ConnectionManager.class.getName()).log(Level.WARNING, "Attention - created " + connectionCounter + " database connections! Please check your implementation"); } return new Connection(DriverManager.getConnection(this.databaseUrl, this.user, this.password)); } catch (SQLException sqle) { //System.err.println(sqle); throw new RuntimeException("Cannot connect to database!", sqle); } } public synchronized Connection getConnection() throws SQLException { Connection result; if (connections.isEmpty()) { result = createConnection(); } else { result = connections.remove(0); } return result; } public synchronized void returnConnection(Connection connection) throws SQLException { connection.closeAndClearStatements(); connections.add(connection); } public synchronized void shutdown() { for (Connection connection : connections) { connection.shutdown(); } Enumeration<Driver> drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { try { DriverManager.deregisterDriver(drivers.nextElement()); } catch (SQLException ex) { Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); } } try { Class<?> cls = Class.forName(dbSetup.getCleanupThreadClassName()); Method mth = (cls == null ? null : cls.getMethod("shutdown")); if (mth != null) { Logger.getLogger(ConnectionManager.class.getName()).log(Level.INFO, "MySQL connection cleanup thread shutdown"); mth.invoke(null); Logger.getLogger(ConnectionManager.class.getName()).log(Level.INFO, "MySQL connection cleanup thread shutdown successful"); } } catch (Throwable ex) { Logger.getLogger(ConnectionManager.class.getName()).log(Level.SEVERE, "[ER] Failed to shutdown SQL connection cleanup thread: " + ex.getMessage(), ex); } } }