1   package org.apache.fulcrum.pool;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  import java.lang.reflect.Method;
23  import java.util.ArrayList;
24  
25  import org.apache.fulcrum.factory.FactoryService;
26  
27  
28  
29  
30  public class PoolBuffer 
31  {
32  
33  	
34  
35  
36  	private BoundedBuffer pool;
37  
38  	
39  
40  
41  	private boolean arrayCtorRecyclable;
42  
43  	
44  
45  
46  	private ArrayList<Recycler> recyclers;
47  
48  	
49  
50  
51  
52  
53  	public PoolBuffer(int capacity) 
54  	{
55  		pool = new BoundedBuffer(capacity);
56  	}
57  
58  	
59  
60  
61  
62  
63  
64  	public void setArrayCtorRecyclable(boolean isArrayCtor) 
65  	{
66  		arrayCtorRecyclable = isArrayCtor;
67  	}
68  
69  	
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  	public <T> T poll(Object[] params, String[] signature, FactoryService factoryService) throws PoolException 
80  	{
81  		T instance = pool.poll();
82  		if (instance != null) 
83  		{
84  			if (arrayCtorRecyclable) 
85  			{
86  				((ArrayCtorRecyclable) instance).recycle(params);
87  			} else if (instance instanceof Recyclable) {
88  				try 
89  				{
90  					if (signature != null && signature.length > 0) 
91  					{
92  						
93  						Method recycle = getRecycle(signature);
94  						if (recycle == null) 
95  						{
96  							synchronized (this) {
97  								
98  								recycle = getRecycle(signature);
99  								if (recycle == null) 
100 								{
101 									Class<? extends Object> clazz = instance.getClass();
102 									recycle = clazz.getMethod("recycle",
103 											factoryService.getSignature(clazz, params, signature));
104 
105 									@SuppressWarnings("unchecked")
106 									ArrayList<Recycler> cache = recyclers != null
107 											? (ArrayList<Recycler>) recyclers.clone()
108 											: new ArrayList<Recycler>();
109 									cache.add(new Recycler(recycle, signature));
110 									recyclers = cache;
111 								}
112 							}
113 						}
114 						recycle.invoke(instance, params);
115 					} else {
116 						((Recyclable) instance).recycle();
117 					}
118 				} 
119 				catch (Exception x) 
120 				{
121 					throw new PoolException("Recycling failed for " + instance.getClass().getName(), x);
122 				}
123 			}
124 		}
125 		return instance;
126 	}
127 
128 	
129 
130 
131 
132 
133 
134 	public boolean offer(Object instance) 
135 	{
136 		if (instance instanceof Recyclable) 
137 		{
138 			try 
139 			{
140 				((Recyclable) instance).dispose();
141 			} 
142 			catch (Exception x) 
143 			{
144 				return false;
145 			}
146 		}
147 		return pool.offer(instance);
148 	}
149 
150 	
151 
152 
153 
154 
155 	public int capacity() 
156 	{
157 		return pool.capacity();
158 	}
159 
160 	
161 
162 
163 
164 
165 	public int size() 
166 	{
167 		return pool.size();
168 	}
169 
170 	
171 
172 
173 
174 
175 
176 	private Method getRecycle(String[] signature) 
177 	{
178 		ArrayList<Recycler> cache = recyclers;
179 		if (cache != null) 
180 		{
181 			Method recycle;
182 			for (Recycler recycler : cache) 
183 			{
184 				recycle = recycler.match(signature);
185 				if (recycle != null)
186 					return recycle;
187 			}
188 		}
189 		return null;
190 	}
191 }