View Javadoc

1   package org.apache.torque.manager;
2   
3   /*
4    * Copyright 2001-2005 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License")
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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         //register the group, if this is the first occurrence
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 }