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