1 package org.apache.jcs.engine;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26 import java.io.Serializable;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29
30 import org.apache.jcs.engine.behavior.IElementAttributes;
31 import org.apache.jcs.engine.control.event.behavior.IElementEventHandler;
32
33 /***
34 * This it the element attribute descriptor class. Each element in the cache has an ElementAttribute
35 * object associated with it. An ElementAttributes object can be associated with an element in 3
36 * ways:
37 * <ol>
38 * <li>When the item is put into the cache, you can associate an element attributes object.</li>
39 * <li>If not attributes object is include when the element is put into the cache, then the default
40 * attributes for the region will be used.</li>
41 * <li>The element attributes can be reset. This effectively results in a retrieval followed by a
42 * put. Hence, this is the same as 1.</li>
43 * </ol>
44 */
45 public class ElementAttributes
46 implements IElementAttributes, Serializable, Cloneable
47 {
48 /*** Don't change. */
49 private static final long serialVersionUID = 7814990748035017441L;
50
51 /*** Can this item be flushed to disk */
52 public boolean IS_SPOOL = true;
53
54 /*** Is this item laterally distributable */
55 public boolean IS_LATERAL = true;
56
57 /*** Can this item be sent to the remote cache */
58 public boolean IS_REMOTE = true;
59
60 /***
61 * You can turn off expiration by setting this to true. This causes the cache to bypass both max
62 * life and idle time expiration.
63 */
64 public boolean IS_ETERNAL = true;
65
66 /*** Max life seconds */
67 public long maxLifeSeconds = -1;
68
69 /***
70 * The maximum time an entry can be idle. Setting this to -1 causes the idle time check to be
71 * ignored.
72 */
73 public long maxIdleTimeSeconds = -1;
74
75 /*** The byte size of the field. Must be manually set. */
76 public int size = 0;
77
78 /*** The creation time. This is used to enforce the max life. */
79 public long createTime = 0;
80
81 /*** The last access time. This is used to enforce the max idel time. */
82 public long lastAccessTime = 0;
83
84 /***
85 * The list of Event handlers to use. This is transient, since the event handlers cannot usually
86 * be serialized. This means that you cannot attach a post serialization event to an item.
87 * <p>
88 * TODO we need to check that when an item is passed to a non-local cache that if the local
89 * cache had a copy with event handlers, that those handlers are used.
90 */
91 public transient ArrayList eventHandlers;
92
93 /***
94 * Constructor for the IElementAttributes object
95 */
96 public ElementAttributes()
97 {
98 this.createTime = System.currentTimeMillis();
99 this.lastAccessTime = this.createTime;
100 }
101
102 /***
103 * Constructor for the IElementAttributes object
104 * <p>
105 * @param attr
106 */
107 protected ElementAttributes( ElementAttributes attr )
108 {
109 IS_ETERNAL = attr.IS_ETERNAL;
110
111
112 IS_SPOOL = attr.IS_SPOOL;
113
114
115 IS_LATERAL = attr.IS_LATERAL;
116
117
118 IS_REMOTE = attr.IS_REMOTE;
119
120 maxLifeSeconds = attr.maxLifeSeconds;
121
122 maxIdleTimeSeconds = attr.maxIdleTimeSeconds;
123 size = attr.size;
124 }
125
126 /***
127 * Copies the attributes, including references to event handlers.
128 * <p>
129 * @return a copy of the Attributes
130 */
131 public IElementAttributes copy()
132 {
133 try
134 {
135
136
137 ElementAttributes attr = new ElementAttributes();
138 attr.setIdleTime( this.getIdleTime() );
139 attr.setIsEternal( this.getIsEternal() );
140 attr.setIsLateral( this.getIsLateral() );
141 attr.setIsRemote( this.getIsRemote() );
142 attr.setIsSpool( this.getIsSpool() );
143 attr.setMaxLifeSeconds( this.getMaxLifeSeconds() );
144 attr.addElementEventHandlers( this.eventHandlers );
145 return attr;
146 }
147 catch ( Exception e )
148 {
149 return new ElementAttributes();
150 }
151 }
152
153 /***
154 * Deep clone the attributes.
155 * <p>
156 * @return a clone of these attributes
157 */
158 public Object clone2()
159 {
160 try
161 {
162 ByteArrayOutputStream baos = new ByteArrayOutputStream( 100 );
163 ObjectOutputStream oos = new ObjectOutputStream( baos );
164 oos.writeObject( this );
165 byte buf[] = baos.toByteArray();
166 oos.close();
167
168
169
170 ByteArrayInputStream bais = new ByteArrayInputStream( buf );
171 ObjectInputStream ois = new ObjectInputStream( bais );
172 ElementAttributes attr = (ElementAttributes) ois.readObject();
173 ois.close();
174
175 attr.createTime = System.currentTimeMillis();
176 return attr;
177 }
178 catch ( Exception e )
179 {
180
181 }
182 return null;
183 }
184
185 /***
186 * Sets the maxLife attribute of the IAttributes object.
187 * <p>
188 * @param mls The new MaxLifeSeconds value
189 */
190 public void setMaxLifeSeconds( long mls )
191 {
192 this.maxLifeSeconds = mls;
193 }
194
195 /***
196 * Sets the maxLife attribute of the IAttributes object. How many seconds it can live after
197 * creation.
198 * <p>
199 * If this is exceeded the element will not be returned, instead it will be removed. It will be
200 * removed on retrieval, or removed actively if the memory shrinker is turned on.
201 * @return The MaxLifeSeconds value
202 */
203 public long getMaxLifeSeconds()
204 {
205 return this.maxLifeSeconds;
206 }
207
208 /***
209 * Sets the idleTime attribute of the IAttributes object. This is the maximum time the item can
210 * be idle in the cache, that is not accessed.
211 * <p>
212 * If this is exceeded the element will not be returned, instead it will be removed. It will be
213 * removed on retrieval, or removed actively if the memory shrinker is turned on.
214 * @param idle The new idleTime value
215 */
216 public void setIdleTime( long idle )
217 {
218 this.maxIdleTimeSeconds = idle;
219 }
220
221 /***
222 * Size in bytes. This is not used except in the admin pages. It will be -1 by default.
223 * <p>
224 * @param size The new size value
225 */
226 public void setSize( int size )
227 {
228 this.size = size;
229 }
230
231 /***
232 * Gets the size attribute of the IAttributes object
233 * <p>
234 * @return The size value
235 */
236 public int getSize()
237 {
238 return size;
239 }
240
241 /***
242 * Gets the createTime attribute of the IAttributes object.
243 * <p>
244 * This should be the current time in milliseconds returned by the sysutem call when the element
245 * is put in the cache.
246 * <p>
247 * Putting an item in the cache overrides any existing items.
248 * @return The createTime value
249 */
250 public long getCreateTime()
251 {
252 return createTime;
253 }
254
255 /***
256 * Sets the createTime attribute of the IElementAttributes object
257 */
258 public void setCreateTime()
259 {
260 createTime = System.currentTimeMillis();
261 }
262
263 /***
264 * Gets the idleTime attribute of the IAttributes object.
265 * <p>
266 * @return The idleTime value
267 */
268 public long getIdleTime()
269 {
270 return this.maxIdleTimeSeconds;
271 }
272
273 /***
274 * Gets the time left to live of the IAttributes object.
275 * <p>
276 * This is the (max life + create time) - current time.
277 * @return The TimeToLiveSeconds value
278 */
279 public long getTimeToLiveSeconds()
280 {
281 long now = System.currentTimeMillis();
282 return ( ( this.getCreateTime() + ( this.getMaxLifeSeconds() * 1000 ) ) - now ) / 1000;
283 }
284
285 /***
286 * Gets the LastAccess attribute of the IAttributes object.
287 * <p>
288 * @return The LastAccess value.
289 */
290 public long getLastAccessTime()
291 {
292 return this.lastAccessTime;
293 }
294
295 /***
296 * Sets the LastAccessTime as now of the IElementAttributes object
297 */
298 public void setLastAccessTimeNow()
299 {
300 this.lastAccessTime = System.currentTimeMillis();
301 }
302
303 /***
304 * Can this item be spooled to disk
305 * <p>
306 * By default this is true.
307 * @return The spoolable value
308 */
309 public boolean getIsSpool()
310 {
311 return this.IS_SPOOL;
312 }
313
314 /***
315 * Sets the isSpool attribute of the IElementAttributes object
316 * <p>
317 * By default this is true.
318 * @param val The new isSpool value
319 */
320 public void setIsSpool( boolean val )
321 {
322 this.IS_SPOOL = val;
323 }
324
325 /***
326 * Is this item laterally distributable. Can it be sent to auxiliaries of type lateral.
327 * <p>
328 * By default this is true.
329 * @return The isLateral value
330 */
331 public boolean getIsLateral()
332 {
333 return this.IS_LATERAL;
334 }
335
336 /***
337 * Sets the isLateral attribute of the IElementAttributes object
338 * <p>
339 * By default this is true.
340 * @param val The new isLateral value
341 */
342 public void setIsLateral( boolean val )
343 {
344 this.IS_LATERAL = val;
345 }
346
347 /***
348 * Can this item be sent to the remote cache
349 * @return true if the item can be sent to a remote auxiliary
350 */
351 public boolean getIsRemote()
352 {
353 return this.IS_REMOTE;
354 }
355
356 /***
357 * Sets the isRemote attribute of the ElementAttributes object
358 * @param val The new isRemote value
359 */
360 public void setIsRemote( boolean val )
361 {
362 this.IS_REMOTE = val;
363 }
364
365 /***
366 * You can turn off expiration by setting this to true. The max life value will be ignored.
367 * <p>
368 * @return true if the item cannot expire.
369 */
370 public boolean getIsEternal()
371 {
372 return this.IS_ETERNAL;
373 }
374
375 /***
376 * Sets the isEternal attribute of the ElementAttributes object. True means that the item should
377 * never expire. If can still be removed if it is the least recently used, and you are using the
378 * LRUMemory cache. it just will not be filtered for expiration by the cache hub.
379 * <p>
380 * @param val The new isEternal value
381 */
382 public void setIsEternal( boolean val )
383 {
384 this.IS_ETERNAL = val;
385 }
386
387 /***
388 * Adds a ElementEventHandler. Handler's can be registered for multiple events. A registered
389 * handler will be called at every recognized event.
390 * <p>
391 * The alternative would be to register handlers for each event. Or maybe The handler interface
392 * should have a method to return whether it cares about certain events.
393 * <p>
394 * @param eventHandler The ElementEventHandler to be added to the list.
395 */
396 public void addElementEventHandler( IElementEventHandler eventHandler )
397 {
398
399 if ( this.eventHandlers == null )
400 {
401 this.eventHandlers = new ArrayList();
402 }
403 this.eventHandlers.add( eventHandler );
404 }
405
406 /***
407 * Sets the eventHandlers of the IElementAttributes object.
408 * <p>
409 * This add the references to the local list. Subsequent changes in the caller's list will not
410 * be reflected.
411 * <p>
412 * @param eventHandlers List of IElementEventHandler objects
413 */
414 public void addElementEventHandlers( ArrayList eventHandlers )
415 {
416 if ( eventHandlers == null )
417 {
418 return;
419 }
420
421 for ( Iterator iter = eventHandlers.iterator(); iter.hasNext(); )
422 {
423 addElementEventHandler( (IElementEventHandler) iter.next() );
424 }
425 }
426
427 /***
428 * Gets the elementEventHandlers. Returns null if none exist. Makes checking easy.
429 * <p>
430 * @return The elementEventHandlers List of IElementEventHandler objects
431 */
432 public ArrayList getElementEventHandlers()
433 {
434 return this.eventHandlers;
435 }
436
437 /***
438 * For logging and debugging the element IElementAttributes.
439 * <p>
440 * @return String info about the values.
441 */
442 public String toString()
443 {
444 StringBuffer dump = new StringBuffer();
445
446 dump.append( "[ IS_LATERAL = " ).append( IS_LATERAL );
447 dump.append( ", IS_SPOOL = " ).append( IS_SPOOL );
448 dump.append( ", IS_REMOTE = " ).append( IS_REMOTE );
449 dump.append( ", IS_ETERNAL = " ).append( IS_ETERNAL );
450 dump.append( ", MaxLifeSeconds = " ).append( this.getMaxLifeSeconds() );
451 dump.append( ", IdleTime = " ).append( this.getIdleTime() );
452 dump.append( ", CreateTime = " ).append( this.getCreateTime() );
453 dump.append( ", LastAccessTime = " ).append( this.getLastAccessTime() );
454 dump.append( ", getTimeToLiveSeconds() = " ).append( String.valueOf( getTimeToLiveSeconds() ) );
455 dump.append( ", createTime = " ).append( String.valueOf( createTime ) ).append( " ]" );
456
457 return dump.toString();
458 }
459 }