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 }