001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/io/DBPool.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005     Department of Geography, University of Bonn
006     and
007     lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035     ----------------------------------------------------------------------------*/
036    
037    package org.deegree.io;
038    
039    import java.sql.Connection;
040    import java.sql.Driver;
041    import java.sql.DriverManager;
042    import java.sql.SQLException;
043    import java.util.Properties;
044    
045    import org.deegree.framework.util.ObjectPool;
046    
047    /**
048     * class to manage a pool of database connections.
049     * 
050     * 
051     * @version $Revision: 21455 $
052     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
053     * @author last edited by: $Author: aschmitz $
054     * 
055     * @version 1.0. $Revision: 21455 $, $Date: 2009-12-15 15:14:47 +0100 (Di, 15. Dez 2009) $
056     * 
057     * @since 2.0
058     */
059    public class DBPool extends ObjectPool {
060    
061        private String driver = null;
062    
063        private String database = null;
064    
065        private Properties properties = new Properties();
066    
067        /**
068         * initialize pool for defined connection parameters
069         * 
070         * @param driver
071         * @param database
072         * @param user
073         * @param password
074         */
075        public DBPool( final String driver, final String database, final String user, final String password ) {
076    
077            this.driver = driver;
078            this.database = database;
079            properties.put( "user", user );
080            properties.put( "password", password );
081        }
082    
083        /**
084         * initialize pool for defined connection parameters
085         * 
086         * @param driver
087         * @param database
088         * @param properties
089         */
090        public DBPool( final String driver, final String database, final Properties properties ) {
091    
092            this.driver = driver;
093            this.database = database;
094            this.properties = properties;
095        }
096    
097        /**
098         * get an object from the object pool
099         * 
100         * @return the object
101         * 
102         * @throws DBPoolException
103         */
104        public synchronized Object acquireObject()
105                                throws DBPoolException {
106            try {
107                // if the maximum amount of instances are in use
108                // wait until an instance has been released back
109                // to the pool or 20 seconds has passed
110                long timediff = 0;
111                while ( in_use.size() == getMaxInstances() && timediff < 20000 ) {
112                    Thread.sleep( 100 );
113                    timediff += 100;
114                }
115                // if no instance has been released within 20 seconds
116                // or can newly be instantiated return null
117                if ( timediff >= 20000 )
118                    return null;
119    
120                // if a none used is available from the pool
121                if ( available.size() > 0 ) {
122    
123                    // get/remove ojebct from the pool
124                    Object o = available.remove( available.size() - 1 );
125                    if ( ( (Connection) o ).isClosed() ) {
126                        startLifeTime.remove( o );
127                        o = acquireObject();
128                    }
129    
130                    // add it to 'in use' container
131                    if ( !in_use.contains( o ) )
132                        in_use.add( o );
133    
134                    // reset its start life time
135                    startLifeTime.put( o, new Long( System.currentTimeMillis() ) );
136                    // set the start of its usage
137                    startUsageTime.put( o, new Long( System.currentTimeMillis() ) );
138    
139                    // return the object
140                    return o;
141    
142                }
143                // else instatiate a new object
144                // create a new class instance
145                DriverManager.registerDriver( (Driver) Class.forName( driver ).newInstance() );
146    
147                Properties prop = (Properties) properties.clone();
148                Object connection = DriverManager.getConnection( database, prop );
149    
150                existingInstances++;
151    
152                // add it to 'in use' container
153                in_use.add( connection );
154                // set the start of its life time
155                startLifeTime.put( connection, new Long( System.currentTimeMillis() ) );
156                // set the start of its usage
157                startUsageTime.put( connection, new Long( System.currentTimeMillis() ) );
158                // return the object
159                return connection;
160            } catch ( Exception e ) {
161                e.printStackTrace();
162                throw new DBPoolException( "Error while acquiring connection: " + e.getMessage(), e );
163            }
164        }
165    
166        /**
167         * will be called when the object is removed from the pool
168         * 
169         * @param o
170         */
171        @Override
172        public void onObjectKill( Object o ) {
173            try {
174                ( (Connection) o ).close();
175            } catch ( SQLException e ) {
176                // which is a bad thing
177            }
178        }
179    
180    }