1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.directwebremoting.guice;
17
18 import com.google.inject.Key;
19
20 import java.util.Collection;
21 import java.util.concurrent.ConcurrentHashMap;
22 import java.util.concurrent.ConcurrentMap;
23
24 /**
25 * A specialization of {@link AbstractContextScope} using a concurrent map
26 * to hold registered instance providers. Concrete implementations must
27 * define {@code get()} to return the current context, and they must call
28 * {@code super(C.class)} in constructors.
29 * @author Tim Peierls [tim at peierls dot net]
30 */
31 public abstract class AbstractMapContextScope<C>
32 extends AbstractContextScope<C, ConcurrentMap>
33 {
34 protected AbstractMapContextScope(Class<C> type, String scopeName)
35 {
36 super(type, scopeName);
37 }
38
39 public abstract C get();
40
41
42
43
44
45
46 public ConcurrentMap registryFor(C context)
47 {
48 ConcurrentMap instanceMap = map.get(context);
49
50 if (instanceMap == null)
51 {
52 ConcurrentMap emptyMap = new ConcurrentHashMap();
53 instanceMap = map.putIfAbsent(context, emptyMap);
54 if (instanceMap == null)
55 {
56 instanceMap = emptyMap;
57 }
58 }
59
60 return instanceMap;
61 }
62
63 public <T> InstanceProvider<T> get(ConcurrentMap registry, Key<T> key, String keyString)
64 {
65 @SuppressWarnings("unchecked")
66 ConcurrentMap<Key<T>, InstanceProvider<T>> instanceMap =
67 (ConcurrentMap<Key<T>, InstanceProvider<T>>) registry;
68 return instanceMap.get(key);
69 }
70
71 public <T> InstanceProvider<T> putIfAbsent(ConcurrentMap registry,
72 Key<T> key, String keyString,
73 InstanceProvider<T> creator)
74 {
75 @SuppressWarnings("unchecked")
76 ConcurrentMap<Key<T>, InstanceProvider<T>> instanceMap =
77 (ConcurrentMap<Key<T>, InstanceProvider<T>>) registry;
78
79 return instanceMap.putIfAbsent(key, creator);
80 }
81
82 public <T> boolean remove(ConcurrentMap registry, Key<T> key, String keyString,
83 InstanceProvider<T> creator)
84 {
85 @SuppressWarnings("unchecked")
86 ConcurrentMap<Key<T>, InstanceProvider<T>> instanceMap =
87 (ConcurrentMap<Key<T>, InstanceProvider<T>>) registry;
88
89 return instanceMap.remove(key, creator);
90 }
91
92 private final ConcurrentMap<C, ConcurrentMap> map =
93 new ConcurrentHashMap<C, ConcurrentMap>();
94 }