1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool.impl;
19
20 import org.apache.commons.pool.BaseKeyedObjectPool;
21 import org.apache.commons.pool.KeyedObjectPool;
22 import org.apache.commons.pool.KeyedPoolableObjectFactory;
23
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.NoSuchElementException;
27 import java.util.Stack;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class StackKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
49
50
51
52
53
54
55
56
57
58 public StackKeyedObjectPool() {
59 this((KeyedPoolableObjectFactory)null,DEFAULT_MAX_SLEEPING,DEFAULT_INIT_SLEEPING_CAPACITY);
60 }
61
62
63
64
65
66
67
68
69
70
71
72 public StackKeyedObjectPool(int max) {
73 this((KeyedPoolableObjectFactory)null,max,DEFAULT_INIT_SLEEPING_CAPACITY);
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public StackKeyedObjectPool(int max, int init) {
89 this((KeyedPoolableObjectFactory)null,max,init);
90 }
91
92
93
94
95
96
97
98 public StackKeyedObjectPool(KeyedPoolableObjectFactory factory) {
99 this(factory,DEFAULT_MAX_SLEEPING);
100 }
101
102
103
104
105
106
107
108
109
110 public StackKeyedObjectPool(KeyedPoolableObjectFactory factory, int max) {
111 this(factory,max,DEFAULT_INIT_SLEEPING_CAPACITY);
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public StackKeyedObjectPool(KeyedPoolableObjectFactory factory, int max, int init) {
127 _factory = factory;
128 _maxSleeping = (max < 0 ? DEFAULT_MAX_SLEEPING : max);
129 _initSleepingCapacity = (init < 1 ? DEFAULT_INIT_SLEEPING_CAPACITY : init);
130 _pools = new HashMap();
131 _activeCount = new HashMap();
132 }
133
134 public synchronized Object borrowObject(Object key) throws Exception {
135 assertOpen();
136 Stack stack = (Stack)(_pools.get(key));
137 if(null == stack) {
138 stack = new Stack();
139 stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
140 _pools.put(key,stack);
141 }
142 Object obj = null;
143 do {
144 boolean newlyMade = false;
145 if (!stack.empty()) {
146 obj = stack.pop();
147 _totIdle--;
148 } else {
149 if(null == _factory) {
150 throw new NoSuchElementException("pools without a factory cannot create new objects as needed.");
151 } else {
152 obj = _factory.makeObject(key);
153 newlyMade = true;
154 }
155 }
156 if (null != _factory && null != obj) {
157 try {
158 _factory.activateObject(key, obj);
159 if (!_factory.validateObject(key, obj)) {
160 throw new Exception("ValidateObject failed");
161 }
162 } catch (Throwable t) {
163 try {
164 _factory.destroyObject(key,obj);
165 } catch (Throwable t2) {
166
167 } finally {
168 obj = null;
169 }
170 if (newlyMade) {
171 throw new NoSuchElementException(
172 "Could not create a validated object, cause: " +
173 t.getMessage());
174 }
175 }
176 }
177 } while (obj == null);
178 incrementActiveCount(key);
179 return obj;
180 }
181
182 public synchronized void returnObject(Object key, Object obj) throws Exception {
183 decrementActiveCount(key);
184 if (null != _factory) {
185 if (_factory.validateObject(key, obj)) {
186 try {
187 _factory.passivateObject(key, obj);
188 } catch (Exception ex) {
189 _factory.destroyObject(key, obj);
190 return;
191 }
192 } else {
193 return;
194 }
195 }
196
197 if (isClosed()) {
198 if (null != _factory) {
199 try {
200 _factory.destroyObject(key, obj);
201 } catch (Exception e) {
202
203 }
204 }
205 return;
206 }
207
208 Stack stack = (Stack)_pools.get(key);
209 if(null == stack) {
210 stack = new Stack();
211 stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
212 _pools.put(key,stack);
213 }
214 final int stackSize = stack.size();
215 if (stackSize >= _maxSleeping) {
216 final Object staleObj;
217 if (stackSize > 0) {
218 staleObj = stack.remove(0);
219 _totIdle--;
220 } else {
221 staleObj = obj;
222 }
223 if(null != _factory) {
224 try {
225 _factory.destroyObject(key, staleObj);
226 } catch (Exception e) {
227
228 }
229 }
230 }
231 stack.push(obj);
232 _totIdle++;
233 }
234
235 public synchronized void invalidateObject(Object key, Object obj) throws Exception {
236 decrementActiveCount(key);
237 if(null != _factory) {
238 _factory.destroyObject(key,obj);
239 }
240 notifyAll();
241 }
242
243
244
245
246
247
248
249
250
251
252 public synchronized void addObject(Object key) throws Exception {
253 assertOpen();
254 if (_factory == null) {
255 throw new IllegalStateException("Cannot add objects without a factory.");
256 }
257 Object obj = _factory.makeObject(key);
258 try {
259 if (!_factory.validateObject(key, obj)) {
260 return;
261 }
262 } catch (Exception e) {
263 try {
264 _factory.destroyObject(key, obj);
265 } catch (Exception e2) {
266
267 }
268 return;
269 }
270 _factory.passivateObject(key, obj);
271
272 Stack stack = (Stack)_pools.get(key);
273 if(null == stack) {
274 stack = new Stack();
275 stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
276 _pools.put(key,stack);
277 }
278
279 final int stackSize = stack.size();
280 if (stackSize >= _maxSleeping) {
281 final Object staleObj;
282 if (stackSize > 0) {
283 staleObj = stack.remove(0);
284 _totIdle--;
285 } else {
286 staleObj = obj;
287 }
288 try {
289 _factory.destroyObject(key, staleObj);
290 } catch (Exception e) {
291
292 if (obj == staleObj) {
293 throw e;
294 }
295 }
296 } else {
297 stack.push(obj);
298 _totIdle++;
299 }
300 }
301
302
303
304
305
306
307 public synchronized int getNumIdle() {
308 return _totIdle;
309 }
310
311
312
313
314
315
316 public synchronized int getNumActive() {
317 return _totActive;
318 }
319
320
321
322
323
324
325
326
327 public synchronized int getNumActive(Object key) {
328 return getActiveCount(key);
329 }
330
331
332
333
334
335
336
337 public synchronized int getNumIdle(Object key) {
338 try {
339 return((Stack)(_pools.get(key))).size();
340 } catch(Exception e) {
341 return 0;
342 }
343 }
344
345
346
347
348 public synchronized void clear() {
349 Iterator it = _pools.keySet().iterator();
350 while(it.hasNext()) {
351 Object key = it.next();
352 Stack stack = (Stack)(_pools.get(key));
353 destroyStack(key,stack);
354 }
355 _totIdle = 0;
356 _pools.clear();
357 _activeCount.clear();
358 }
359
360
361
362
363
364
365 public synchronized void clear(Object key) {
366 Stack stack = (Stack)(_pools.remove(key));
367 destroyStack(key,stack);
368 }
369
370 private synchronized void destroyStack(Object key, Stack stack) {
371 if(null == stack) {
372 return;
373 } else {
374 if(null != _factory) {
375 Iterator it = stack.iterator();
376 while(it.hasNext()) {
377 try {
378 _factory.destroyObject(key,it.next());
379 } catch(Exception e) {
380
381 }
382 }
383 }
384 _totIdle -= stack.size();
385 _activeCount.remove(key);
386 stack.clear();
387 }
388 }
389
390 public synchronized String toString() {
391 StringBuffer buf = new StringBuffer();
392 buf.append(getClass().getName());
393 buf.append(" contains ").append(_pools.size()).append(" distinct pools: ");
394 Iterator it = _pools.keySet().iterator();
395 while(it.hasNext()) {
396 Object key = it.next();
397 buf.append(" |").append(key).append("|=");
398 Stack s = (Stack)(_pools.get(key));
399 buf.append(s.size());
400 }
401 return buf.toString();
402 }
403
404
405
406
407
408
409
410
411
412
413 public void close() throws Exception {
414 super.close();
415 clear();
416 }
417
418
419
420
421
422
423
424
425
426
427 public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
428 if(0 < getNumActive()) {
429 throw new IllegalStateException("Objects are already active");
430 } else {
431 clear();
432 _factory = factory;
433 }
434 }
435
436 private int getActiveCount(Object key) {
437 try {
438 return ((Integer)_activeCount.get(key)).intValue();
439 } catch(NoSuchElementException e) {
440 return 0;
441 } catch(NullPointerException e) {
442 return 0;
443 }
444 }
445
446 private void incrementActiveCount(Object key) {
447 _totActive++;
448 Integer old = (Integer)(_activeCount.get(key));
449 if(null == old) {
450 _activeCount.put(key,new Integer(1));
451 } else {
452 _activeCount.put(key,new Integer(old.intValue() + 1));
453 }
454 }
455
456 private void decrementActiveCount(Object key) {
457 _totActive--;
458 Integer active = (Integer)(_activeCount.get(key));
459 if(null == active) {
460
461 } else if(active.intValue() <= 1) {
462 _activeCount.remove(key);
463 } else {
464 _activeCount.put(key, new Integer(active.intValue() - 1));
465 }
466 }
467
468
469 protected static final int DEFAULT_MAX_SLEEPING = 8;
470
471
472
473
474
475
476 protected static final int DEFAULT_INIT_SLEEPING_CAPACITY = 4;
477
478
479 protected HashMap _pools = null;
480
481
482 protected KeyedPoolableObjectFactory _factory = null;
483
484
485 protected int _maxSleeping = DEFAULT_MAX_SLEEPING;
486
487
488 protected int _initSleepingCapacity = DEFAULT_INIT_SLEEPING_CAPACITY;
489
490
491 protected int _totActive = 0;
492
493
494 protected int _totIdle = 0;
495
496
497 protected HashMap _activeCount = null;
498
499 }