01 /*
02 * PoolFiller.java
03 *
04 * Copyright (c) 1995-2010, The University of Sheffield. See the file
05 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
06 *
07 * This file is part of GATE (see http://gate.ac.uk/), and is free
08 * software, licenced under the GNU Library General Public License,
09 * Version 2, June 1991 (in the distribution as file licence.html,
10 * and also available at http://gate.ac.uk/gate/licence.html).
11 *
12 * Ian Roberts, 10/Apr/2010
13 *
14 * $Id: PoolFiller.java 12496 2010-04-15 16:20:57Z ian_roberts $
15 */
16 package gate.util.spring.xml;
17
18 import org.springframework.aop.target.AbstractPoolingTargetSource;
19 import org.springframework.beans.factory.InitializingBean;
20
21 /**
22 * Simple bean that takes a pooled target source and performs a sequence
23 * of n getTarget calls followed by n releaseTarget calls. This has the
24 * effect of pre-populating the pool with n instances up-front (normally
25 * a pooled target source only creates objects the first time they are
26 * required). Note that if the specified number of instances is greater
27 * than the maximum size of the pool the number of calls will be reduced
28 * accordingly.
29 */
30 public class PoolFiller implements InitializingBean {
31
32 private AbstractPoolingTargetSource targetSource;
33
34 private int numInstances = 1;
35
36 /**
37 * Set the target source to be populated.
38 */
39 public void setTargetSource(AbstractPoolingTargetSource targetSource) {
40 this.targetSource = targetSource;
41 }
42
43 /**
44 * Set the number of nested get/release calls to make. The actual
45 * number of calls made is the minimum of this value and the maximum
46 * size of the pool.
47 */
48 public void setNumInstances(int numInstances) {
49 this.numInstances = numInstances;
50 }
51
52 public void afterPropertiesSet() throws Exception {
53 int instancesToCreate = numInstances;
54 if(instancesToCreate > targetSource.getMaxSize()) {
55 instancesToCreate = targetSource.getMaxSize();
56 }
57 checkoutTargets(instancesToCreate);
58 }
59
60 /**
61 * Recursive helper method to check out <code>num</code> targets
62 * from the target source and then release them, with proper
63 * try/finally handling in case of exceptions. If the target source is
64 * backed by a pool this will have the effect of forcing upfront
65 * creation of at least <code>num</code> instances in the pool.
66 */
67 private void checkoutTargets(int num) throws Exception {
68 if(num < 1) return;
69 Object target = targetSource.getTarget();
70 try {
71 checkoutTargets(num - 1);
72 }
73 finally {
74 if(target != null) targetSource.releaseTarget(target);
75 }
76 }
77 }
|