001/*
002 * (C) Copyright 2012-2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 */
017package org.nuxeo.runtime.datasource;
018
019import java.sql.Connection;
020import java.sql.SQLException;
021import java.util.HashMap;
022import java.util.Hashtable;
023import java.util.Map;
024import java.util.concurrent.locks.ReentrantReadWriteLock;
025
026import javax.naming.Context;
027import javax.naming.Name;
028import javax.naming.Reference;
029import javax.sql.DataSource;
030
031public class PooledDataSourceRegistry extends ReentrantReadWriteLock {
032
033    private static final long serialVersionUID = 1L;
034
035    public interface PooledDataSource extends DataSource {
036        void dispose();
037
038        Connection getConnection(boolean noSharing) throws SQLException;
039    }
040
041    protected final Map<String, PooledDataSource> pools = new HashMap<>();
042
043    protected final PooledDataSourceFactory poolFactory = new org.nuxeo.runtime.datasource.PooledDataSourceFactory();
044
045    public <T> T getPool(String name, Class<T> type) {
046        return type.cast(pools.get(name));
047    }
048
049    public PooledDataSource getOrCreatePool(Object obj, Name objectName, Context nameCtx, Hashtable<?, ?> env) {
050        final Reference ref = (Reference) obj;
051        String dsName = (String) ref.get("name").getContent();
052        PooledDataSource ds = pools.get(dsName);
053        if (ds != null) {
054            return ds;
055        }
056        return createPool(dsName, ref, objectName, nameCtx, env);
057    }
058
059    protected PooledDataSource createPool(String dsName, Reference ref, Name objectName, Context nameCtx, Hashtable<?, ?> env) {
060        PooledDataSource ds;
061        try {
062            readLock().lock();
063            ds = pools.get(dsName);
064            if (ds != null) {
065                return ds;
066            }
067            ds = (PooledDataSource) poolFactory.getObjectInstance(ref, objectName, nameCtx, env);
068            pools.put(dsName, ds);
069        } finally {
070            readLock().unlock();
071        }
072        return ds;
073    }
074
075    protected void clearPool(String name) {
076        PooledDataSource ds = pools.remove(name);
077        if (ds != null) {
078            ds.dispose();
079        }
080    }
081
082    public void createAlias(String name, PooledDataSource pool) {
083        pools.put(name, pool);
084    }
085
086}