1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.dbcp.datasources;
19
20 import java.io.IOException;
21 import java.io.ObjectInputStream;
22 import java.sql.Connection;
23 import java.sql.SQLException;
24
25 import javax.naming.NamingException;
26 import javax.naming.Reference;
27 import javax.naming.StringRefAddr;
28 import javax.sql.ConnectionPoolDataSource;
29
30 import org.apache.commons.pool.KeyedObjectPool;
31 import org.apache.commons.pool.impl.GenericKeyedObjectPool;
32 import org.apache.commons.pool.impl.GenericObjectPool;
33 import org.apache.commons.dbcp.SQLNestedException;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class SharedPoolDataSource
53 extends InstanceKeyDataSource {
54
55 private static final long serialVersionUID = -8132305535403690372L;
56
57 private int maxActive = GenericObjectPool.DEFAULT_MAX_ACTIVE;
58 private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
59 private int maxWait = (int)Math.min(Integer.MAX_VALUE,
60 GenericObjectPool.DEFAULT_MAX_WAIT);
61 private transient KeyedObjectPool pool = null;
62 private transient KeyedCPDSConnectionFactory factory = null;
63
64
65
66
67 public SharedPoolDataSource() {
68 }
69
70
71
72
73 public void close() throws Exception {
74 if (pool != null) {
75 pool.close();
76 }
77 InstanceKeyObjectFactory.removeInstance(instanceKey);
78 }
79
80
81
82
83
84
85
86
87 public int getMaxActive() {
88 return (this.maxActive);
89 }
90
91
92
93
94
95
96 public void setMaxActive(int maxActive) {
97 assertInitializationAllowed();
98 this.maxActive = maxActive;
99 }
100
101
102
103
104
105 public int getMaxIdle() {
106 return (this.maxIdle);
107 }
108
109
110
111
112
113
114 public void setMaxIdle(int maxIdle) {
115 assertInitializationAllowed();
116 this.maxIdle = maxIdle;
117 }
118
119
120
121
122
123
124
125
126 public int getMaxWait() {
127 return (this.maxWait);
128 }
129
130
131
132
133
134
135
136
137 public void setMaxWait(int maxWait) {
138 assertInitializationAllowed();
139 this.maxWait = maxWait;
140 }
141
142
143
144
145
146
147
148 public int getNumActive() {
149 return (pool == null) ? 0 : pool.getNumActive();
150 }
151
152
153
154
155 public int getNumIdle() {
156 return (pool == null) ? 0 : pool.getNumIdle();
157 }
158
159
160
161
162 protected PooledConnectionAndInfo
163 getPooledConnectionAndInfo(String username, String password)
164 throws SQLException {
165
166 synchronized(this) {
167 if (pool == null) {
168 try {
169 registerPool(username, password);
170 } catch (NamingException e) {
171 throw new SQLNestedException("RegisterPool failed", e);
172 }
173 }
174 }
175
176 PooledConnectionAndInfo info = null;
177
178 UserPassKey key = new UserPassKey(username, password);
179
180 try {
181 info = (PooledConnectionAndInfo) pool.borrowObject(key);
182 }
183 catch (Exception e) {
184 throw new SQLNestedException(
185 "Could not retrieve connection info from pool", e);
186 }
187 return info;
188 }
189
190 protected PooledConnectionManager getConnectionManager(UserPassKey upkey) {
191 return factory;
192 }
193
194
195
196
197
198
199 public Reference getReference() throws NamingException {
200 Reference ref = new Reference(getClass().getName(),
201 SharedPoolDataSourceFactory.class.getName(), null);
202 ref.add(new StringRefAddr("instanceKey", instanceKey));
203 return ref;
204 }
205
206 private void registerPool(
207 String username, String password)
208 throws javax.naming.NamingException, SQLException {
209
210 ConnectionPoolDataSource cpds = testCPDS(username, password);
211
212
213 GenericKeyedObjectPool tmpPool = new GenericKeyedObjectPool(null);
214 tmpPool.setMaxActive(getMaxActive());
215 tmpPool.setMaxIdle(getMaxIdle());
216 tmpPool.setMaxWait(getMaxWait());
217 tmpPool.setWhenExhaustedAction(whenExhaustedAction(maxActive, maxWait));
218 tmpPool.setTestOnBorrow(getTestOnBorrow());
219 tmpPool.setTestOnReturn(getTestOnReturn());
220 tmpPool.setTimeBetweenEvictionRunsMillis(
221 getTimeBetweenEvictionRunsMillis());
222 tmpPool.setNumTestsPerEvictionRun(getNumTestsPerEvictionRun());
223 tmpPool.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
224 tmpPool.setTestWhileIdle(getTestWhileIdle());
225 pool = tmpPool;
226
227
228
229 factory = new KeyedCPDSConnectionFactory(cpds, pool, getValidationQuery(),
230 isRollbackAfterValidation());
231 }
232
233 protected void setupDefaults(Connection con, String username) throws SQLException {
234 boolean defaultAutoCommit = isDefaultAutoCommit();
235 if (con.getAutoCommit() != defaultAutoCommit) {
236 con.setAutoCommit(defaultAutoCommit);
237 }
238
239 int defaultTransactionIsolation = getDefaultTransactionIsolation();
240 if (defaultTransactionIsolation != UNKNOWN_TRANSACTIONISOLATION) {
241 con.setTransactionIsolation(defaultTransactionIsolation);
242 }
243
244 boolean defaultReadOnly = isDefaultReadOnly();
245 if (con.isReadOnly() != defaultReadOnly) {
246 con.setReadOnly(defaultReadOnly);
247 }
248 }
249
250
251
252
253
254
255
256
257 private void readObject(ObjectInputStream in)
258 throws IOException, ClassNotFoundException {
259 try
260 {
261 in.defaultReadObject();
262 SharedPoolDataSource oldDS = (SharedPoolDataSource)
263 new SharedPoolDataSourceFactory()
264 .getObjectInstance(getReference(), null, null, null);
265 this.pool = oldDS.pool;
266 }
267 catch (NamingException e)
268 {
269 throw new IOException("NamingException: " + e);
270 }
271 }
272 }
273