View Javadoc

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