View Javadoc

1   package org.apache.torque.manager;
2   
3   /* ====================================================================
4    * The Apache Software License, Version 1.1
5    *
6    * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
7    * reserved.
8    *
9    * Redistribution and use in source and binary forms, with or without
10   * modification, are permitted provided that the following conditions
11   * are met:
12   *
13   * 1. Redistributions of source code must retain the above copyright
14   *    notice, this list of conditions and the following disclaimer.
15   *
16   * 2. Redistributions in binary form must reproduce the above copyright
17   *    notice, this list of conditions and the following disclaimer in
18   *    the documentation and/or other materials provided with the
19   *    distribution.
20   *
21   * 3. The end-user documentation included with the redistribution,
22   *    if any, must include the following acknowledgment:
23   *       "This product includes software developed by the
24   *        Apache Software Foundation (http://www.apache.org/)."
25   *    Alternately, this acknowledgment may appear in the software itself,
26   *    if and wherever such third-party acknowledgments normally appear.
27   *
28   * 4. The names "Apache" and "Apache Software Foundation" and
29   *    "Apache Turbine" must not be used to endorse or promote products
30   *    derived from this software without prior written permission. For
31   *    written permission, please contact apache@apache.org.
32   *
33   * 5. Products derived from this software may not be called "Apache",
34   *    "Apache Turbine", nor may "Apache" appear in their name, without
35   *    prior written permission of the Apache Software Foundation.
36   *
37   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48   * SUCH DAMAGE.
49   * ====================================================================
50   *
51   * This software consists of voluntary contributions made by many
52   * individuals on behalf of the Apache Software Foundation.  For more
53   * information on the Apache Software Foundation, please see
54   * <http://www.apache.org/>.
55   */
56  
57  import java.io.Serializable;
58  import java.util.HashMap;
59  import java.util.Map;
60  
61  import org.apache.commons.pool.ObjectPool;
62  import org.apache.commons.pool.impl.StackObjectPool;
63  
64  import org.apache.jcs.access.GroupCacheAccess;
65  import org.apache.jcs.access.exception.CacheException;
66  
67  import org.apache.commons.logging.Log;
68  import org.apache.commons.logging.LogFactory;
69  
70  import org.apache.torque.TorqueException;
71  
72  /***
73   * This class provides a cache for convenient storage of method
74   * results.
75   *
76   * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
77   * @version $Id: MethodResultCache.java,v 1.19 2003/08/25 16:33:22 henning Exp $
78   */
79  public class MethodResultCache
80  {
81      private ObjectPool pool;
82      private GroupCacheAccess jcsCache;
83      private Map groups;
84  
85      /*** Logging */
86      private static Log log = LogFactory.getLog(MethodResultCache.class);
87  
88      public MethodResultCache(GroupCacheAccess cache)
89          throws TorqueException
90      {
91          this.jcsCache = cache;
92          groups = new HashMap();
93          pool = new StackObjectPool(new MethodCacheKey.Factory(), 10000);
94      }
95  
96      /***
97       * Allows subclasses to have ctors that do not require a cache.
98       * This is used by NullMethodResultCache which has no-op versions
99       * of all methods.
100      */
101     protected MethodResultCache()
102     {
103     }
104 
105     public void clear()
106     {
107         if (jcsCache != null)
108         {
109             try
110             {
111                 jcsCache.remove();
112                 groups.clear();
113             }
114             catch (CacheException ce)
115             {
116                 log.error(new TorqueException(
117                     "Could not clear cache due to internal JCS error.", ce));
118             }
119         }
120     }
121 
122     protected Object getImpl(MethodCacheKey key)
123     {
124         Object result = null;
125         if (jcsCache != null)
126         {
127             synchronized (this)
128             {
129                 result = jcsCache.getFromGroup(key, key.getGroupKey());
130             }
131         }
132 
133         if (result != null)
134         {
135             if (log.isDebugEnabled())
136             {
137                 log.debug("MethodResultCache saved expensive operation: " + key);
138             }
139         }
140         return result;
141     }
142 
143 
144     protected Object putImpl(MethodCacheKey key, Object value)
145         throws TorqueException
146     {
147         //register the group, if this is the first occurrence
148         String group = key.getGroupKey();
149         if (!groups.containsKey(group))
150         {
151             groups.put(group, null);
152         }
153 
154         Object old = null;
155         if (jcsCache != null)
156         {
157             try
158             {
159                 synchronized (this)
160                 {
161                     old = jcsCache.getFromGroup(key, group);
162                     jcsCache.putInGroup(key, group, value);
163                 }
164             }
165             catch (CacheException ce)
166             {
167                 throw new TorqueException
168                     ("Could not cache due to internal JCS error", ce);
169             }
170         }
171         return old;
172     }
173 
174     protected Object removeImpl(MethodCacheKey key)
175         throws TorqueException
176     {
177         Object old = null;
178         if (jcsCache != null)
179         {
180             synchronized (this)
181             {
182                 old = jcsCache.getFromGroup(key, key.getGroupKey());
183                 jcsCache.remove(key, key.getGroupKey());
184             }
185         }
186         return old;
187     }
188 
189 
190     public Object get(Serializable instanceOrClass, String method)
191     {
192         Object result = null;
193         if (jcsCache != null)
194         {
195             try
196             {
197                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
198                 key.init(instanceOrClass, method);
199                 result = getImpl(key);
200                 try
201                 {
202                     pool.returnObject(key);
203                 }
204                 catch (Exception e)
205                 {
206                     log.warn(
207                         "Nonfatal error.  Could not return key to pool", e);
208                 }
209             }
210             catch (Exception e)
211             {
212                 log.error("", e);
213             }
214         }
215         return result;
216     }
217 
218     public Object get(Serializable instanceOrClass, String method,
219                       Serializable arg1)
220     {
221         Object result = null;
222         if (jcsCache != null)
223         {
224             try
225             {
226                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
227                 key.init(instanceOrClass, method, arg1);
228                 result = getImpl(key);
229                 try
230                 {
231                     pool.returnObject(key);
232                 }
233                 catch (Exception e)
234                 {
235                     log.warn(
236                         "Nonfatal error.  Could not return key to pool", e);
237                 }
238             }
239             catch (Exception e)
240             {
241                 log.error("", e);
242             }
243         }
244         return result;
245     }
246 
247     public Object get(Serializable instanceOrClass, String method,
248                       Serializable arg1, Serializable arg2)
249     {
250         Object result = null;
251         if (jcsCache != null)
252         {
253             try
254             {
255                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
256                 key.init(instanceOrClass, method, arg1, arg2);
257                 result = getImpl(key);
258                 try
259                 {
260                     pool.returnObject(key);
261                 }
262                 catch (Exception e)
263                 {
264                     log.warn(
265                         "Nonfatal error.  Could not return key to pool", e);
266                 }
267             }
268             catch (Exception e)
269             {
270                 log.error("", e);
271             }
272         }
273         return result;
274     }
275 
276     public Object get(Serializable instanceOrClass, String method,
277                       Serializable arg1, Serializable arg2,
278                       Serializable arg3)
279     {
280         Object result = null;
281         if (jcsCache != null)
282         {
283             try
284             {
285                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
286                 key.init(instanceOrClass, method, arg1, arg2, arg3);
287                 result = getImpl(key);
288                 try
289                 {
290                     pool.returnObject(key);
291                 }
292                 catch (Exception e)
293                 {
294                     log.warn(
295                         "Nonfatal error.  Could not return key to pool", e);
296                 }
297             }
298             catch (Exception e)
299             {
300                 log.error("", e);
301             }
302         }
303         return result;
304     }
305 
306     public Object get(Serializable[] keys)
307     {
308         Object result = null;
309         if (jcsCache != null)
310         {
311             try
312             {
313                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
314                 key.init(keys);
315                 result = getImpl(key);
316                 try
317                 {
318                     pool.returnObject(key);
319                 }
320                 catch (Exception e)
321                 {
322                     log.warn(
323                         "Nonfatal error.  Could not return key to pool", e);
324                 }
325             }
326             catch (Exception e)
327             {
328                 log.error("", e);
329             }
330         }
331         return result;
332     }
333 
334     public void put(Object value, Serializable instanceOrClass,  String method)
335     {
336         try
337         {
338             MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
339             key.init(instanceOrClass, method);
340             putImpl(key, value);
341         }
342         catch (Exception e)
343         {
344             log.error("", e);
345         }
346     }
347 
348     public void put(Object value, Serializable instanceOrClass,
349                     String method, Serializable arg1)
350     {
351         try
352         {
353             MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
354             key.init(instanceOrClass, method, arg1);
355             putImpl(key, value);
356         }
357         catch (Exception e)
358         {
359             log.error("", e);
360         }
361     }
362 
363     public void put(Object value, Serializable instanceOrClass, String method,
364                     Serializable arg1, Serializable arg2)
365     {
366         try
367         {
368             MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
369             key.init(instanceOrClass, method, arg1, arg2);
370             putImpl(key, value);
371         }
372         catch (Exception e)
373         {
374             log.error("", e);
375         }
376     }
377 
378     public void put(Object value, Serializable instanceOrClass, String method,
379                     Serializable arg1, Serializable arg2, Serializable arg3)
380     {
381         try
382         {
383             MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
384             key.init(instanceOrClass, method, arg1, arg2, arg3);
385             putImpl(key, value);
386         }
387         catch (Exception e)
388         {
389             log.error("", e);
390         }
391     }
392 
393     public void put(Object value, Serializable[] keys)
394     {
395         try
396         {
397             MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
398             key.init(keys);
399             putImpl(key, value);
400         }
401         catch (Exception e)
402         {
403             log.error("", e);
404         }
405     }
406 
407 
408     public void removeAll(Serializable instanceOrClass, String method)
409     {
410         if (jcsCache != null)
411         {
412             try
413             {
414                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
415                 key.init(instanceOrClass, method);
416                 String groupName = key.getGroupKey();
417                 jcsCache.invalidateGroup(groupName);
418                 groups.remove(groupName);
419                 try
420                 {
421                     pool.returnObject(key);
422                 }
423                 catch (Exception e)
424                 {
425                     log.warn(
426                         "Nonfatal error.  Could not return key to pool", e);
427                 }
428             }
429             catch (Exception e)
430             {
431                 log.error("", e);
432             }
433         }
434     }
435 
436 
437     public Object remove(Serializable instanceOrClass, String method)
438     {
439         Object result = null;
440         if (jcsCache != null)
441         {
442             try
443             {
444                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
445                 key.init(instanceOrClass, method);
446                 result = removeImpl(key);
447                 try
448                 {
449                     pool.returnObject(key);
450                 }
451                 catch (Exception e)
452                 {
453                     log.warn(
454                         "Nonfatal error.  Could not return key to pool", e);
455                 }
456             }
457             catch (Exception e)
458             {
459                 log.error("", e);
460             }
461         }
462         return result;
463     }
464 
465     public Object remove(Serializable instanceOrClass, String method,
466                          Serializable arg1)
467     {
468         Object result = null;
469         if (jcsCache != null)
470         {
471             try
472             {
473                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
474                 key.init(instanceOrClass, method, arg1);
475                 result = removeImpl(key);
476                 try
477                 {
478                     pool.returnObject(key);
479                 }
480                 catch (Exception e)
481                 {
482                     log.warn(
483                         "Nonfatal error.  Could not return key to pool", e);
484                 }
485             }
486             catch (Exception e)
487             {
488                 log.error("Error removing element", e);
489             }
490         }
491         return result;
492     }
493 
494     public Object remove(Serializable instanceOrClass, String method,
495                          Serializable arg1, Serializable arg2)
496     {
497         Object result = null;
498         if (jcsCache != null)
499         {
500             try
501             {
502                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
503                 key.init(instanceOrClass, method, arg1, arg2);
504                 result = removeImpl(key);
505                 try
506                 {
507                     pool.returnObject(key);
508                 }
509                 catch (Exception e)
510                 {
511                     log.warn(
512                         "Nonfatal error: Could not return key to pool", e);
513                 }
514             }
515             catch (Exception e)
516             {
517                 log.error("Error removing element from cache", e);
518             }
519         }
520         return result;
521     }
522 
523     public Object remove(Serializable instanceOrClass, String method,
524                          Serializable arg1, Serializable arg2,
525                          Serializable arg3)
526     {
527         Object result = null;
528         if (jcsCache != null)
529         {
530             try
531             {
532                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
533                 key.init(instanceOrClass, method, arg1, arg2, arg3);
534                 result = removeImpl(key);
535                 try
536                 {
537                     pool.returnObject(key);
538                 }
539                 catch (Exception e)
540                 {
541                     log.warn(
542                         "Nonfatal error.  Could not return key to pool", e);
543                 }
544             }
545             catch (Exception e)
546             {
547                 log.error("Error removing element from cache", e);
548             }
549         }
550         return result;
551     }
552 
553     public Object remove(Serializable[] keys)
554     {
555         Object result = null;
556         if (jcsCache != null)
557         {
558             try
559             {
560                 MethodCacheKey key = (MethodCacheKey) pool.borrowObject();
561                 key.init(keys);
562                 result = removeImpl(key);
563                 try
564                 {
565                     pool.returnObject(key);
566                 }
567                 catch (Exception e)
568                 {
569                     log.warn(
570                         "Nonfatal error: Could not return key to pool", e);
571                 }
572             }
573             catch (Exception e)
574             {
575                 log.error("Error removing element from cache", e);
576             }
577         }
578         return result;
579     }
580 }