View Javadoc

1   package org.apache.jcs.engine;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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         // waterfall onto disk, for pure disk set memory to 0
112         IS_SPOOL = attr.IS_SPOOL;
113 
114         // lateral
115         IS_LATERAL = attr.IS_LATERAL;
116 
117         // central rmi store
118         IS_REMOTE = attr.IS_REMOTE;
119 
120         maxLifeSeconds = attr.maxLifeSeconds;
121         // time-to-live
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             // need to make this more efficient. Just want to insure
136             // a proper copy
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             // deserialize byte array into ArrayList
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             // swallow
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         // lazy here, no concurrency problems expected
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 }