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.IOException;
25  import java.io.ObjectInputStream;
26  import java.io.ObjectOutputStream;
27  import java.io.Serializable;
28  import java.util.ArrayList;
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<IElementEventHandler> 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 ( IOException e )
179         {
180             // swallow
181         }
182         catch (ClassNotFoundException e)
183         {
184             // swallow
185         }
186         return null;
187     }
188 
189     /**
190      * Sets the maxLife attribute of the IAttributes object.
191      * <p>
192      * @param mls The new MaxLifeSeconds value
193      */
194     public void setMaxLifeSeconds( long mls )
195     {
196         this.maxLifeSeconds = mls;
197     }
198 
199     /**
200      * Sets the maxLife attribute of the IAttributes object. How many seconds it can live after
201      * creation.
202      * <p>
203      * If this is exceeded the element will not be returned, instead it will be removed. It will be
204      * removed on retrieval, or removed actively if the memory shrinker is turned on.
205      * @return The MaxLifeSeconds value
206      */
207     public long getMaxLifeSeconds()
208     {
209         return this.maxLifeSeconds;
210     }
211 
212     /**
213      * Sets the idleTime attribute of the IAttributes object. This is the maximum time the item can
214      * be idle in the cache, that is not accessed.
215      * <p>
216      * If this is exceeded the element will not be returned, instead it will be removed. It will be
217      * removed on retrieval, or removed actively if the memory shrinker is turned on.
218      * @param idle The new idleTime value
219      */
220     public void setIdleTime( long idle )
221     {
222         this.maxIdleTimeSeconds = idle;
223     }
224 
225     /**
226      * Size in bytes. This is not used except in the admin pages. It will be -1 by default.
227      * <p>
228      * @param size The new size value
229      */
230     public void setSize( int size )
231     {
232         this.size = size;
233     }
234 
235     /**
236      * Gets the size attribute of the IAttributes object
237      * <p>
238      * @return The size value
239      */
240     public int getSize()
241     {
242         return size;
243     }
244 
245     /**
246      * Gets the createTime attribute of the IAttributes object.
247      * <p>
248      * This should be the current time in milliseconds returned by the sysutem call when the element
249      * is put in the cache.
250      * <p>
251      * Putting an item in the cache overrides any existing items.
252      * @return The createTime value
253      */
254     public long getCreateTime()
255     {
256         return createTime;
257     }
258 
259     /**
260      * Sets the createTime attribute of the IElementAttributes object
261      */
262     public void setCreateTime()
263     {
264         createTime = System.currentTimeMillis();
265     }
266 
267     /**
268      * Gets the idleTime attribute of the IAttributes object.
269      * <p>
270      * @return The idleTime value
271      */
272     public long getIdleTime()
273     {
274         return this.maxIdleTimeSeconds;
275     }
276 
277     /**
278      * Gets the time left to live of the IAttributes object.
279      * <p>
280      * This is the (max life + create time) - current time.
281      * @return The TimeToLiveSeconds value
282      */
283     public long getTimeToLiveSeconds()
284     {
285         long now = System.currentTimeMillis();
286         return ( ( this.getCreateTime() + ( this.getMaxLifeSeconds() * 1000 ) ) - now ) / 1000;
287     }
288 
289     /**
290      * Gets the LastAccess attribute of the IAttributes object.
291      * <p>
292      * @return The LastAccess value.
293      */
294     public long getLastAccessTime()
295     {
296         return this.lastAccessTime;
297     }
298 
299     /**
300      * Sets the LastAccessTime as now of the IElementAttributes object
301      */
302     public void setLastAccessTimeNow()
303     {
304         this.lastAccessTime = System.currentTimeMillis();
305     }
306 
307     /**
308      * Can this item be spooled to disk
309      * <p>
310      * By default this is true.
311      * @return The spoolable value
312      */
313     public boolean getIsSpool()
314     {
315         return this.IS_SPOOL;
316     }
317 
318     /**
319      * Sets the isSpool attribute of the IElementAttributes object
320      * <p>
321      * By default this is true.
322      * @param val The new isSpool value
323      */
324     public void setIsSpool( boolean val )
325     {
326         this.IS_SPOOL = val;
327     }
328 
329     /**
330      * Is this item laterally distributable. Can it be sent to auxiliaries of type lateral.
331      * <p>
332      * By default this is true.
333      * @return The isLateral value
334      */
335     public boolean getIsLateral()
336     {
337         return this.IS_LATERAL;
338     }
339 
340     /**
341      * Sets the isLateral attribute of the IElementAttributes object
342      * <p>
343      * By default this is true.
344      * @param val The new isLateral value
345      */
346     public void setIsLateral( boolean val )
347     {
348         this.IS_LATERAL = val;
349     }
350 
351     /**
352      * Can this item be sent to the remote cache
353      * @return true if the item can be sent to a remote auxiliary
354      */
355     public boolean getIsRemote()
356     {
357         return this.IS_REMOTE;
358     }
359 
360     /**
361      * Sets the isRemote attribute of the ElementAttributes object
362      * @param val The new isRemote value
363      */
364     public void setIsRemote( boolean val )
365     {
366         this.IS_REMOTE = val;
367     }
368 
369     /**
370      * You can turn off expiration by setting this to true. The max life value will be ignored.
371      * <p>
372      * @return true if the item cannot expire.
373      */
374     public boolean getIsEternal()
375     {
376         return this.IS_ETERNAL;
377     }
378 
379     /**
380      * Sets the isEternal attribute of the ElementAttributes object. True means that the item should
381      * never expire. If can still be removed if it is the least recently used, and you are using the
382      * LRUMemory cache. it just will not be filtered for expiration by the cache hub.
383      * <p>
384      * @param val The new isEternal value
385      */
386     public void setIsEternal( boolean val )
387     {
388         this.IS_ETERNAL = val;
389     }
390 
391     /**
392      * Adds a ElementEventHandler. Handler's can be registered for multiple events. A registered
393      * handler will be called at every recognized event.
394      * <p>
395      * The alternative would be to register handlers for each event. Or maybe The handler interface
396      * should have a method to return whether it cares about certain events.
397      * <p>
398      * @param eventHandler The ElementEventHandler to be added to the list.
399      */
400     public void addElementEventHandler( IElementEventHandler eventHandler )
401     {
402         // lazy here, no concurrency problems expected
403         if ( this.eventHandlers == null )
404         {
405             this.eventHandlers = new ArrayList<IElementEventHandler>();
406         }
407         this.eventHandlers.add( eventHandler );
408     }
409 
410     /**
411      * Sets the eventHandlers of the IElementAttributes object.
412      * <p>
413      * This add the references to the local list. Subsequent changes in the caller's list will not
414      * be reflected.
415      * <p>
416      * @param eventHandlers List of IElementEventHandler objects
417      */
418     public void addElementEventHandlers( ArrayList<IElementEventHandler> eventHandlers )
419     {
420         if ( eventHandlers == null )
421         {
422             return;
423         }
424 
425         for (IElementEventHandler handler : eventHandlers)
426         {
427             addElementEventHandler(handler);
428         }
429     }
430 
431     /**
432      * Gets the elementEventHandlers. Returns null if none exist. Makes checking easy.
433      * <p>
434      * @return The elementEventHandlers List of IElementEventHandler objects
435      */
436     public ArrayList<IElementEventHandler> getElementEventHandlers()
437     {
438         return this.eventHandlers;
439     }
440 
441     /**
442      * For logging and debugging the element IElementAttributes.
443      * <p>
444      * @return String info about the values.
445      */
446     @Override
447     public String toString()
448     {
449         StringBuffer dump = new StringBuffer();
450 
451         dump.append( "[ IS_LATERAL = " ).append( IS_LATERAL );
452         dump.append( ", IS_SPOOL = " ).append( IS_SPOOL );
453         dump.append( ", IS_REMOTE = " ).append( IS_REMOTE );
454         dump.append( ", IS_ETERNAL = " ).append( IS_ETERNAL );
455         dump.append( ", MaxLifeSeconds = " ).append( this.getMaxLifeSeconds() );
456         dump.append( ", IdleTime = " ).append( this.getIdleTime() );
457         dump.append( ", CreateTime = " ).append( this.getCreateTime() );
458         dump.append( ", LastAccessTime = " ).append( this.getLastAccessTime() );
459         dump.append( ", getTimeToLiveSeconds() = " ).append( String.valueOf( getTimeToLiveSeconds() ) );
460         dump.append( ", createTime = " ).append( String.valueOf( createTime ) ).append( " ]" );
461 
462         return dump.toString();
463     }
464 }