Coverage Report - org.apache.ojb.broker.cache.ObjectCacheLocalDefaultImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
ObjectCacheLocalDefaultImpl
N/A
N/A
2.125
ObjectCacheLocalDefaultImpl$CacheEntry
N/A
N/A
2.125
 
 1  
 package org.apache.ojb.broker.cache;
 2  
 
 3  
 /* Copyright 2003-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 
 18  
 import org.apache.commons.lang.builder.ToStringBuilder;
 19  
 import org.apache.commons.lang.builder.ToStringStyle;
 20  
 import org.apache.ojb.broker.Identity;
 21  
 import org.apache.ojb.broker.PersistenceBroker;
 22  
 
 23  
 import java.lang.ref.SoftReference;
 24  
 import java.util.HashMap;
 25  
 import java.util.Map;
 26  
 import java.util.Properties;
 27  
 
 28  
 /**
 29  
  * Simple, flexible local {@link ObjectCache} implementation using a
 30  
  * {@link java.util.HashMap} to cache given objects.
 31  
  * <p>
 32  
  * The cache uses soft-references which allows objects (softly) referenced by
 33  
  * the cache to be reclaimed by the Java Garbage Collector when they are not
 34  
  * longer referenced elsewhere.
 35  
  * </p>
 36  
  * <p>
 37  
  * NOTE: Handle with care! If multiple PB instances are used (OJB standard behavior) you
 38  
  * will run into synchronization problems.
 39  
  * </p>
 40  
  * <p>
 41  
  * Implementation configuration properties:
 42  
  * </p>
 43  
  *
 44  
  * <table cellspacing="2" cellpadding="2" border="3" frame="box">
 45  
  * <tr>
 46  
  *     <td><strong>Property Key</strong></td>
 47  
  *     <td><strong>Property Values</strong></td>
 48  
  * </tr>
 49  
  * <tr>
 50  
  *     <td>timeout</td>
 51  
  *     <td>
 52  
  *          Lifetime of the cached objects in seconds.
 53  
  *          If expired the cached object was not returned
 54  
  *          on lookup call (and removed from cache).
 55  
  *    </td>
 56  
  * </tr>
 57  
  * </table>
 58  
  *
 59  
  * <br/>
 60  
  *
 61  
  * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
 62  
  * @author <a href="mailto:armin@codeAuLait.de">Armin Waibel</a>
 63  
  * @version $Id: ObjectCacheLocalDefaultImpl.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
 64  
  */
 65  
 public class ObjectCacheLocalDefaultImpl implements ObjectCache
 66  
 {
 67  
     private static final String TIMEOUT = "timeout";
 68  
 
 69  
     /**
 70  
      * the hashtable holding all cached object
 71  
      */
 72  
     protected Map objectTable = new HashMap();
 73  
 
 74  
     /**
 75  
      * Timeout of the cached objects.
 76  
      */
 77  
     private long timeout = 1000 * 60 * 15;
 78  
 
 79  
     /**
 80  
      *
 81  
      */
 82  
     public ObjectCacheLocalDefaultImpl(PersistenceBroker broker, Properties prop)
 83  
     {
 84  
         timeout = prop == null ? timeout : ( Long.parseLong( prop.getProperty( TIMEOUT, "" + timeout ) ) )*1000;
 85  
     }
 86  
 
 87  
     /**
 88  
      * Clear ObjectCache. I.e. remove all entries for classes and objects.
 89  
      */
 90  
     public void clear()
 91  
     {
 92  
         objectTable.clear();
 93  
     }
 94  
 
 95  
     /**
 96  
      * Makes object persistent to the Objectcache.
 97  
      * I'm using soft-references to allow gc reclaim unused objects
 98  
      * even if they are still cached.
 99  
      */
 100  
     public void cache(Identity oid, Object obj)
 101  
     {
 102  
         if ((obj != null))
 103  
         {
 104  
             SoftReference ref = new SoftReference(new CacheEntry(obj));
 105  
             objectTable.put(oid, ref);
 106  
         }
 107  
     }
 108  
 
 109  
     public boolean cacheIfNew(Identity oid, Object obj)
 110  
     {
 111  
         if(objectTable.get(oid) == null)
 112  
         {
 113  
             cache(oid, obj);
 114  
             return true;
 115  
         }
 116  
         return false;
 117  
     }
 118  
 
 119  
     /**
 120  
      * Lookup object with Identity oid in objectTable.
 121  
      * Returns null if no matching id is found
 122  
      */
 123  
     public Object lookup(Identity oid)
 124  
     {
 125  
         CacheEntry entry = null;
 126  
         SoftReference ref = (SoftReference) objectTable.get(oid);
 127  
         if (ref != null)
 128  
         {
 129  
             entry = (CacheEntry) ref.get();
 130  
             if (entry == null || entry.lifetime < System.currentTimeMillis())
 131  
             {
 132  
                 objectTable.remove(oid);    // Soft-referenced Object reclaimed by GC
 133  
                 // timeout, so set null
 134  
                 entry = null;
 135  
             }
 136  
         }
 137  
         return entry != null ? entry.object : null;
 138  
     }
 139  
 
 140  
     /**
 141  
      * Removes an Object from the cache.
 142  
      */
 143  
     public void remove(Identity oid)
 144  
     {
 145  
         if (oid != null)
 146  
         {
 147  
             objectTable.remove(oid);
 148  
         }
 149  
     }
 150  
 
 151  
     public String toString()
 152  
     {
 153  
         ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE);
 154  
         buf.append("Count of cached objects", objectTable.keySet().size());
 155  
         return buf.toString();
 156  
     }
 157  
 
 158  
     //-----------------------------------------------------------
 159  
     // inner class
 160  
     //-----------------------------------------------------------
 161  
     class CacheEntry
 162  
     {
 163  
         long lifetime;
 164  
         Object object;
 165  
 
 166  
         public CacheEntry(Object object)
 167  
         {
 168  
             this.object = object;
 169  
             lifetime = System.currentTimeMillis() + timeout;
 170  
         }
 171  
     }
 172  
 
 173  
 }