1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.pool;
19
20 import java.util.Collection;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.Map;
24 import java.util.NoSuchElementException;
25 import java.util.Timer;
26 import java.util.TimerTask;
27 import java.util.Collections;
28
29
30
31
32
33
34
35
36
37 public final class PoolUtils {
38
39
40
41
42
43 private static Timer MIN_IDLE_TIMER;
44
45
46
47
48
49
50 public PoolUtils() {
51 }
52
53
54
55
56
57
58
59
60
61
62
63 public static void checkRethrow(Throwable t) {
64 if (t instanceof ThreadDeath) {
65 throw (ThreadDeath) t;
66 }
67 if (t instanceof VirtualMachineError) {
68 throw (VirtualMachineError) t;
69 }
70
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84 public static PoolableObjectFactory adapt(final KeyedPoolableObjectFactory keyedFactory) throws IllegalArgumentException {
85 return adapt(keyedFactory, new Object());
86 }
87
88
89
90
91
92
93
94
95
96
97
98
99 public static PoolableObjectFactory adapt(final KeyedPoolableObjectFactory keyedFactory, final Object key) throws IllegalArgumentException {
100 return new PoolableObjectFactoryAdaptor(keyedFactory, key);
101 }
102
103
104
105
106
107
108
109
110
111
112 public static KeyedPoolableObjectFactory adapt(final PoolableObjectFactory factory) throws IllegalArgumentException {
113 return new KeyedPoolableObjectFactoryAdaptor(factory);
114 }
115
116
117
118
119
120
121
122
123
124
125
126 public static ObjectPool adapt(final KeyedObjectPool keyedPool) throws IllegalArgumentException {
127 return adapt(keyedPool, new Object());
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141 public static ObjectPool adapt(final KeyedObjectPool keyedPool, final Object key) throws IllegalArgumentException {
142 return new ObjectPoolAdaptor(keyedPool, key);
143 }
144
145
146
147
148
149
150
151
152
153
154 public static KeyedObjectPool adapt(final ObjectPool pool) throws IllegalArgumentException {
155 return new KeyedObjectPoolAdaptor(pool);
156 }
157
158
159
160
161
162
163
164
165
166
167 public static ObjectPool checkedPool(final ObjectPool pool, final Class type) {
168 if (pool == null) {
169 throw new IllegalArgumentException("pool must not be null.");
170 }
171 if (type == null) {
172 throw new IllegalArgumentException("type must not be null.");
173 }
174 return new CheckedObjectPool(pool, type);
175 }
176
177
178
179
180
181
182
183
184
185
186 public static KeyedObjectPool checkedPool(final KeyedObjectPool keyedPool, final Class type) {
187 if (keyedPool == null) {
188 throw new IllegalArgumentException("keyedPool must not be null.");
189 }
190 if (type == null) {
191 throw new IllegalArgumentException("type must not be null.");
192 }
193 return new CheckedKeyedObjectPool(keyedPool, type);
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 public static TimerTask checkMinIdle(final ObjectPool pool, final int minIdle, final long period) throws IllegalArgumentException {
211 if (pool == null) {
212 throw new IllegalArgumentException("keyedPool must not be null.");
213 }
214 if (minIdle < 0) {
215 throw new IllegalArgumentException("minIdle must be non-negative.");
216 }
217 final TimerTask task = new ObjectPoolMinIdleTimerTask(pool, minIdle);
218 getMinIdleTimer().schedule(task, 0L, period);
219 return task;
220 }
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238 public static TimerTask checkMinIdle(final KeyedObjectPool keyedPool, final Object key, final int minIdle, final long period) throws IllegalArgumentException {
239 if (keyedPool == null) {
240 throw new IllegalArgumentException("keyedPool must not be null.");
241 }
242 if (key == null) {
243 throw new IllegalArgumentException("key must not be null.");
244 }
245 if (minIdle < 0) {
246 throw new IllegalArgumentException("minIdle must be non-negative.");
247 }
248 final TimerTask task = new KeyedObjectPoolMinIdleTimerTask(keyedPool, key, minIdle);
249 getMinIdleTimer().schedule(task, 0L, period);
250 return task;
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269 public static Map checkMinIdle(final KeyedObjectPool keyedPool, final Collection keys, final int minIdle, final long period) throws IllegalArgumentException {
270 if (keys == null) {
271 throw new IllegalArgumentException("keys must not be null.");
272 }
273 final Map tasks = new HashMap(keys.size());
274 final Iterator iter = keys.iterator();
275 while (iter.hasNext()) {
276 final Object key = iter.next();
277 final TimerTask task = checkMinIdle(keyedPool, key, minIdle, period);
278 tasks.put(key, task);
279 }
280 return tasks;
281 }
282
283
284
285
286
287
288
289
290
291
292 public static void prefill(final ObjectPool pool, final int count) throws Exception, IllegalArgumentException {
293 if (pool == null) {
294 throw new IllegalArgumentException("pool must not be null.");
295 }
296 for (int i = 0; i < count; i++) {
297 pool.addObject();
298 }
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312 public static void prefill(final KeyedObjectPool keyedPool, final Object key, final int count) throws Exception, IllegalArgumentException {
313 if (keyedPool == null) {
314 throw new IllegalArgumentException("keyedPool must not be null.");
315 }
316 if (key == null) {
317 throw new IllegalArgumentException("key must not be null.");
318 }
319 for (int i = 0; i < count; i++) {
320 keyedPool.addObject(key);
321 }
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 public static void prefill(final KeyedObjectPool keyedPool, final Collection keys, final int count) throws Exception, IllegalArgumentException {
339 if (keys == null) {
340 throw new IllegalArgumentException("keys must not be null.");
341 }
342 final Iterator iter = keys.iterator();
343 while (iter.hasNext()) {
344 prefill(keyedPool, iter.next(), count);
345 }
346 }
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 public static ObjectPool synchronizedPool(final ObjectPool pool) {
363 if (pool == null) {
364 throw new IllegalArgumentException("pool must not be null.");
365 }
366
367
368
369
370
371
372
373
374
375
376 return new SynchronizedObjectPool(pool);
377 }
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393 public static KeyedObjectPool synchronizedPool(final KeyedObjectPool keyedPool) {
394 if (keyedPool == null) {
395 throw new IllegalArgumentException("keyedPool must not be null.");
396 }
397
398
399
400
401
402
403
404
405 return new SynchronizedKeyedObjectPool(keyedPool);
406 }
407
408
409
410
411
412
413
414
415 public static PoolableObjectFactory synchronizedPoolableFactory(final PoolableObjectFactory factory) {
416 return new SynchronizedPoolableObjectFactory(factory);
417 }
418
419
420
421
422
423
424
425
426 public static KeyedPoolableObjectFactory synchronizedPoolableFactory(final KeyedPoolableObjectFactory keyedFactory) {
427 return new SynchronizedKeyedPoolableObjectFactory(keyedFactory);
428 }
429
430
431
432
433
434
435
436
437
438
439
440
441 public static ObjectPool erodingPool(final ObjectPool pool) {
442 return erodingPool(pool, 1f);
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465 public static ObjectPool erodingPool(final ObjectPool pool, final float factor) {
466 if (pool == null) {
467 throw new IllegalArgumentException("pool must not be null.");
468 }
469 if (factor <= 0f) {
470 throw new IllegalArgumentException("factor must be positive.");
471 }
472 return new ErodingObjectPool(pool, factor);
473 }
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488 public static KeyedObjectPool erodingPool(final KeyedObjectPool keyedPool) {
489 return erodingPool(keyedPool, 1f);
490 }
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513 public static KeyedObjectPool erodingPool(final KeyedObjectPool keyedPool, final float factor) {
514 return erodingPool(keyedPool, factor, false);
515 }
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546 public static KeyedObjectPool erodingPool(final KeyedObjectPool keyedPool, final float factor, final boolean perKey) {
547 if (keyedPool == null) {
548 throw new IllegalArgumentException("keyedPool must not be null.");
549 }
550 if (factor <= 0f) {
551 throw new IllegalArgumentException("factor must be positive.");
552 }
553 if (perKey) {
554 return new ErodingPerKeyKeyedObjectPool(keyedPool, factor);
555 } else {
556 return new ErodingKeyedObjectPool(keyedPool, factor);
557 }
558 }
559
560
561
562
563
564
565
566 private static synchronized Timer getMinIdleTimer() {
567 if (MIN_IDLE_TIMER == null) {
568 MIN_IDLE_TIMER = new Timer(true);
569 }
570 return MIN_IDLE_TIMER;
571 }
572
573
574
575
576
577 private static class PoolableObjectFactoryAdaptor implements PoolableObjectFactory {
578
579 private final Object key;
580
581
582 private final KeyedPoolableObjectFactory keyedFactory;
583
584
585
586
587
588
589
590
591
592 PoolableObjectFactoryAdaptor(final KeyedPoolableObjectFactory keyedFactory, final Object key)
593 throws IllegalArgumentException {
594 if (keyedFactory == null) {
595 throw new IllegalArgumentException("keyedFactory must not be null.");
596 }
597 if (key == null) {
598 throw new IllegalArgumentException("key must not be null.");
599 }
600 this.keyedFactory = keyedFactory;
601 this.key = key;
602 }
603
604
605
606
607
608
609 public Object makeObject() throws Exception {
610 return keyedFactory.makeObject(key);
611 }
612
613
614
615
616
617
618 public void destroyObject(final Object obj) throws Exception {
619 keyedFactory.destroyObject(key, obj);
620 }
621
622
623
624
625
626
627
628 public boolean validateObject(final Object obj) {
629 return keyedFactory.validateObject(key, obj);
630 }
631
632
633
634
635
636
637 public void activateObject(final Object obj) throws Exception {
638 keyedFactory.activateObject(key, obj);
639 }
640
641
642
643
644
645
646 public void passivateObject(final Object obj) throws Exception {
647 keyedFactory.passivateObject(key, obj);
648 }
649
650
651
652
653 public String toString() {
654 final StringBuffer sb = new StringBuffer();
655 sb.append("PoolableObjectFactoryAdaptor");
656 sb.append("{key=").append(key);
657 sb.append(", keyedFactory=").append(keyedFactory);
658 sb.append('}');
659 return sb.toString();
660 }
661 }
662
663
664
665
666
667 private static class KeyedPoolableObjectFactoryAdaptor implements KeyedPoolableObjectFactory {
668
669
670 private final PoolableObjectFactory factory;
671
672
673
674
675
676
677
678
679 KeyedPoolableObjectFactoryAdaptor(final PoolableObjectFactory factory) throws IllegalArgumentException {
680 if (factory == null) {
681 throw new IllegalArgumentException("factory must not be null.");
682 }
683 this.factory = factory;
684 }
685
686
687
688
689
690
691
692 public Object makeObject(final Object key) throws Exception {
693 return factory.makeObject();
694 }
695
696
697
698
699
700
701
702 public void destroyObject(final Object key, final Object obj) throws Exception {
703 factory.destroyObject(obj);
704 }
705
706
707
708
709
710
711
712
713 public boolean validateObject(final Object key, final Object obj) {
714 return factory.validateObject(obj);
715 }
716
717
718
719
720
721
722
723 public void activateObject(final Object key, final Object obj) throws Exception {
724 factory.activateObject(obj);
725 }
726
727
728
729
730
731
732
733 public void passivateObject(final Object key, final Object obj) throws Exception {
734 factory.passivateObject(obj);
735 }
736
737
738
739
740 public String toString() {
741 final StringBuffer sb = new StringBuffer();
742 sb.append("KeyedPoolableObjectFactoryAdaptor");
743 sb.append("{factory=").append(factory);
744 sb.append('}');
745 return sb.toString();
746 }
747 }
748
749
750
751
752
753 private static class ObjectPoolAdaptor implements ObjectPool {
754
755
756 private final Object key;
757
758
759 private final KeyedObjectPool keyedPool;
760
761
762
763
764
765
766
767
768 ObjectPoolAdaptor(final KeyedObjectPool keyedPool, final Object key) throws IllegalArgumentException {
769 if (keyedPool == null) {
770 throw new IllegalArgumentException("keyedPool must not be null.");
771 }
772 if (key == null) {
773 throw new IllegalArgumentException("key must not be null.");
774 }
775 this.keyedPool = keyedPool;
776 this.key = key;
777 }
778
779
780
781
782 public Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
783 return keyedPool.borrowObject(key);
784 }
785
786
787
788
789 public void returnObject(final Object obj) {
790 try {
791 keyedPool.returnObject(key, obj);
792 } catch (Exception e) {
793
794 }
795 }
796
797
798
799
800 public void invalidateObject(final Object obj) {
801 try {
802 keyedPool.invalidateObject(key, obj);
803 } catch (Exception e) {
804
805 }
806 }
807
808
809
810
811 public void addObject() throws Exception, IllegalStateException {
812 keyedPool.addObject(key);
813 }
814
815
816
817
818 public int getNumIdle() throws UnsupportedOperationException {
819 return keyedPool.getNumIdle(key);
820 }
821
822
823
824
825 public int getNumActive() throws UnsupportedOperationException {
826 return keyedPool.getNumActive(key);
827 }
828
829
830
831
832 public void clear() throws Exception, UnsupportedOperationException {
833 keyedPool.clear();
834 }
835
836
837
838
839 public void close() {
840 try {
841 keyedPool.close();
842 } catch (Exception e) {
843
844 }
845 }
846
847
848
849
850
851
852
853 public void setFactory(final PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
854 keyedPool.setFactory(adapt(factory));
855 }
856
857
858
859
860 public String toString() {
861 final StringBuffer sb = new StringBuffer();
862 sb.append("ObjectPoolAdaptor");
863 sb.append("{key=").append(key);
864 sb.append(", keyedPool=").append(keyedPool);
865 sb.append('}');
866 return sb.toString();
867 }
868 }
869
870
871
872
873 private static class KeyedObjectPoolAdaptor implements KeyedObjectPool {
874
875
876 private final ObjectPool pool;
877
878
879
880
881
882
883
884 KeyedObjectPoolAdaptor(final ObjectPool pool) throws IllegalArgumentException {
885 if (pool == null) {
886 throw new IllegalArgumentException("pool must not be null.");
887 }
888 this.pool = pool;
889 }
890
891
892
893
894
895
896
897 public Object borrowObject(final Object key) throws Exception, NoSuchElementException, IllegalStateException {
898 return pool.borrowObject();
899 }
900
901
902
903
904
905
906
907 public void returnObject(final Object key, final Object obj) {
908 try {
909 pool.returnObject(obj);
910 } catch (Exception e) {
911
912 }
913 }
914
915
916
917
918
919
920
921 public void invalidateObject(final Object key, final Object obj) {
922 try {
923 pool.invalidateObject(obj);
924 } catch (Exception e) {
925
926 }
927 }
928
929
930
931
932
933
934 public void addObject(final Object key) throws Exception, IllegalStateException {
935 pool.addObject();
936 }
937
938
939
940
941
942
943
944 public int getNumIdle(final Object key) throws UnsupportedOperationException {
945 return pool.getNumIdle();
946 }
947
948
949
950
951
952
953
954 public int getNumActive(final Object key) throws UnsupportedOperationException {
955 return pool.getNumActive();
956 }
957
958
959
960
961 public int getNumIdle() throws UnsupportedOperationException {
962 return pool.getNumIdle();
963 }
964
965
966
967
968 public int getNumActive() throws UnsupportedOperationException {
969 return pool.getNumActive();
970 }
971
972
973
974
975 public void clear() throws Exception, UnsupportedOperationException {
976 pool.clear();
977 }
978
979
980
981
982
983
984 public void clear(final Object key) throws Exception, UnsupportedOperationException {
985 pool.clear();
986 }
987
988
989
990
991 public void close() {
992 try {
993 pool.close();
994 } catch (Exception e) {
995
996 }
997 }
998
999
1000
1001
1002
1003
1004
1005 public void setFactory(final KeyedPoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
1006 pool.setFactory(adapt(factory));
1007 }
1008
1009
1010
1011
1012 public String toString() {
1013 final StringBuffer sb = new StringBuffer();
1014 sb.append("KeyedObjectPoolAdaptor");
1015 sb.append("{pool=").append(pool);
1016 sb.append('}');
1017 return sb.toString();
1018 }
1019 }
1020
1021
1022
1023
1024
1025
1026 private static class CheckedObjectPool implements ObjectPool {
1027
1028
1029
1030
1031 private final Class type;
1032
1033
1034 private final ObjectPool pool;
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044 CheckedObjectPool(final ObjectPool pool, final Class type) {
1045 if (pool == null) {
1046 throw new IllegalArgumentException("pool must not be null.");
1047 }
1048 if (type == null) {
1049 throw new IllegalArgumentException("type must not be null.");
1050 }
1051 this.pool = pool;
1052 this.type = type;
1053 }
1054
1055
1056
1057
1058
1059
1060
1061 public Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
1062 final Object obj = pool.borrowObject();
1063 if (type.isInstance(obj)) {
1064 return obj;
1065 } else {
1066 throw new ClassCastException("Borrowed object is not of type: " + type.getName() + " was: " + obj);
1067 }
1068 }
1069
1070
1071
1072
1073
1074
1075
1076 public void returnObject(final Object obj) {
1077 if (type.isInstance(obj)) {
1078 try {
1079 pool.returnObject(obj);
1080 } catch (Exception e) {
1081
1082 }
1083 } else {
1084 throw new ClassCastException("Returned object is not of type: " + type.getName() + " was: " + obj);
1085 }
1086 }
1087
1088
1089
1090
1091
1092
1093
1094 public void invalidateObject(final Object obj) {
1095 if (type.isInstance(obj)) {
1096 try {
1097 pool.invalidateObject(obj);
1098 } catch (Exception e) {
1099
1100 }
1101 } else {
1102 throw new ClassCastException("Invalidated object is not of type: " + type.getName() + " was: " + obj);
1103 }
1104 }
1105
1106
1107
1108
1109 public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
1110 pool.addObject();
1111 }
1112
1113
1114
1115
1116 public int getNumIdle() throws UnsupportedOperationException {
1117 return pool.getNumIdle();
1118 }
1119
1120
1121
1122
1123 public int getNumActive() throws UnsupportedOperationException {
1124 return pool.getNumActive();
1125 }
1126
1127
1128
1129
1130 public void clear() throws Exception, UnsupportedOperationException {
1131 pool.clear();
1132 }
1133
1134
1135
1136
1137 public void close() {
1138 try {
1139 pool.close();
1140 } catch (Exception e) {
1141
1142 }
1143 }
1144
1145
1146
1147
1148
1149
1150
1151 public void setFactory(final PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
1152 pool.setFactory(factory);
1153 }
1154
1155
1156
1157
1158 public String toString() {
1159 final StringBuffer sb = new StringBuffer();
1160 sb.append("CheckedObjectPool");
1161 sb.append("{type=").append(type);
1162 sb.append(", pool=").append(pool);
1163 sb.append('}');
1164 return sb.toString();
1165 }
1166 }
1167
1168
1169
1170
1171
1172
1173 private static class CheckedKeyedObjectPool implements KeyedObjectPool {
1174
1175
1176
1177
1178 private final Class type;
1179
1180
1181 private final KeyedObjectPool keyedPool;
1182
1183
1184
1185
1186
1187
1188
1189
1190 CheckedKeyedObjectPool(final KeyedObjectPool keyedPool, final Class type) {
1191 if (keyedPool == null) {
1192 throw new IllegalArgumentException("keyedPool must not be null.");
1193 }
1194 if (type == null) {
1195 throw new IllegalArgumentException("type must not be null.");
1196 }
1197 this.keyedPool = keyedPool;
1198 this.type = type;
1199 }
1200
1201
1202
1203
1204
1205
1206
1207
1208 public Object borrowObject(final Object key) throws Exception, NoSuchElementException, IllegalStateException {
1209 Object obj = keyedPool.borrowObject(key);
1210 if (type.isInstance(obj)) {
1211 return obj;
1212 } else {
1213 throw new ClassCastException("Borrowed object for key: " + key + " is not of type: " + type.getName() + " was: " + obj);
1214 }
1215 }
1216
1217
1218
1219
1220
1221
1222
1223
1224 public void returnObject(final Object key, final Object obj) {
1225 if (type.isInstance(obj)) {
1226 try {
1227 keyedPool.returnObject(key, obj);
1228 } catch (Exception e) {
1229
1230 }
1231 } else {
1232 throw new ClassCastException("Returned object for key: " + key + " is not of type: " + type.getName() + " was: " + obj);
1233 }
1234 }
1235
1236
1237
1238
1239
1240
1241
1242
1243 public void invalidateObject(final Object key, final Object obj) {
1244 if (type.isInstance(obj)) {
1245 try {
1246 keyedPool.invalidateObject(key, obj);
1247 } catch (Exception e) {
1248
1249 }
1250 } else {
1251 throw new ClassCastException("Invalidated object for key: " + key + " is not of type: " + type.getName() + " was: " + obj);
1252 }
1253 }
1254
1255
1256
1257
1258 public void addObject(final Object key) throws Exception, IllegalStateException, UnsupportedOperationException {
1259 keyedPool.addObject(key);
1260 }
1261
1262
1263
1264
1265 public int getNumIdle(final Object key) throws UnsupportedOperationException {
1266 return keyedPool.getNumIdle(key);
1267 }
1268
1269
1270
1271
1272 public int getNumActive(final Object key) throws UnsupportedOperationException {
1273 return keyedPool.getNumActive(key);
1274 }
1275
1276
1277
1278
1279 public int getNumIdle() throws UnsupportedOperationException {
1280 return keyedPool.getNumIdle();
1281 }
1282
1283
1284
1285
1286 public int getNumActive() throws UnsupportedOperationException {
1287 return keyedPool.getNumActive();
1288 }
1289
1290
1291
1292
1293 public void clear() throws Exception, UnsupportedOperationException {
1294 keyedPool.clear();
1295 }
1296
1297
1298
1299
1300 public void clear(final Object key) throws Exception, UnsupportedOperationException {
1301 keyedPool.clear(key);
1302 }
1303
1304
1305
1306
1307 public void close() {
1308 try {
1309 keyedPool.close();
1310 } catch (Exception e) {
1311
1312 }
1313 }
1314
1315
1316
1317
1318
1319
1320
1321 public void setFactory(final KeyedPoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
1322 keyedPool.setFactory(factory);
1323 }
1324
1325
1326
1327
1328 public String toString() {
1329 final StringBuffer sb = new StringBuffer();
1330 sb.append("CheckedKeyedObjectPool");
1331 sb.append("{type=").append(type);
1332 sb.append(", keyedPool=").append(keyedPool);
1333 sb.append('}');
1334 return sb.toString();
1335 }
1336 }
1337
1338
1339
1340
1341
1342
1343
1344 private static class ObjectPoolMinIdleTimerTask extends TimerTask {
1345
1346
1347 private final int minIdle;
1348
1349
1350 private final ObjectPool pool;
1351
1352
1353
1354
1355
1356
1357
1358
1359 ObjectPoolMinIdleTimerTask(final ObjectPool pool, final int minIdle) throws IllegalArgumentException {
1360 if (pool == null) {
1361 throw new IllegalArgumentException("pool must not be null.");
1362 }
1363 this.pool = pool;
1364 this.minIdle = minIdle;
1365 }
1366
1367
1368
1369
1370 public void run() {
1371 boolean success = false;
1372 try {
1373 if (pool.getNumIdle() < minIdle) {
1374 pool.addObject();
1375 }
1376 success = true;
1377
1378 } catch (Exception e) {
1379 cancel();
1380
1381 } finally {
1382
1383 if (!success) {
1384 cancel();
1385 }
1386 }
1387 }
1388
1389
1390
1391
1392 public String toString() {
1393 final StringBuffer sb = new StringBuffer();
1394 sb.append("ObjectPoolMinIdleTimerTask");
1395 sb.append("{minIdle=").append(minIdle);
1396 sb.append(", pool=").append(pool);
1397 sb.append('}');
1398 return sb.toString();
1399 }
1400 }
1401
1402
1403
1404
1405
1406
1407
1408 private static class KeyedObjectPoolMinIdleTimerTask extends TimerTask {
1409
1410 private final int minIdle;
1411
1412
1413 private final Object key;
1414
1415
1416 private final KeyedObjectPool keyedPool;
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426 KeyedObjectPoolMinIdleTimerTask(final KeyedObjectPool keyedPool, final Object key, final int minIdle) throws IllegalArgumentException {
1427 if (keyedPool == null) {
1428 throw new IllegalArgumentException("keyedPool must not be null.");
1429 }
1430 this.keyedPool = keyedPool;
1431 this.key = key;
1432 this.minIdle = minIdle;
1433 }
1434
1435
1436
1437
1438 public void run() {
1439 boolean success = false;
1440 try {
1441 if (keyedPool.getNumIdle(key) < minIdle) {
1442 keyedPool.addObject(key);
1443 }
1444 success = true;
1445
1446 } catch (Exception e) {
1447 cancel();
1448
1449 } finally {
1450
1451 if (!success) {
1452 cancel();
1453 }
1454 }
1455 }
1456
1457
1458
1459
1460 public String toString() {
1461 final StringBuffer sb = new StringBuffer();
1462 sb.append("KeyedObjectPoolMinIdleTimerTask");
1463 sb.append("{minIdle=").append(minIdle);
1464 sb.append(", key=").append(key);
1465 sb.append(", keyedPool=").append(keyedPool);
1466 sb.append('}');
1467 return sb.toString();
1468 }
1469 }
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481 private static class SynchronizedObjectPool implements ObjectPool {
1482
1483
1484 private final Object lock;
1485
1486
1487 private final ObjectPool pool;
1488
1489
1490
1491
1492
1493
1494
1495 SynchronizedObjectPool(final ObjectPool pool) throws IllegalArgumentException {
1496 if (pool == null) {
1497 throw new IllegalArgumentException("pool must not be null.");
1498 }
1499 this.pool = pool;
1500 lock = new Object();
1501 }
1502
1503
1504
1505
1506 public Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
1507 synchronized (lock) {
1508 return pool.borrowObject();
1509 }
1510 }
1511
1512
1513
1514
1515 public void returnObject(final Object obj) {
1516 synchronized (lock) {
1517 try {
1518 pool.returnObject(obj);
1519 } catch (Exception e) {
1520
1521 }
1522 }
1523 }
1524
1525
1526
1527
1528 public void invalidateObject(final Object obj) {
1529 synchronized (lock) {
1530 try {
1531 pool.invalidateObject(obj);
1532 } catch (Exception e) {
1533
1534 }
1535 }
1536 }
1537
1538
1539
1540
1541 public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
1542 synchronized (lock) {
1543 pool.addObject();
1544 }
1545 }
1546
1547
1548
1549
1550 public int getNumIdle() throws UnsupportedOperationException {
1551 synchronized (lock) {
1552 return pool.getNumIdle();
1553 }
1554 }
1555
1556
1557
1558
1559 public int getNumActive() throws UnsupportedOperationException {
1560 synchronized (lock) {
1561 return pool.getNumActive();
1562 }
1563 }
1564
1565
1566
1567
1568 public void clear() throws Exception, UnsupportedOperationException {
1569 synchronized (lock) {
1570 pool.clear();
1571 }
1572 }
1573
1574
1575
1576
1577 public void close() {
1578 try {
1579 synchronized (lock) {
1580 pool.close();
1581 }
1582 } catch (Exception e) {
1583
1584 }
1585 }
1586
1587
1588
1589
1590
1591
1592
1593 public void setFactory(final PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
1594 synchronized (lock) {
1595 pool.setFactory(factory);
1596 }
1597 }
1598
1599
1600
1601
1602 public String toString() {
1603 final StringBuffer sb = new StringBuffer();
1604 sb.append("SynchronizedObjectPool");
1605 sb.append("{pool=").append(pool);
1606 sb.append('}');
1607 return sb.toString();
1608 }
1609 }
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621 private static class SynchronizedKeyedObjectPool implements KeyedObjectPool {
1622
1623
1624 private final Object lock;
1625
1626
1627 private final KeyedObjectPool keyedPool;
1628
1629
1630
1631
1632
1633
1634
1635 SynchronizedKeyedObjectPool(final KeyedObjectPool keyedPool) throws IllegalArgumentException {
1636 if (keyedPool == null) {
1637 throw new IllegalArgumentException("keyedPool must not be null.");
1638 }
1639 this.keyedPool = keyedPool;
1640 lock = new Object();
1641 }
1642
1643
1644
1645
1646 public Object borrowObject(final Object key) throws Exception, NoSuchElementException, IllegalStateException {
1647 synchronized (lock) {
1648 return keyedPool.borrowObject(key);
1649 }
1650 }
1651
1652
1653
1654
1655 public void returnObject(final Object key, final Object obj) {
1656 synchronized (lock) {
1657 try {
1658 keyedPool.returnObject(key, obj);
1659 } catch (Exception e) {
1660
1661 }
1662 }
1663 }
1664
1665
1666
1667
1668 public void invalidateObject(final Object key, final Object obj) {
1669 synchronized (lock) {
1670 try {
1671 keyedPool.invalidateObject(key, obj);
1672 } catch (Exception e) {
1673
1674 }
1675 }
1676 }
1677
1678
1679
1680
1681 public void addObject(final Object key) throws Exception, IllegalStateException, UnsupportedOperationException {
1682 synchronized (lock) {
1683 keyedPool.addObject(key);
1684 }
1685 }
1686
1687
1688
1689
1690 public int getNumIdle(final Object key) throws UnsupportedOperationException {
1691 synchronized (lock) {
1692 return keyedPool.getNumIdle(key);
1693 }
1694 }
1695
1696
1697
1698
1699 public int getNumActive(final Object key) throws UnsupportedOperationException {
1700 synchronized (lock) {
1701 return keyedPool.getNumActive(key);
1702 }
1703 }
1704
1705
1706
1707
1708 public int getNumIdle() throws UnsupportedOperationException {
1709 synchronized (lock) {
1710 return keyedPool.getNumIdle();
1711 }
1712 }
1713
1714
1715
1716
1717 public int getNumActive() throws UnsupportedOperationException {
1718 synchronized (lock) {
1719 return keyedPool.getNumActive();
1720 }
1721 }
1722
1723
1724
1725
1726 public void clear() throws Exception, UnsupportedOperationException {
1727 synchronized (lock) {
1728 keyedPool.clear();
1729 }
1730 }
1731
1732
1733
1734
1735 public void clear(final Object key) throws Exception, UnsupportedOperationException {
1736 synchronized (lock) {
1737 keyedPool.clear(key);
1738 }
1739 }
1740
1741
1742
1743
1744 public void close() {
1745 try {
1746 synchronized (lock) {
1747 keyedPool.close();
1748 }
1749 } catch (Exception e) {
1750
1751 }
1752 }
1753
1754
1755
1756
1757
1758
1759
1760 public void setFactory(final KeyedPoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
1761 synchronized (lock) {
1762 keyedPool.setFactory(factory);
1763 }
1764 }
1765
1766
1767
1768
1769 public String toString() {
1770 final StringBuffer sb = new StringBuffer();
1771 sb.append("SynchronizedKeyedObjectPool");
1772 sb.append("{keyedPool=").append(keyedPool);
1773 sb.append('}');
1774 return sb.toString();
1775 }
1776 }
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786 private static class SynchronizedPoolableObjectFactory implements PoolableObjectFactory {
1787
1788 private final Object lock;
1789
1790
1791 private final PoolableObjectFactory factory;
1792
1793
1794
1795
1796
1797
1798
1799 SynchronizedPoolableObjectFactory(final PoolableObjectFactory factory) throws IllegalArgumentException {
1800 if (factory == null) {
1801 throw new IllegalArgumentException("factory must not be null.");
1802 }
1803 this.factory = factory;
1804 lock = new Object();
1805 }
1806
1807
1808
1809
1810 public Object makeObject() throws Exception {
1811 synchronized (lock) {
1812 return factory.makeObject();
1813 }
1814 }
1815
1816
1817
1818
1819 public void destroyObject(final Object obj) throws Exception {
1820 synchronized (lock) {
1821 factory.destroyObject(obj);
1822 }
1823 }
1824
1825
1826
1827
1828 public boolean validateObject(final Object obj) {
1829 synchronized (lock) {
1830 return factory.validateObject(obj);
1831 }
1832 }
1833
1834
1835
1836
1837 public void activateObject(final Object obj) throws Exception {
1838 synchronized (lock) {
1839 factory.activateObject(obj);
1840 }
1841 }
1842
1843
1844
1845
1846 public void passivateObject(final Object obj) throws Exception {
1847 synchronized (lock) {
1848 factory.passivateObject(obj);
1849 }
1850 }
1851
1852
1853
1854
1855 public String toString() {
1856 final StringBuffer sb = new StringBuffer();
1857 sb.append("SynchronizedPoolableObjectFactory");
1858 sb.append("{factory=").append(factory);
1859 sb.append('}');
1860 return sb.toString();
1861 }
1862 }
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872 private static class SynchronizedKeyedPoolableObjectFactory implements KeyedPoolableObjectFactory {
1873
1874 private final Object lock;
1875
1876
1877 private final KeyedPoolableObjectFactory keyedFactory;
1878
1879
1880
1881
1882
1883
1884
1885 SynchronizedKeyedPoolableObjectFactory(final KeyedPoolableObjectFactory keyedFactory) throws IllegalArgumentException {
1886 if (keyedFactory == null) {
1887 throw new IllegalArgumentException("keyedFactory must not be null.");
1888 }
1889 this.keyedFactory = keyedFactory;
1890 lock = new Object();
1891 }
1892
1893
1894
1895
1896 public Object makeObject(final Object key) throws Exception {
1897 synchronized (lock) {
1898 return keyedFactory.makeObject(key);
1899 }
1900 }
1901
1902
1903
1904
1905 public void destroyObject(final Object key, final Object obj) throws Exception {
1906 synchronized (lock) {
1907 keyedFactory.destroyObject(key, obj);
1908 }
1909 }
1910
1911
1912
1913
1914 public boolean validateObject(final Object key, final Object obj) {
1915 synchronized (lock) {
1916 return keyedFactory.validateObject(key, obj);
1917 }
1918 }
1919
1920
1921
1922
1923 public void activateObject(final Object key, final Object obj) throws Exception {
1924 synchronized (lock) {
1925 keyedFactory.activateObject(key, obj);
1926 }
1927 }
1928
1929
1930
1931
1932 public void passivateObject(final Object key, final Object obj) throws Exception {
1933 synchronized (lock) {
1934 keyedFactory.passivateObject(key, obj);
1935 }
1936 }
1937
1938
1939
1940
1941 public String toString() {
1942 final StringBuffer sb = new StringBuffer();
1943 sb.append("SynchronizedKeyedPoolableObjectFactory");
1944 sb.append("{keyedFactory=").append(keyedFactory);
1945 sb.append('}');
1946 return sb.toString();
1947 }
1948 }
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959 private static class ErodingFactor {
1960
1961 private final float factor;
1962
1963
1964 private transient volatile long nextShrink;
1965
1966
1967 private transient volatile int idleHighWaterMark;
1968
1969
1970
1971
1972
1973
1974 public ErodingFactor(final float factor) {
1975 this.factor = factor;
1976 nextShrink = System.currentTimeMillis() + (long)(900000 * factor);
1977 idleHighWaterMark = 1;
1978 }
1979
1980
1981
1982
1983
1984
1985 public void update(final int numIdle) {
1986 update(System.currentTimeMillis(), numIdle);
1987 }
1988
1989
1990
1991
1992
1993
1994
1995 public void update(final long now, final int numIdle) {
1996 final int idle = Math.max(0, numIdle);
1997 idleHighWaterMark = Math.max(idle, idleHighWaterMark);
1998 final float maxInterval = 15f;
1999 final float minutes = maxInterval + ((1f-maxInterval)/idleHighWaterMark) * idle;
2000 nextShrink = now + (long)(minutes * 60000f * factor);
2001 }
2002
2003
2004
2005
2006
2007
2008 public long getNextShrink() {
2009 return nextShrink;
2010 }
2011
2012
2013
2014
2015 public String toString() {
2016 return "ErodingFactor{" +
2017 "factor=" + factor +
2018 ", idleHighWaterMark=" + idleHighWaterMark +
2019 '}';
2020 }
2021 }
2022
2023
2024
2025
2026
2027
2028
2029 private static class ErodingObjectPool implements ObjectPool {
2030
2031 private final ObjectPool pool;
2032
2033
2034 private final ErodingFactor factor;
2035
2036
2037
2038
2039
2040
2041
2042
2043 public ErodingObjectPool(final ObjectPool pool, final float factor) {
2044 this.pool = pool;
2045 this.factor = new ErodingFactor(factor);
2046 }
2047
2048
2049
2050
2051 public Object borrowObject() throws Exception, NoSuchElementException, IllegalStateException {
2052 return pool.borrowObject();
2053 }
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064 public void returnObject(final Object obj) {
2065 boolean discard = false;
2066 final long now = System.currentTimeMillis();
2067 synchronized (pool) {
2068 if (factor.getNextShrink() < now) {
2069 final int numIdle = pool.getNumIdle();
2070 if (numIdle > 0) {
2071 discard = true;
2072 }
2073
2074 factor.update(now, numIdle);
2075 }
2076 }
2077 try {
2078 if (discard) {
2079 pool.invalidateObject(obj);
2080 } else {
2081 pool.returnObject(obj);
2082 }
2083 } catch (Exception e) {
2084
2085 }
2086 }
2087
2088
2089
2090
2091 public void invalidateObject(final Object obj) {
2092 try {
2093 pool.invalidateObject(obj);
2094 } catch (Exception e) {
2095
2096 }
2097 }
2098
2099
2100
2101
2102 public void addObject() throws Exception, IllegalStateException, UnsupportedOperationException {
2103 pool.addObject();
2104 }
2105
2106
2107
2108
2109 public int getNumIdle() throws UnsupportedOperationException {
2110 return pool.getNumIdle();
2111 }
2112
2113
2114
2115
2116 public int getNumActive() throws UnsupportedOperationException {
2117 return pool.getNumActive();
2118 }
2119
2120
2121
2122
2123 public void clear() throws Exception, UnsupportedOperationException {
2124 pool.clear();
2125 }
2126
2127
2128
2129
2130 public void close() {
2131 try {
2132 pool.close();
2133 } catch (Exception e) {
2134
2135 }
2136 }
2137
2138
2139
2140
2141
2142 public void setFactory(final PoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
2143 pool.setFactory(factory);
2144 }
2145
2146
2147
2148
2149 public String toString() {
2150 return "ErodingObjectPool{" +
2151 "factor=" + factor +
2152 ", pool=" + pool +
2153 '}';
2154 }
2155 }
2156
2157
2158
2159
2160
2161
2162
2163 private static class ErodingKeyedObjectPool implements KeyedObjectPool {
2164
2165 private final KeyedObjectPool keyedPool;
2166
2167
2168 private final ErodingFactor erodingFactor;
2169
2170
2171
2172
2173
2174
2175
2176
2177 public ErodingKeyedObjectPool(final KeyedObjectPool keyedPool, final float factor) {
2178 this(keyedPool, new ErodingFactor(factor));
2179 }
2180
2181
2182
2183
2184
2185
2186
2187
2188 protected ErodingKeyedObjectPool(final KeyedObjectPool keyedPool, final ErodingFactor erodingFactor) {
2189 if (keyedPool == null) {
2190 throw new IllegalArgumentException("keyedPool must not be null.");
2191 }
2192 this.keyedPool = keyedPool;
2193 this.erodingFactor = erodingFactor;
2194 }
2195
2196
2197
2198
2199 public Object borrowObject(final Object key) throws Exception, NoSuchElementException, IllegalStateException {
2200 return keyedPool.borrowObject(key);
2201 }
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213 public void returnObject(final Object key, final Object obj) throws Exception {
2214 boolean discard = false;
2215 final long now = System.currentTimeMillis();
2216 final ErodingFactor factor = getErodingFactor(key);
2217 synchronized (keyedPool) {
2218 if (factor.getNextShrink() < now) {
2219 final int numIdle = numIdle(key);
2220 if (numIdle > 0) {
2221 discard = true;
2222 }
2223
2224 factor.update(now, numIdle);
2225 }
2226 }
2227 try {
2228 if (discard) {
2229 keyedPool.invalidateObject(key, obj);
2230 } else {
2231 keyedPool.returnObject(key, obj);
2232 }
2233 } catch (Exception e) {
2234
2235 }
2236 }
2237
2238 protected int numIdle(final Object key) {
2239 return getKeyedPool().getNumIdle();
2240 }
2241
2242
2243
2244
2245
2246
2247 protected ErodingFactor getErodingFactor(final Object key) {
2248 return erodingFactor;
2249 }
2250
2251
2252
2253
2254 public void invalidateObject(final Object key, final Object obj) {
2255 try {
2256 keyedPool.invalidateObject(key, obj);
2257 } catch (Exception e) {
2258
2259 }
2260 }
2261
2262
2263
2264
2265 public void addObject(final Object key) throws Exception, IllegalStateException, UnsupportedOperationException {
2266 keyedPool.addObject(key);
2267 }
2268
2269
2270
2271
2272 public int getNumIdle() throws UnsupportedOperationException {
2273 return keyedPool.getNumIdle();
2274 }
2275
2276
2277
2278
2279 public int getNumIdle(final Object key) throws UnsupportedOperationException {
2280 return keyedPool.getNumIdle(key);
2281 }
2282
2283
2284
2285
2286 public int getNumActive() throws UnsupportedOperationException {
2287 return keyedPool.getNumActive();
2288 }
2289
2290
2291
2292
2293 public int getNumActive(final Object key) throws UnsupportedOperationException {
2294 return keyedPool.getNumActive(key);
2295 }
2296
2297
2298
2299
2300 public void clear() throws Exception, UnsupportedOperationException {
2301 keyedPool.clear();
2302 }
2303
2304
2305
2306
2307 public void clear(final Object key) throws Exception, UnsupportedOperationException {
2308 keyedPool.clear(key);
2309 }
2310
2311
2312
2313
2314 public void close() {
2315 try {
2316 keyedPool.close();
2317 } catch (Exception e) {
2318
2319 }
2320 }
2321
2322
2323
2324
2325
2326 public void setFactory(final KeyedPoolableObjectFactory factory) throws IllegalStateException, UnsupportedOperationException {
2327 keyedPool.setFactory(factory);
2328 }
2329
2330
2331
2332
2333
2334
2335 protected KeyedObjectPool getKeyedPool() {
2336 return keyedPool;
2337 }
2338
2339
2340
2341
2342 public String toString() {
2343 return "ErodingKeyedObjectPool{" +
2344 "erodingFactor=" + erodingFactor +
2345 ", keyedPool=" + keyedPool +
2346 '}';
2347 }
2348 }
2349
2350
2351
2352
2353
2354 private static class ErodingPerKeyKeyedObjectPool extends ErodingKeyedObjectPool {
2355
2356 private final float factor;
2357
2358
2359 private final Map factors = Collections.synchronizedMap(new HashMap());
2360
2361
2362
2363
2364
2365
2366
2367 public ErodingPerKeyKeyedObjectPool(final KeyedObjectPool keyedPool, final float factor) {
2368 super(keyedPool, null);
2369 this.factor = factor;
2370 }
2371
2372
2373
2374
2375 protected int numIdle(final Object key) {
2376 return getKeyedPool().getNumIdle(key);
2377 }
2378
2379
2380
2381
2382 protected ErodingFactor getErodingFactor(final Object key) {
2383 ErodingFactor factor = (ErodingFactor)factors.get(key);
2384
2385
2386 if (factor == null) {
2387 factor = new ErodingFactor(this.factor);
2388 factors.put(key, factor);
2389 }
2390 return factor;
2391 }
2392
2393
2394
2395
2396 public String toString() {
2397 return "ErodingPerKeyKeyedObjectPool{" +
2398 "factor=" + factor +
2399 ", keyedPool=" + getKeyedPool() +
2400 '}';
2401 }
2402 }
2403 }