001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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: 21456 $
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: 21456 $, $Date: 2009-12-15 15:17:33 +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 }