001/*
002 * (C) Copyright 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 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019package org.nuxeo.runtime.datasource;
020
021import java.sql.Connection;
022import java.sql.SQLException;
023import java.util.HashMap;
024import java.util.Hashtable;
025import java.util.Map;
026import java.util.concurrent.locks.ReentrantReadWriteLock;
027
028import javax.naming.Context;
029import javax.naming.Name;
030import javax.naming.Reference;
031import javax.naming.spi.ObjectFactory;
032import javax.sql.DataSource;
033
034import org.nuxeo.runtime.datasource.geronimo.PooledDataSourceFactory;
035
036public class PooledDataSourceRegistry extends ReentrantReadWriteLock {
037
038    private static final long serialVersionUID = 1L;
039
040    public interface Factory extends ObjectFactory {
041
042    }
043
044    public interface PooledDataSource extends DataSource {
045        void dispose();
046
047        Connection getConnection(boolean noSharing) throws SQLException;
048    }
049
050    protected final Map<String, PooledDataSource> pools = new HashMap<>();
051
052    protected final PooledDataSourceFactory poolFactory = new org.nuxeo.runtime.datasource.geronimo.PooledDataSourceFactory();
053
054    public <T> T getPool(String name, Class<T> type) {
055        return type.cast(pools.get(name));
056    }
057
058    public DataSource getOrCreatePool(Object obj, Name objectName, Context nameCtx, Hashtable<?, ?> env) {
059        final Reference ref = (Reference) obj;
060        String dsName = (String) ref.get("name").getContent();
061        DataSource ds = pools.get(dsName);
062        if (ds != null) {
063            return ds;
064        }
065        return createPool(dsName, ref, objectName, nameCtx, env);
066    }
067
068    protected DataSource createPool(String dsName, Reference ref, Name objectName, Context nameCtx, Hashtable<?, ?> env) {
069        PooledDataSource ds;
070        try {
071            readLock().lock();
072            ds = pools.get(dsName);
073            if (ds != null) {
074                return ds;
075            }
076            ds = (PooledDataSource) poolFactory.getObjectInstance(ref, objectName, nameCtx, env);
077            pools.put(dsName, ds);
078        } finally {
079            readLock().unlock();
080        }
081        return ds;
082    }
083
084    protected void clearPool(String name) {
085        PooledDataSource ds = pools.remove(name);
086        if (ds != null) {
087            ds.dispose();
088        }
089    }
090
091    public void createAlias(String name, PooledDataSource pool) {
092        pools.put(name, pool);
093    }
094
095}