Clover coverage report -
Coverage timestamp: Sa Jul 7 2007 09:11:40 CEST
file stats: LOC: 311   Methods: 16
NCLOC: 113   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
CacheEntry.java 58,3% 68% 81,2% 67,8%
coverage coverage
 1    /*
 2    * Copyright (c) 2002-2003 by OpenSymphony
 3    * All rights reserved.
 4    */
 5    package com.opensymphony.oscache.base;
 6   
 7    import com.opensymphony.oscache.web.filter.ResponseContent;
 8   
 9    import java.io.Serializable;
 10   
 11    import java.util.Collection;
 12    import java.util.HashSet;
 13    import java.util.Set;
 14   
 15    /**
 16    * A CacheEntry instance represents one entry in the cache. It holds the object that
 17    * is being cached, along with a host of information about that entry such as the
 18    * cache key, the time it was cached, whether the entry has been flushed or not and
 19    * the groups it belongs to.
 20    *
 21    * @version $Revision: 388 $
 22    * @author <a href="mailto:mike@atlassian.com">Mike Cannon-Brookes</a>
 23    * @author <a href="mailto:tgochenour@peregrine.com">Todd Gochenour</a>
 24    * @author <a href="mailto:fbeauregard@pyxis-tech.com">Francois Beauregard</a>
 25    */
 26    public class CacheEntry implements Serializable {
 27    /**
 28    * Default initialization value for the creation time and the last
 29    * update time. This is a placeholder that indicates the value has
 30    * not been set yet.
 31    */
 32    private static final byte NOT_YET = -1;
 33   
 34    /**
 35    * Specifying this as the refresh period for the
 36    * {@link #needsRefresh(int)} method will ensure
 37    * an entry does not become stale until it is
 38    * either explicitly flushed or a custom refresh
 39    * policy causes the entry to expire.
 40    */
 41    public static final int INDEFINITE_EXPIRY = -1;
 42   
 43    /**
 44    * The entry refresh policy object to use for this cache entry. This is optional.
 45    */
 46    private EntryRefreshPolicy policy = null;
 47   
 48    /**
 49    * The actual content that is being cached. Wherever possible this object
 50    * should be serializable. This allows <code>PersistenceListener</code>s
 51    * to serialize the cache entries to disk or database.
 52    */
 53    private Object content = null;
 54   
 55    /**
 56    * The set of cache groups that this cache entry belongs to, if any.
 57    */
 58    private Set groups = null;
 59   
 60    /**
 61    * The unique cache key for this entry
 62    */
 63    private String key;
 64   
 65    /**
 66    * <code>true</code> if this entry was flushed
 67    */
 68    private boolean wasFlushed = false;
 69   
 70    /**
 71    * The time this entry was created.
 72    */
 73    private long created = NOT_YET;
 74   
 75    /**
 76    * The time this emtry was last updated.
 77    */
 78    private long lastUpdate = NOT_YET;
 79   
 80    /**
 81    * Construct a new CacheEntry using the key provided.
 82    *
 83    * @param key The key of this CacheEntry
 84    */
 85  90 public CacheEntry(String key) {
 86  90 this(key, null);
 87    }
 88   
 89    /**
 90    * Construct a CacheEntry.
 91    *
 92    * @param key The unique key for this <code>CacheEntry</code>.
 93    * @param policy Object that implements refresh policy logic. This parameter
 94    * is optional.
 95    */
 96  125667 public CacheEntry(String key, EntryRefreshPolicy policy) {
 97  125667 this(key, policy, null);
 98    }
 99   
 100    /**
 101    * Construct a CacheEntry.
 102    *
 103    * @param key The unique key for this <code>CacheEntry</code>.
 104    * @param policy The object that implements the refresh policy logic. This
 105    * parameter is optional.
 106    * @param groups The groups that this <code>CacheEntry</code> belongs to. This
 107    * parameter is optional.
 108    */
 109  125667 public CacheEntry(String key, EntryRefreshPolicy policy, String[] groups) {
 110  125667 this.key = key;
 111   
 112  125667 if (groups != null) {
 113  0 this.groups = new HashSet(groups.length);
 114   
 115  0 for (int i = 0; i < groups.length; i++) {
 116  0 this.groups.add(groups[i]);
 117    }
 118    }
 119   
 120  125667 this.policy = policy;
 121  125667 this.created = System.currentTimeMillis();
 122    }
 123   
 124    /**
 125    * Sets the actual content that is being cached. Wherever possible this
 126    * object should be <code>Serializable</code>, however it is not an
 127    * absolute requirement when using a memory-only cache. Being <code>Serializable</code>
 128    * allows <code>PersistenceListener</code>s to serialize the cache entries to disk
 129    * or database.
 130    *
 131    * @param value The content to store in this CacheEntry.
 132    */
 133  65545 public synchronized void setContent(Object value) {
 134  65545 content = value;
 135  65545 lastUpdate = System.currentTimeMillis();
 136  65545 wasFlushed = false;
 137    }
 138   
 139    /**
 140    * Get the cached content from this CacheEntry.
 141    *
 142    * @return The content of this CacheEntry.
 143    */
 144  4572146 public Object getContent() {
 145  4574169 return content;
 146    }
 147   
 148    /**
 149    * Get the date this CacheEntry was created.
 150    *
 151    * @return The date this CacheEntry was created.
 152    */
 153  45 public long getCreated() {
 154  45 return created;
 155    }
 156   
 157    /**
 158    * Sets the cache groups for this entry.
 159    *
 160    * @param groups A string array containing all the group names
 161    */
 162  65445 public synchronized void setGroups(String[] groups) {
 163  65445 if (groups != null) {
 164  145 this.groups = new HashSet(groups.length);
 165   
 166  145 for (int i = 0; i < groups.length; i++) {
 167  205 this.groups.add(groups[i]);
 168    }
 169    } else {
 170  65300 this.groups = null;
 171    }
 172   
 173  65445 lastUpdate = System.currentTimeMillis();
 174    }
 175   
 176    /**
 177    * Sets the cache groups for this entry
 178    *
 179    * @param groups A collection containing all the group names
 180    */
 181  0 public synchronized void setGroups(Collection groups) {
 182  0 if (groups != null) {
 183  0 this.groups = new HashSet(groups);
 184    } else {
 185  0 this.groups = null;
 186    }
 187   
 188  0 lastUpdate = System.currentTimeMillis();
 189    }
 190   
 191    /**
 192    * Gets the cache groups that this cache entry belongs to.
 193    * These returned groups should be treated as immuatable.
 194    *
 195    * @return A set containing the names of all the groups that
 196    * this cache entry belongs to.
 197    */
 198  79946 public Set getGroups() {
 199  79946 return groups;
 200    }
 201   
 202    /**
 203    * Get the key of this CacheEntry
 204    *
 205    * @return The key of this CacheEntry
 206    */
 207  9699 public String getKey() {
 208  9699 return key;
 209    }
 210   
 211    /**
 212    * Set the date this CacheEntry was last updated.
 213    *
 214    * @param update The time (in milliseconds) this CacheEntry was last updated.
 215    */
 216  0 public void setLastUpdate(long update) {
 217  0 lastUpdate = update;
 218    }
 219   
 220    /**
 221    * Get the date this CacheEntry was last updated.
 222    *
 223    * @return The date this CacheEntry was last updated.
 224    */
 225  15 public long getLastUpdate() {
 226  15 return lastUpdate;
 227    }
 228   
 229    /**
 230    * Indicates whether this CacheEntry is a freshly created one and
 231    * has not yet been assigned content or placed in a cache.
 232    *
 233    * @return <code>true</code> if this entry is newly created
 234    */
 235  4668387 public boolean isNew() {
 236  4668387 return lastUpdate == NOT_YET;
 237    }
 238   
 239    /**
 240    * Get the size of the cache entry in bytes (roughly).<p>
 241    *
 242    * Currently this method only handles <code>String<code>s and
 243    * {@link ResponseContent} objects.
 244    *
 245    * @return The approximate size of the entry in bytes, or -1 if the
 246    * size could not be estimated.
 247    */
 248  0 public int getSize() {
 249    // a char is two bytes
 250  0 int size = (key.length() * 2) + 4;
 251   
 252  0 if (content.getClass() == String.class) {
 253  0 size += ((content.toString().length() * 2) + 4);
 254  0 } else if (content instanceof ResponseContent) {
 255  0 size += ((ResponseContent) content).getSize();
 256    } else {
 257  0 return -1;
 258    }
 259   
 260    //add created, lastUpdate, and wasFlushed field sizes (1, 8, and 8)
 261  0 return size + 17;
 262    }
 263   
 264    /**
 265    * Flush the entry from cache.
 266    * note that flushing the cache doesn't actually remove the cache contents
 267    * it just tells the CacheEntry that it needs a refresh next time it is asked
 268    * this is so that the content is still there for a <usecached />.
 269    */
 270  89 public void flush() {
 271  89 wasFlushed = true;
 272    }
 273   
 274    /**
 275    * Check if this CacheEntry needs to be refreshed.
 276    *
 277    * @param refreshPeriod The period of refresh (in seconds). Passing in
 278    * {@link #INDEFINITE_EXPIRY} will result in the content never becoming
 279    * stale unless it is explicitly flushed, or expired by a custom
 280    * {@link EntryRefreshPolicy}. Passing in 0 will always result in a
 281    * refresh being required.
 282    *
 283    * @return Whether or not this CacheEntry needs refreshing.
 284    */
 285  4565721 public boolean needsRefresh(int refreshPeriod) {
 286  4565721 boolean needsRefresh;
 287   
 288    // needs a refresh if it has never been updated
 289  4565098 if (lastUpdate == NOT_YET) {
 290  60087 needsRefresh = true;
 291    }
 292    // Was it flushed from cache?
 293  4505005 else if (wasFlushed) {
 294  117 needsRefresh = true;
 295  4504197 } else if (refreshPeriod == 0) {
 296  4503948 needsRefresh = true;
 297    }
 298    // check what the policy has to say if there is one
 299  392 else if (policy != null) {
 300  10 needsRefresh = policy.needsRefresh(this);
 301    }
 302    // check if the last update + update period is in the past
 303  382 else if ((refreshPeriod >= 0) && (System.currentTimeMillis() >= (lastUpdate + (refreshPeriod * 1000L)))) {
 304  0 needsRefresh = true;
 305    } else {
 306  382 needsRefresh = false;
 307    }
 308   
 309  4565721 return needsRefresh;
 310    }
 311    }