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 import org.apache.commons.pool.PoolUtils;
24
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.NoSuchElementException;
29 import java.util.Stack;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class StackKeyedObjectPool extends BaseKeyedObjectPool implements KeyedObjectPool {
51
52
53
54
55
56
57
58
59
60 public StackKeyedObjectPool() {
61 this((KeyedPoolableObjectFactory)null,DEFAULT_MAX_SLEEPING,DEFAULT_INIT_SLEEPING_CAPACITY);
62 }
63
64
65
66
67
68
69
70
71
72
73
74 public StackKeyedObjectPool(int max) {
75 this((KeyedPoolableObjectFactory)null,max,DEFAULT_INIT_SLEEPING_CAPACITY);
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public StackKeyedObjectPool(int max, int init) {
91 this((KeyedPoolableObjectFactory)null,max,init);
92 }
93
94
95
96
97
98
99
100 public StackKeyedObjectPool(KeyedPoolableObjectFactory factory) {
101 this(factory,DEFAULT_MAX_SLEEPING);
102 }
103
104
105
106
107
108
109
110
111
112 public StackKeyedObjectPool(KeyedPoolableObjectFactory factory, int max) {
113 this(factory,max,DEFAULT_INIT_SLEEPING_CAPACITY);
114 }
115
116
117
118
119
120
121
122
123
124
125
126
127
128 public StackKeyedObjectPool(KeyedPoolableObjectFactory factory, int max, int init) {
129 _factory = factory;
130 _maxSleeping = (max < 0 ? DEFAULT_MAX_SLEEPING : max);
131 _initSleepingCapacity = (init < 1 ? DEFAULT_INIT_SLEEPING_CAPACITY : init);
132 _pools = new HashMap();
133 _activeCount = new HashMap();
134 }
135
136
137
138
139
140
141
142
143 public synchronized Object borrowObject(Object key) throws Exception {
144 assertOpen();
145 Stack stack = (Stack)(_pools.get(key));
146 if(null == stack) {
147 stack = new Stack();
148 stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
149 _pools.put(key,stack);
150 }
151 Object obj = null;
152 do {
153 boolean newlyMade = false;
154 if (!stack.empty()) {
155 obj = stack.pop();
156 _totIdle--;
157 } else {
158 if(null == _factory) {
159 throw new NoSuchElementException("pools without a factory cannot create new objects as needed.");
160 } else {
161 obj = _factory.makeObject(key);
162 newlyMade = true;
163 }
164 }
165 if (null != _factory && null != obj) {
166 try {
167 _factory.activateObject(key, obj);
168 if (!_factory.validateObject(key, obj)) {
169 throw new Exception("ValidateObject failed");
170 }
171 } catch (Throwable t) {
172 PoolUtils.checkRethrow(t);
173 try {
174 _factory.destroyObject(key,obj);
175 } catch (Throwable t2) {
176 PoolUtils.checkRethrow(t2);
177
178 } finally {
179 obj = null;
180 }
181 if (newlyMade) {
182 throw new NoSuchElementException(
183 "Could not create a validated object, cause: " +
184 t.getMessage());
185 }
186 }
187 }
188 } while (obj == null);
189 incrementActiveCount(key);
190 return obj;
191 }
192
193
194
195
196
197
198
199
200
201
202 public synchronized void returnObject(Object key, Object obj) throws Exception {
203 decrementActiveCount(key);
204 if (null != _factory) {
205 if (_factory.validateObject(key, obj)) {
206 try {
207 _factory.passivateObject(key, obj);
208 } catch (Exception ex) {
209 _factory.destroyObject(key, obj);
210 return;
211 }
212 } else {
213 return;
214 }
215 }
216
217 if (isClosed()) {
218 if (null != _factory) {
219 try {
220 _factory.destroyObject(key, obj);
221 } catch (Exception e) {
222
223 }
224 }
225 return;
226 }
227
228 Stack stack = (Stack)_pools.get(key);
229 if(null == stack) {
230 stack = new Stack();
231 stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
232 _pools.put(key,stack);
233 }
234 final int stackSize = stack.size();
235 if (stackSize >= _maxSleeping) {
236 final Object staleObj;
237 if (stackSize > 0) {
238 staleObj = stack.remove(0);
239 _totIdle--;
240 } else {
241 staleObj = obj;
242 }
243 if(null != _factory) {
244 try {
245 _factory.destroyObject(key, staleObj);
246 } catch (Exception e) {
247
248 }
249 }
250 }
251 stack.push(obj);
252 _totIdle++;
253 }
254
255
256
257
258 public synchronized void invalidateObject(Object key, Object obj) throws Exception {
259 decrementActiveCount(key);
260 if(null != _factory) {
261 _factory.destroyObject(key,obj);
262 }
263 notifyAll();
264 }
265
266
267
268
269
270
271
272
273
274
275 public synchronized void addObject(Object key) throws Exception {
276 assertOpen();
277 if (_factory == null) {
278 throw new IllegalStateException("Cannot add objects without a factory.");
279 }
280 Object obj = _factory.makeObject(key);
281 try {
282 if (!_factory.validateObject(key, obj)) {
283 return;
284 }
285 } catch (Exception e) {
286 try {
287 _factory.destroyObject(key, obj);
288 } catch (Exception e2) {
289
290 }
291 return;
292 }
293 _factory.passivateObject(key, obj);
294
295 Stack stack = (Stack)_pools.get(key);
296 if(null == stack) {
297 stack = new Stack();
298 stack.ensureCapacity( _initSleepingCapacity > _maxSleeping ? _maxSleeping : _initSleepingCapacity);
299 _pools.put(key,stack);
300 }
301
302 final int stackSize = stack.size();
303 if (stackSize >= _maxSleeping) {
304 final Object staleObj;
305 if (stackSize > 0) {
306 staleObj = stack.remove(0);
307 _totIdle--;
308 } else {
309 staleObj = obj;
310 }
311 try {
312 _factory.destroyObject(key, staleObj);
313 } catch (Exception e) {
314
315 if (obj == staleObj) {
316 throw e;
317 }
318 }
319 } else {
320 stack.push(obj);
321 _totIdle++;
322 }
323 }
324
325
326
327
328
329
330 public synchronized int getNumIdle() {
331 return _totIdle;
332 }
333
334
335
336
337
338
339 public synchronized int getNumActive() {
340 return _totActive;
341 }
342
343
344
345
346
347
348
349
350 public synchronized int getNumActive(Object key) {
351 return getActiveCount(key);
352 }
353
354
355
356
357
358
359
360 public synchronized int getNumIdle(Object key) {
361 try {
362 return((Stack)(_pools.get(key))).size();
363 } catch(Exception e) {
364 return 0;
365 }
366 }
367
368
369
370
371 public synchronized void clear() {
372 Iterator it = _pools.keySet().iterator();
373 while(it.hasNext()) {
374 Object key = it.next();
375 Stack stack = (Stack)(_pools.get(key));
376 destroyStack(key,stack);
377 }
378 _totIdle = 0;
379 _pools.clear();
380 _activeCount.clear();
381 }
382
383
384
385
386
387
388 public synchronized void clear(Object key) {
389 Stack stack = (Stack)(_pools.remove(key));
390 destroyStack(key,stack);
391 }
392
393
394
395
396
397
398
399 private synchronized void destroyStack(Object key, Stack stack) {
400 if(null == stack) {
401 return;
402 } else {
403 if(null != _factory) {
404 Iterator it = stack.iterator();
405 while(it.hasNext()) {
406 try {
407 _factory.destroyObject(key,it.next());
408 } catch(Exception e) {
409
410 }
411 }
412 }
413 _totIdle -= stack.size();
414 _activeCount.remove(key);
415 stack.clear();
416 }
417 }
418
419
420
421
422
423
424
425 public synchronized String toString() {
426 StringBuffer buf = new StringBuffer();
427 buf.append(getClass().getName());
428 buf.append(" contains ").append(_pools.size()).append(" distinct pools: ");
429 Iterator it = _pools.keySet().iterator();
430 while(it.hasNext()) {
431 Object key = it.next();
432 buf.append(" |").append(key).append("|=");
433 Stack s = (Stack)(_pools.get(key));
434 buf.append(s.size());
435 }
436 return buf.toString();
437 }
438
439
440
441
442
443
444
445
446
447
448 public void close() throws Exception {
449 super.close();
450 clear();
451 }
452
453
454
455
456
457
458
459
460
461
462
463 public synchronized void setFactory(KeyedPoolableObjectFactory factory) throws IllegalStateException {
464 if(0 < getNumActive()) {
465 throw new IllegalStateException("Objects are already active");
466 } else {
467 clear();
468 _factory = factory;
469 }
470 }
471
472
473
474
475
476 public synchronized KeyedPoolableObjectFactory getFactory() {
477 return _factory;
478 }
479
480
481
482
483
484
485
486 private int getActiveCount(Object key) {
487 try {
488 return ((Integer)_activeCount.get(key)).intValue();
489 } catch(NoSuchElementException e) {
490 return 0;
491 } catch(NullPointerException e) {
492 return 0;
493 }
494 }
495
496
497
498
499
500
501
502 private void incrementActiveCount(Object key) {
503 _totActive++;
504 Integer old = (Integer)(_activeCount.get(key));
505 if(null == old) {
506 _activeCount.put(key,new Integer(1));
507 } else {
508 _activeCount.put(key,new Integer(old.intValue() + 1));
509 }
510 }
511
512
513
514
515
516
517
518 private void decrementActiveCount(Object key) {
519 _totActive--;
520 Integer active = (Integer)(_activeCount.get(key));
521 if(null == active) {
522
523 } else if(active.intValue() <= 1) {
524 _activeCount.remove(key);
525 } else {
526 _activeCount.put(key, new Integer(active.intValue() - 1));
527 }
528 }
529
530
531
532
533
534
535 public Map getPools() {
536 return _pools;
537 }
538
539
540
541
542
543 public int getMaxSleeping() {
544 return _maxSleeping;
545 }
546
547
548
549
550
551 public int getInitSleepingCapacity() {
552 return _initSleepingCapacity;
553 }
554
555
556
557
558 public int getTotActive() {
559 return _totActive;
560 }
561
562
563
564
565 public int getTotIdle() {
566 return _totIdle;
567 }
568
569
570
571
572
573 public Map getActiveCount() {
574 return _activeCount;
575 }
576
577
578
579 protected static final int DEFAULT_MAX_SLEEPING = 8;
580
581
582
583
584
585
586 protected static final int DEFAULT_INIT_SLEEPING_CAPACITY = 4;
587
588
589
590
591
592 protected HashMap _pools = null;
593
594
595
596
597
598 protected KeyedPoolableObjectFactory _factory = null;
599
600
601
602
603
604 protected int _maxSleeping = DEFAULT_MAX_SLEEPING;
605
606
607
608
609
610 protected int _initSleepingCapacity = DEFAULT_INIT_SLEEPING_CAPACITY;
611
612
613
614
615
616 protected int _totActive = 0;
617
618
619
620
621
622 protected int _totIdle = 0;
623
624
625
626
627
628 protected HashMap _activeCount = null;
629
630 }