1 package org.apache.torque.manager;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.Serializable;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 import org.apache.commons.pool.ObjectPool;
24 import org.apache.commons.pool.impl.StackObjectPool;
25
26 import org.apache.jcs.access.GroupCacheAccess;
27 import org.apache.jcs.access.exception.CacheException;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 import org.apache.torque.TorqueException;
33
34 /***
35 * This class provides a cache for convenient storage of method
36 * results.
37 *
38 * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
39 * @version $Id: MethodResultCache.java 239630 2005-08-24 12:25:32Z henning $
40 */
41 public class MethodResultCache
42 {
43 private ObjectPool pool;
44 private GroupCacheAccess jcsCache;
45 private Map groups;
46
47 /*** Logging */
48 private static Log log = LogFactory.getLog(MethodResultCache.class);
49
50 public MethodResultCache(GroupCacheAccess cache)
51 throws TorqueException
52 {
53 this.jcsCache = cache;
54 groups = new HashMap();
55 pool = new StackObjectPool(new MethodCacheKey.Factory(), 10000);
56 }
57
58 /***
59 * Allows subclasses to have ctors that do not require a cache.
60 * This is used by NullMethodResultCache which has no-op versions
61 * of all methods.
62 */
63 protected MethodResultCache()
64 {
65 }
66
67 public void clear()
68 {
69 if (jcsCache != null)
70 {
71 try
72 {
73 jcsCache.remove();
74 groups.clear();
75 }
76 catch (CacheException ce)
77 {
78 log.error(new TorqueException(
79 "Could not clear cache due to internal JCS error.", ce));
80 }
81 }
82 }
83
84 protected Object getImpl(MethodCacheKey key)
85 {
86 Object result = null;
87 if (jcsCache != null)
88 {
89 synchronized (this)
90 {
91 result = jcsCache.getFromGroup(key, key.getGroupKey());
92 }
93 }
94
95 if (result != null)
96 {
97 if (log.isDebugEnabled())
98 {
99 log.debug("MethodResultCache saved expensive operation: " + key);
100 }
101 }
102 return result;
103 }
104
105
106 protected Object putImpl(MethodCacheKey key, Object value)
107 throws TorqueException
108 {
109
110 String group = key.getGroupKey();
111 if (!groups.containsKey(group))
112 {
113 groups.put(group, null);
114 }
115
116 Object old = null;
117 if (jcsCache != null)
118 {
119 try
120 {
121 synchronized (this)
122 {
123 old = jcsCache.getFromGroup(key, group);
124 jcsCache.putInGroup(key, group, value);
125 }
126 }
127 catch (CacheException ce)
128 {
129 throw new TorqueException
130 ("Could not cache due to internal JCS error", ce);
131 }
132 }
133 return old;
134 }
135
136 protected Object removeImpl(MethodCacheKey key)
137 throws TorqueException
138 {
139 Object old = null;
140 if (jcsCache != null)
141 {
142 synchronized (this)
143 {
144 old = jcsCache.getFromGroup(key, key.getGroupKey());
145 jcsCache.remove(key, key.getGroupKey());
146 }
147 }
148 return old;
149 }
150
151
152 public Object get(Serializable instanceOrClass, String method)
153 {
154 Object result = null;
155 if (jcsCache != null)
156 {
157 try
158 {
159 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
160 key.init(instanceOrClass, method);
161 result = getImpl(key);
162 try
163 {
164 pool.returnObject(key);
165 }
166 catch (Exception e)
167 {
168 log.warn(
169 "Nonfatal error. Could not return key to pool", e);
170 }
171 }
172 catch (Exception e)
173 {
174 log.error("", e);
175 }
176 }
177 return result;
178 }
179
180 public Object get(Serializable instanceOrClass, String method,
181 Serializable arg1)
182 {
183 Object result = null;
184 if (jcsCache != null)
185 {
186 try
187 {
188 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
189 key.init(instanceOrClass, method, arg1);
190 result = getImpl(key);
191 try
192 {
193 pool.returnObject(key);
194 }
195 catch (Exception e)
196 {
197 log.warn(
198 "Nonfatal error. Could not return key to pool", e);
199 }
200 }
201 catch (Exception e)
202 {
203 log.error("", e);
204 }
205 }
206 return result;
207 }
208
209 public Object get(Serializable instanceOrClass, String method,
210 Serializable arg1, Serializable arg2)
211 {
212 Object result = null;
213 if (jcsCache != null)
214 {
215 try
216 {
217 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
218 key.init(instanceOrClass, method, arg1, arg2);
219 result = getImpl(key);
220 try
221 {
222 pool.returnObject(key);
223 }
224 catch (Exception e)
225 {
226 log.warn(
227 "Nonfatal error. Could not return key to pool", e);
228 }
229 }
230 catch (Exception e)
231 {
232 log.error("", e);
233 }
234 }
235 return result;
236 }
237
238 public Object get(Serializable instanceOrClass, String method,
239 Serializable arg1, Serializable arg2,
240 Serializable arg3)
241 {
242 Object result = null;
243 if (jcsCache != null)
244 {
245 try
246 {
247 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
248 key.init(instanceOrClass, method, arg1, arg2, arg3);
249 result = getImpl(key);
250 try
251 {
252 pool.returnObject(key);
253 }
254 catch (Exception e)
255 {
256 log.warn(
257 "Nonfatal error. Could not return key to pool", e);
258 }
259 }
260 catch (Exception e)
261 {
262 log.error("", e);
263 }
264 }
265 return result;
266 }
267
268 public Object get(Serializable[] keys)
269 {
270 Object result = null;
271 if (jcsCache != null)
272 {
273 try
274 {
275 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
276 key.init(keys);
277 result = getImpl(key);
278 try
279 {
280 pool.returnObject(key);
281 }
282 catch (Exception e)
283 {
284 log.warn(
285 "Nonfatal error. Could not return key to pool", e);
286 }
287 }
288 catch (Exception e)
289 {
290 log.error("", e);
291 }
292 }
293 return result;
294 }
295
296 public void put(Object value, Serializable instanceOrClass, String method)
297 {
298 try
299 {
300 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
301 key.init(instanceOrClass, method);
302 putImpl(key, value);
303 }
304 catch (Exception e)
305 {
306 log.error("", e);
307 }
308 }
309
310 public void put(Object value, Serializable instanceOrClass,
311 String method, Serializable arg1)
312 {
313 try
314 {
315 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
316 key.init(instanceOrClass, method, arg1);
317 putImpl(key, value);
318 }
319 catch (Exception e)
320 {
321 log.error("", e);
322 }
323 }
324
325 public void put(Object value, Serializable instanceOrClass, String method,
326 Serializable arg1, Serializable arg2)
327 {
328 try
329 {
330 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
331 key.init(instanceOrClass, method, arg1, arg2);
332 putImpl(key, value);
333 }
334 catch (Exception e)
335 {
336 log.error("", e);
337 }
338 }
339
340 public void put(Object value, Serializable instanceOrClass, String method,
341 Serializable arg1, Serializable arg2, Serializable arg3)
342 {
343 try
344 {
345 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
346 key.init(instanceOrClass, method, arg1, arg2, arg3);
347 putImpl(key, value);
348 }
349 catch (Exception e)
350 {
351 log.error("", e);
352 }
353 }
354
355 public void put(Object value, Serializable[] keys)
356 {
357 try
358 {
359 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
360 key.init(keys);
361 putImpl(key, value);
362 }
363 catch (Exception e)
364 {
365 log.error("", e);
366 }
367 }
368
369
370 public void removeAll(Serializable instanceOrClass, String method)
371 {
372 if (jcsCache != null)
373 {
374 try
375 {
376 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
377 key.init(instanceOrClass, method);
378 String groupName = key.getGroupKey();
379 jcsCache.invalidateGroup(groupName);
380 groups.remove(groupName);
381 try
382 {
383 pool.returnObject(key);
384 }
385 catch (Exception e)
386 {
387 log.warn(
388 "Nonfatal error. Could not return key to pool", e);
389 }
390 }
391 catch (Exception e)
392 {
393 log.error("", e);
394 }
395 }
396 }
397
398
399 public Object remove(Serializable instanceOrClass, String method)
400 {
401 Object result = null;
402 if (jcsCache != null)
403 {
404 try
405 {
406 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
407 key.init(instanceOrClass, method);
408 result = removeImpl(key);
409 try
410 {
411 pool.returnObject(key);
412 }
413 catch (Exception e)
414 {
415 log.warn(
416 "Nonfatal error. Could not return key to pool", e);
417 }
418 }
419 catch (Exception e)
420 {
421 log.error("", e);
422 }
423 }
424 return result;
425 }
426
427 public Object remove(Serializable instanceOrClass, String method,
428 Serializable arg1)
429 {
430 Object result = null;
431 if (jcsCache != null)
432 {
433 try
434 {
435 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
436 key.init(instanceOrClass, method, arg1);
437 result = removeImpl(key);
438 try
439 {
440 pool.returnObject(key);
441 }
442 catch (Exception e)
443 {
444 log.warn(
445 "Nonfatal error. Could not return key to pool", e);
446 }
447 }
448 catch (Exception e)
449 {
450 log.error("Error removing element", e);
451 }
452 }
453 return result;
454 }
455
456 public Object remove(Serializable instanceOrClass, String method,
457 Serializable arg1, Serializable arg2)
458 {
459 Object result = null;
460 if (jcsCache != null)
461 {
462 try
463 {
464 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
465 key.init(instanceOrClass, method, arg1, arg2);
466 result = removeImpl(key);
467 try
468 {
469 pool.returnObject(key);
470 }
471 catch (Exception e)
472 {
473 log.warn(
474 "Nonfatal error: Could not return key to pool", e);
475 }
476 }
477 catch (Exception e)
478 {
479 log.error("Error removing element from cache", e);
480 }
481 }
482 return result;
483 }
484
485 public Object remove(Serializable instanceOrClass, String method,
486 Serializable arg1, Serializable arg2,
487 Serializable arg3)
488 {
489 Object result = null;
490 if (jcsCache != null)
491 {
492 try
493 {
494 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
495 key.init(instanceOrClass, method, arg1, arg2, arg3);
496 result = removeImpl(key);
497 try
498 {
499 pool.returnObject(key);
500 }
501 catch (Exception e)
502 {
503 log.warn(
504 "Nonfatal error. Could not return key to pool", e);
505 }
506 }
507 catch (Exception e)
508 {
509 log.error("Error removing element from cache", e);
510 }
511 }
512 return result;
513 }
514
515 public Object remove(Serializable[] keys)
516 {
517 Object result = null;
518 if (jcsCache != null)
519 {
520 try
521 {
522 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
523 key.init(keys);
524 result = removeImpl(key);
525 try
526 {
527 pool.returnObject(key);
528 }
529 catch (Exception e)
530 {
531 log.warn(
532 "Nonfatal error: Could not return key to pool", e);
533 }
534 }
535 catch (Exception e)
536 {
537 log.error("Error removing element from cache", e);
538 }
539 }
540 return result;
541 }
542 }