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