KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > dbcp > datasources > SharedPoolDataSource


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.commons.dbcp.datasources;
18
19 import java.io.IOException JavaDoc;
20 import java.io.ObjectInputStream JavaDoc;
21 import java.sql.Connection JavaDoc;
22 import java.sql.SQLException JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import javax.naming.NamingException JavaDoc;
26 import javax.sql.ConnectionPoolDataSource JavaDoc;
27
28 import org.apache.commons.collections.LRUMap;
29 import org.apache.commons.pool.KeyedObjectPool;
30 import org.apache.commons.pool.impl.GenericKeyedObjectPool;
31 import org.apache.commons.pool.impl.GenericObjectPool;
32 import org.apache.commons.dbcp.SQLNestedException;
33
34 /**
35  * A pooling <code>DataSource</code> appropriate for deployment within
36  * J2EE environment. There are many configuration options, most of which are
37  * defined in the parent class. All users (based on username) share a single
38  * maximum number of Connections in this datasource.
39  *
40  * @author John D. McNally
41  * @version $Revision: 1.9 $ $Date: 2004/02/28 12:18:17 $
42  */

43 public class SharedPoolDataSource
44     extends InstanceKeyDataSource {
45
46     private static final Map JavaDoc userKeys = new LRUMap(10);
47
48     private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;
49     private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
50     private int maxWait = (int)Math.min((long)Integer.MAX_VALUE,
51         GenericObjectPool.DEFAULT_MAX_WAIT);
52     private KeyedObjectPool pool = null;
53
54     /**
55      * Default no-arg constructor for Serialization
56      */

57     public SharedPoolDataSource() {
58     }
59
60     /**
61      * Close pool being maintained by this datasource.
62      */

63     public void close() throws Exception JavaDoc {
64         pool.close();
65         InstanceKeyObjectFactory.removeInstance(instanceKey);
66     }
67
68     // -------------------------------------------------------------------
69
// Properties
70

71     /**
72      * The maximum number of active connections that can be allocated from
73      * this pool at the same time, or zero for no limit.
74      * The default is 0.
75      */

76     public int getMaxActive() {
77         return (this.maxActive);
78     }
79
80     /**
81      * The maximum number of active connections that can be allocated from
82      * this pool at the same time, or zero for no limit.
83      * The default is 0.
84      */

85     public void setMaxActive(int maxActive) {
86         assertInitializationAllowed();
87         this.maxActive = maxActive;
88     }
89
90     /**
91      * The maximum number of active connections that can remain idle in the
92      * pool, without extra ones being released, or zero for no limit.
93      * The default is 0.
94      */

95     public int getMaxIdle() {
96         return (this.maxIdle);
97     }
98
99     /**
100      * The maximum number of active connections that can remain idle in the
101      * pool, without extra ones being released, or zero for no limit.
102      * The default is 0.
103      */

104     public void setMaxIdle(int maxIdle) {
105         assertInitializationAllowed();
106         this.maxIdle = maxIdle;
107     }
108
109     /**
110      * The maximum number of milliseconds that the pool will wait (when there
111      * are no available connections) for a connection to be returned before
112      * throwing an exception, or -1 to wait indefinitely. Will fail
113      * immediately if value is 0.
114      * The default is -1.
115      */

116     public int getMaxWait() {
117         return (this.maxWait);
118     }
119
120     /**
121      * The maximum number of milliseconds that the pool will wait (when there
122      * are no available connections) for a connection to be returned before
123      * throwing an exception, or -1 to wait indefinitely. Will fail
124      * immediately if value is 0.
125      * The default is -1.
126      */

127     public void setMaxWait(int maxWait) {
128         assertInitializationAllowed();
129         this.maxWait = maxWait;
130     }
131
132     // ----------------------------------------------------------------------
133
// Instrumentation Methods
134

135     /**
136      * Get the number of active connections in the pool.
137      */

138     public int getNumActive() {
139         return (pool == null) ? 0 : pool.getNumActive();
140     }
141
142     /**
143      * Get the number of idle connections in the pool.
144      */

145     public int getNumIdle() {
146         return (pool == null) ? 0 : pool.getNumIdle();
147     }
148
149     // ----------------------------------------------------------------------
150
// Inherited abstract methods
151

152     protected synchronized PooledConnectionAndInfo
153         getPooledConnectionAndInfo(String JavaDoc username, String JavaDoc password)
154         throws SQLException JavaDoc {
155         if (pool == null) {
156             try {
157                 registerPool(username, password);
158             } catch (NamingException JavaDoc e) {
159                 throw new SQLNestedException("RegisterPool failed", e);
160             }
161         }
162
163         PooledConnectionAndInfo info = null;
164         try {
165             info = (PooledConnectionAndInfo) pool
166                 .borrowObject(getUserPassKey(username, password));
167         }
168         catch (Exception JavaDoc e) {
169             throw new SQLNestedException(
170                 "Could not retrieve connection info from pool", e);
171         }
172         return info;
173     }
174
175     private UserPassKey getUserPassKey(String JavaDoc username, String JavaDoc password) {
176         UserPassKey key = (UserPassKey) userKeys.get(username);
177         if (key == null) {
178             key = new UserPassKey(username, password);
179             userKeys.put(username, key);
180         }
181         return key;
182     }
183
184     private void registerPool(
185         String JavaDoc username, String JavaDoc password)
186         throws javax.naming.NamingException JavaDoc, SQLException JavaDoc {
187
188         ConnectionPoolDataSource JavaDoc cpds = testCPDS(username, password);
189
190         // Create an object pool to contain our PooledConnections
191
GenericKeyedObjectPool tmpPool = new GenericKeyedObjectPool(null);
192         tmpPool.setMaxActive(getMaxActive());
193         tmpPool.setMaxIdle(getMaxIdle());
194         tmpPool.setMaxWait(getMaxWait());
195         tmpPool.setWhenExhaustedAction(whenExhaustedAction(maxActive, maxWait));
196         tmpPool.setTestOnBorrow(getTestOnBorrow());
197         tmpPool.setTestOnReturn(getTestOnReturn());
198         tmpPool.setTimeBetweenEvictionRunsMillis(
199             getTimeBetweenEvictionRunsMillis());
200         tmpPool.setNumTestsPerEvictionRun(getNumTestsPerEvictionRun());
201         tmpPool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
202         tmpPool.setTestWhileIdle(getTestWhileIdle());
203         pool = tmpPool;
204         // Set up the factory we will use (passing the pool associates
205
// the factory with the pool, so we do not have to do so
206
// explicitly)
207
new KeyedCPDSConnectionFactory(cpds, pool, getValidationQuery());
208     }
209
210     protected void setupDefaults(Connection JavaDoc con, String JavaDoc username)
211         throws SQLException JavaDoc {
212         con.setAutoCommit(isDefaultAutoCommit());
213         con.setReadOnly(isDefaultReadOnly());
214         int defaultTransactionIsolation = getDefaultTransactionIsolation();
215         if (defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) {
216             con.setTransactionIsolation(defaultTransactionIsolation);
217         }
218     }
219
220     /**
221      * Supports Serialization interface.
222      *
223      * @param in a <code>java.io.ObjectInputStream</code> value
224      * @exception IOException if an error occurs
225      * @exception ClassNotFoundException if an error occurs
226      */

227     private void readObject(ObjectInputStream JavaDoc in)
228         throws IOException JavaDoc, ClassNotFoundException JavaDoc {
229         try
230         {
231             in.defaultReadObject();
232             SharedPoolDataSource oldDS = (SharedPoolDataSource)
233                 new SharedPoolDataSourceFactory()
234                     .getObjectInstance(getReference(), null, null, null);
235             this.pool = oldDS.pool;
236         }
237         catch (NamingException JavaDoc e)
238         {
239             throw new IOException JavaDoc("NamingException: " + e);
240         }
241     }
242 }
243
244
Popular Tags