Roberto Sánchez
2014-01-17 c2cf57687d1d61fd476659bc5bead0592143a5c6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package net.curisit.securis.utils;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Cache implementation with TTL (time To Live) The objects are removed from cache when TTL is reached.
 * 
 * @author roberto <roberto.sanchez@curisit.net>
 */
@Singleton
public class CacheTTL {
   private static final Logger log = LoggerFactory.getLogger(CacheTTL.class);
   /**
    * Period before token expires, set in seconds.
    */
   private static int DEFAULT_CACHE_DURATION = 24 * 60 * 60;
   private Map<String, CachedObject> data = new Hashtable<>();
   private Thread cleaningThread = null;
   @Inject
   public CacheTTL() {
       cleaningThread = new Thread(new Runnable() {
           @Override
           public void run() {
               while (CacheTTL.this.data != null) {
                   try {
                       // We check for expired object every 60 seconds
                       Thread.sleep(60 * 1000);
                   } catch (InterruptedException e) {
                       log.error("Exiting from Cache Thread");
                       data.clear();
                       return;
                   }
                   // log.info("Cheking expired objects " + new Date());
                   Date now = new Date();
                   for (String key : CacheTTL.this.data.keySet()) {
                       CachedObject co = CacheTTL.this.data.get(key);
                       if (now.after(co.getExpireAt())) {
                           CacheTTL.this.data.remove(key);
                       }
                   }
               }
           }
       });
       cleaningThread.start();
   }
   /**
    * 
    * @param key
    * @param obj
    * @param ttl
    *            Time To Live in seconds
    */
   public void set(String key, Object obj, int ttl) {
       Date expirationDate = new Date(new Date().getTime() + ttl * 1000);
       data.put(key, new CachedObject(expirationDate, obj));
   }
   public void set(String key, Object obj) {
       set(key, obj, DEFAULT_CACHE_DURATION);
   }
   public Object get(String key) {
       CachedObject co = data.get(key);
       return co == null ? null : co.getObject();
   }
   public <T> T get(String key, Class<T> type) {
       CachedObject co = data.get(key);
       return co == null ? null : co.getObject(type);
   }
   public <T> T remove(String key, Class<T> type) {
       CachedObject co = data.remove(key);
       return co == null ? null : co.getObject(type);
   }
   public Object remove(String key) {
       CachedObject co = data.remove(key);
       return co == null ? null : co.getObject();
   }
   public void clear() {
       data.clear();
   }
   private class CachedObject {
       Date expireAt;
       Object object;
       public CachedObject(Date date, Object obj) {
           expireAt = date;
           object = obj;
       }
       public Date getExpireAt() {
           return expireAt;
       }
       public Object getObject() {
           return object;
       }
       @SuppressWarnings("unchecked")
       public <T> T getObject(Class<T> type) {
           return (T) object;
       }
   }
}