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 package info.magnolia.module.cache.ehcache3;
35
36 import info.magnolia.module.cache.BlockingCache;
37 import info.magnolia.module.cache.CacheModule;
38 import info.magnolia.module.cache.blocking.AbstractBlockingCache;
39 import info.magnolia.module.cache.filter.CachedEntry;
40
41 import java.io.IOException;
42 import java.util.ArrayList;
43 import java.util.Iterator;
44 import java.util.List;
45
46 import javax.servlet.FilterChain;
47 import javax.servlet.ServletException;
48 import javax.servlet.http.HttpServletRequest;
49 import javax.servlet.http.HttpServletResponse;
50
51 import org.ehcache.Cache;
52 import org.ehcache.Status;
53 import org.ehcache.UserManagedCache;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57
58
59
60 public class EhCache3Wrapper extends AbstractBlockingCache implements BlockingCache {
61
62 private static final Logger log = LoggerFactory.getLogger(EhCache3Wrapper.class);
63
64 private final Cache ehcache;
65
66 public EhCache3Wrapper(String name, CacheModule cacheModule, int blockingTimeout, Cache ehcache) {
67 super(name, cacheModule, blockingTimeout);
68 this.ehcache = ehcache;
69 }
70
71 @Override
72 public Object getQuiet(Object key) {
73 if (isInitialized()) {
74 super.getQuiet(key);
75 final Object value = ehcache.get(key);
76 return value instanceof CacheEntryTtlWrapper ? ((CacheEntryTtlWrapper) value).getWrappedValue() : value;
77 } else {
78 return null;
79 }
80 }
81
82 @Override
83 protected void putQuiet(Object key, Object value, int timeToLiveInSeconds) {
84 if (isInitialized()) {
85 if (timeToLiveInSeconds != -1 && !(value instanceof CachedEntry)) {
86 value = new CacheEntryTtlWrapper(value, timeToLiveInSeconds);
87 }
88 ehcache.put(key, value);
89 }
90 }
91
92 private static class CacheEntryTtlWrapper implements CachedEntry {
93
94 final Object wrapped;
95 final int ttl;
96
97 private CacheEntryTtlWrapper(Object wrapped, int ttl) {
98 this.wrapped = wrapped;
99 this.ttl = ttl;
100 }
101
102 @Override
103 public void replay(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
104 throw new UnsupportedOperationException();
105 }
106
107 @Override
108 public String getOriginalURL() {
109 throw new UnsupportedOperationException();
110 }
111
112 @Override
113 public long getLastModificationTime() {
114 throw new UnsupportedOperationException();
115 }
116
117 @Override
118 public int getTimeToLiveInSeconds() {
119 return ttl;
120 }
121
122 private Object getWrappedValue() {
123 return wrapped;
124 }
125 }
126
127 @Override
128 public void remove(Object key) {
129 if (isInitialized()) {
130 ehcache.remove(key);
131 super.remove(key);
132 }
133 }
134
135 @Override
136 public void clear() {
137 if (isInitialized()) {
138 ehcache.clear();
139 super.clear();
140 }
141 }
142
143 @Override
144 public int getSize() {
145 if (!isInitialized()) {
146 return 0;
147 }
148 final Iterator iterator = ehcache.iterator();
149 int size = 0;
150 while(iterator.hasNext()) {
151 iterator.next();
152 size++;
153 }
154 return size;
155 }
156
157 @Override
158 public List<Object> getKeys() {
159 if (!isInitialized()) {
160 return new ArrayList<>();
161 }
162 final Iterator<Cache.Entry> iterator = ehcache.iterator();
163 final List<Object> keys = new ArrayList<>();
164 while(iterator.hasNext()) {
165 Cache.Entry entry = iterator.next();
166 keys.add(entry.getKey());
167 }
168 return keys;
169 }
170
171 public Cache getWrappedEhCache() {
172 return ehcache;
173 }
174
175 private boolean isInitialized() {
176 if (ehcache instanceof UserManagedCache && ((UserManagedCache) ehcache).getStatus() == Status.UNINITIALIZED) {
177 log.warn("Cache named {{}} is {}. Ignoring any calls on it. This might happen when editing the Ehcache factory configuration at runtime", getName(), Status.UNINITIALIZED);
178 return false;
179 } else {
180 return true;
181 }
182 }
183 }