View Javadoc
1   package org.apache.fulcrum.cache;
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  /**
23   * The idea of the RefreshableCachedObject is that, rather than removing items
24   * from the cache when they become stale, we'll tell them to refresh themselves
25   * instead. That way they'll always be in the cache, and the code to refresh
26   * them will be run by the background thread rather than by a user request
27   * thread. You can also set a TTL (Time To Live) for the object. This way, if
28   * the object hasn't been touched for the TTL period, then it will be removed
29   * from the cache.
30   *
31   * This extends CachedObject and provides a method for refreshing the cached
32   * object, and resetting its expire time.
33   *
34   * @author <a href="mailto:nissim@nksystems.com">Nissim Karpenstein</a>
35   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
36   * @version $Id$
37   */
38  public class RefreshableCachedObject<T extends Refreshable> extends CachedObject<T>
39  {
40  
41      /**
42       * Serialization key
43       */
44      private static final long serialVersionUID = 4072572956381768087L;
45  
46      /**
47       * How long to wait before removing an untouched object from the cache.
48       * Negative numbers mean never remove (the default).
49       * 
50       * time to live in millisec, getter/setter ({@link #getTTL()}
51       * 
52       */
53      private long timeToLive = -1;
54  
55      /**
56       * The last time the Object was accessed from the cache.
57       */
58      private long lastAccess;
59  
60      /**
61       * Constructor; sets the object to expire in the default time (30 minutes).
62       *
63       * @param object
64       *            The object you want to cache.
65       */
66      public RefreshableCachedObject(final T object)
67      {
68          super(object);
69          setLastAccess(System.currentTimeMillis());
70      }
71  
72      /**
73       * Constructor.
74       *
75       * @param object
76       *            The object to cache.
77       * @param expires
78       *            How long before the object expires, in ms, e.g. 1000 = 1
79       *            second.
80       */
81      public RefreshableCachedObject(final T object, final long expires)
82      {
83          super(object, expires);
84          setLastAccess(System.currentTimeMillis());
85      }
86  
87      /**
88       * Sets the timeToLive value
89       *
90       * @param timeToLive
91       *            the new Value in milliseconds
92       */
93      public void setTTL(final long timeToLive)
94      {
95          synchronized(this) {
96              this.timeToLive = timeToLive;
97          }
98      }
99  
100     /**
101      * Gets the timeToLive value.
102      *
103      * @return The current timeToLive value (in milliseconds)
104      */
105     public long getTTL()
106     {
107         synchronized(this) {
108             return this.timeToLive;
109         }
110     }
111 
112     /**
113      * Sets the last access time to the current time.
114      */
115     public void touch()
116     {
117         synchronized(this) {
118             this.lastAccess = System.currentTimeMillis();
119         }
120     }
121 
122     /**
123      * Returns true if the object hasn't been touched in the previous TTL
124      * period.
125      * 
126      * @return boolean status of object
127      */
128     public boolean isUntouched()
129     {
130         boolean untouched = false;
131         synchronized(this) {
132             if (this.lastAccess + this.timeToLive < System.currentTimeMillis())
133             {
134             	untouched = true;
135             }
136             return untouched;
137         }
138     }
139 
140     /**
141      * Refresh the object and the created time.
142      */
143     public void refresh()
144     {
145         final Refreshable refreshable = getContents();
146         synchronized (this)
147         {
148             this.created = System.currentTimeMillis();
149             refreshable.refresh();
150         }
151     }
152 
153     public long getLastAccess()
154     {
155         return lastAccess;
156     }
157 
158     public void setLastAccess(long lastAccess)
159     {
160         this.lastAccess = lastAccess;
161     }
162 }