Clover coverage report - Coverage timestamp: Sa Jul 7 2007 09:11:40 CEST FRAMES NO FRAMES |
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% |

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 |  | }