| /* $Id$ */ |
| |
| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache 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.apache.org/licenses/LICENSE-2.0 |
| * |
| * 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.apache.manifoldcf.core.jdbcpool; |
| |
| import javax.naming.*; |
| import javax.sql.*; |
| import java.util.*; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| |
| import org.apache.manifoldcf.core.interfaces.ManifoldCFException; |
| import org.apache.manifoldcf.core.interfaces.LockManagerFactory; |
| import org.apache.manifoldcf.core.system.ManifoldCF; |
| |
| /** An instance of this class manages a number of (independent) connection pools. |
| */ |
| public class ConnectionPoolManager |
| { |
| public static final String _rcsid = "@(#)$Id$"; |
| |
| protected final Map<String,ConnectionPool> poolMap; |
| protected final ConnectionCloserThread connectionCloserThread; |
| protected volatile AtomicBoolean shuttingDown = new AtomicBoolean(false); |
| protected final boolean debug; |
| |
| public ConnectionPoolManager(int count, boolean debug) |
| throws ManifoldCFException |
| { |
| this.debug = debug; |
| poolMap = new HashMap<String,ConnectionPool>(count); |
| connectionCloserThread = new ConnectionCloserThread(); |
| connectionCloserThread.start(); |
| } |
| |
| /** Look for a pool with a given key. |
| */ |
| public synchronized ConnectionPool getPool(String poolKey) |
| { |
| return poolMap.get(poolKey); |
| } |
| |
| /** Set up a pool with a given key. |
| */ |
| public synchronized ConnectionPool addAlias(String poolKey, String driverClassName, String dbURL, |
| String userName, String password, int maxSize, long expiration) |
| throws ClassNotFoundException, InstantiationException, IllegalAccessException |
| { |
| Class.forName(driverClassName).newInstance(); |
| ConnectionPool cp = new ConnectionPool(dbURL,userName,password,maxSize,expiration,debug); |
| poolMap.put(poolKey,cp); |
| return cp; |
| } |
| |
| public void shutdown() |
| { |
| //System.out.println("JDBC POOL SHUTDOWN CALLED"); |
| shuttingDown.set(true); |
| while (connectionCloserThread.isAlive()) |
| { |
| try |
| { |
| Thread.sleep(1000L); |
| } |
| catch (InterruptedException e) |
| { |
| // Ignore this until the thread is down |
| connectionCloserThread.interrupt(); |
| } |
| } |
| synchronized (this) |
| { |
| Iterator<String> iter = poolMap.keySet().iterator(); |
| while (iter.hasNext()) |
| { |
| String poolKey = iter.next(); |
| ConnectionPool cp = poolMap.get(poolKey); |
| cp.closePool(); |
| } |
| } |
| } |
| |
| protected void cleanupExpiredConnections(long cleanupTime) |
| { |
| ConnectionPool[] connectionPools; |
| synchronized (this) |
| { |
| connectionPools = new ConnectionPool[poolMap.size()]; |
| int i = 0; |
| Iterator<String> iter = poolMap.keySet().iterator(); |
| while (iter.hasNext()) |
| { |
| String poolKey = iter.next(); |
| connectionPools[i++] = poolMap.get(poolKey); |
| } |
| } |
| for (int i = 0 ; i < connectionPools.length ; i++) |
| { |
| connectionPools[i].cleanupExpiredConnections(cleanupTime); |
| } |
| } |
| |
| protected class ConnectionCloserThread extends Thread |
| { |
| |
| public ConnectionCloserThread() |
| { |
| super(); |
| setName("Connection pool reaper"); |
| setDaemon(true); |
| } |
| |
| public void run() |
| { |
| while (true) |
| { |
| if (shuttingDown.get()) |
| break; |
| cleanupExpiredConnections(System.currentTimeMillis()); |
| if (shuttingDown.get()) |
| break; |
| try |
| { |
| Thread.sleep(5000L); |
| } |
| catch (InterruptedException e) |
| { |
| break; |
| } |
| } |
| |
| } |
| |
| } |
| |
| |
| } |
| |
| |