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