1 package com.atlassian.cache.ehcache;
2
3 import net.sf.ehcache.Ehcache;
4 import net.sf.ehcache.Element;
5 import net.sf.ehcache.constructs.EhcacheDecoratorAdapter;
6
7 import java.io.Serializable;
8 import java.util.Map;
9 import java.util.concurrent.ConcurrentHashMap;
10 import java.util.function.Consumer;
11 import java.util.function.Function;
12
13 public class SynchronizedLoadingCacheDecorator extends EhcacheDecoratorAdapter {
14
15 private static final Object LOAD_PLACEHOLDER = new Object();
16
17 private final Map synchronizationMap = new ConcurrentHashMap<>();
18
19 public SynchronizedLoadingCacheDecorator(final Ehcache delegate) {
20 super(delegate);
21 }
22
23 @SuppressWarnings("unchecked")
24 protected <V> Element synchronizedLoad(Object key, Function<Object, V> loader, Consumer<Element> postLoadProcessor) {
25 Element result;
26 V value = null;
27 try {
28 synchronizationMap.put(key, LOAD_PLACEHOLDER);
29 value = loader.apply(key);
30 } finally {
31 result = new Element(key, value);
32 synchronizationMap.computeIfPresent(key, (a, b) -> {
33 postLoadProcessor.accept(result);
34 return null;
35 });
36
37 }
38 return result;
39 }
40
41 @Override
42 public boolean remove(Serializable key, boolean doNotNotifyCacheReplicators) {
43 synchronizationMap.remove(key);
44 return super.remove(key, doNotNotifyCacheReplicators);
45 }
46
47 @Override
48 public boolean remove(Serializable key) {
49 synchronizationMap.remove(key);
50 return super.remove(key);
51 }
52
53 @Override
54 public boolean remove(Object key, final boolean doNotNotifyCacheReplicators) {
55 synchronizationMap.remove(key);
56 return super.remove(key, doNotNotifyCacheReplicators);
57 }
58
59 @Override
60 public boolean remove(Object key) {
61 synchronizationMap.remove(key);
62 return super.remove(key);
63 }
64
65 @Override
66 public void removeAll() {
67 synchronizationMap.clear();
68 super.removeAll();
69 }
70
71 @Override
72 public void removeAll(boolean doNotNotifyCacheReplicators) {
73 synchronizationMap.clear();
74 super.removeAll(doNotNotifyCacheReplicators);
75 }
76 }