001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2012  Paul Ferraro
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package net.sf.hajdbc.pool.generic;
019
020import java.util.NoSuchElementException;
021
022import net.sf.hajdbc.logging.Level;
023import net.sf.hajdbc.logging.Logger;
024import net.sf.hajdbc.logging.LoggerFactory;
025import net.sf.hajdbc.pool.Pool;
026import net.sf.hajdbc.pool.PoolFactory;
027import net.sf.hajdbc.pool.PoolProvider;
028
029import org.apache.commons.pool.ObjectPool;
030import org.apache.commons.pool.PoolableObjectFactory;
031import org.apache.commons.pool.impl.GenericObjectPool;
032
033/**
034 * Adapter for a <a href="http://commons.apache.org/pool">commons-pool</a> GenericObjectPool.
035 * 
036 * @author Paul Ferraro
037 */
038public class GenericObjectPoolFactory implements PoolFactory
039{
040        static final Logger logger = LoggerFactory.getLogger(GenericObjectPoolFactory.class);
041        
042        private final GenericObjectPool.Config config;
043        
044        public GenericObjectPoolFactory(GenericObjectPoolConfiguration config)
045        {
046                this.config = config.toConfig();
047        }
048        
049        @Override
050        public <T, E extends Exception> Pool<T, E> createPool(final PoolProvider<T, E> provider)
051        {
052                PoolableObjectFactory<T> factory = new PoolableObjectFactory<T>()
053                {
054                        @Override
055                        public void destroyObject(T object)
056                        {
057                                provider.close(object);
058                        }
059
060                        @Override
061                        public T makeObject() throws Exception
062                        {
063                                return provider.create();
064                        }
065
066                        @Override
067                        public boolean validateObject(T object)
068                        {
069                                return provider.isValid(object);
070                        }
071                        
072                        @Override
073                        public void activateObject(T object)
074                        {
075                        }
076
077                        @Override
078                        public void passivateObject(T object)
079                        {
080                        }
081                };
082
083                final ObjectPool<T> pool = new GenericObjectPool<T>(factory, this.config);
084                
085                return new Pool<T, E>()
086                {
087                        @Override
088                        public void close()
089                        {
090                                try
091                                {
092                                        pool.close();
093                                }
094                                catch (Exception e)
095                                {
096                                        logger.log(Level.WARN, e, e.getMessage());
097                                }
098                        }
099
100                        @Override
101                        public void release(T item)
102                        {
103                                try
104                                {
105                                        pool.returnObject(item);
106                                }
107                                catch (Exception e)
108                                {
109                                        logger.log(Level.WARN, e, e.getMessage());
110                                }
111                        }
112
113                        @Override
114                        public T take() throws E
115                        {
116                                try
117                                {
118                                        return pool.borrowObject();
119                                }
120                                catch (NoSuchElementException e)
121                                {
122                                        return provider.create();
123                                }
124                                catch (IllegalStateException e)
125                                {
126                                        throw e;
127                                }
128                                catch (Exception e)
129                                {
130                                        throw provider.getExceptionClass().cast(e);
131                                }
132                        }
133                };
134        }
135}