1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.cdi.util;
21
22
23 import javax.enterprise.context.spi.Contextual;
24 import javax.enterprise.context.spi.CreationalContext;
25 import javax.enterprise.inject.spi.BeanManager;
26 import javax.enterprise.inject.spi.PassivationCapable;
27 import java.io.Serializable;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.concurrent.ConcurrentMap;
32
33
34
35
36
37
38
39
40
41 public class ContextualStorage implements Serializable
42 {
43 private static final long serialVersionUID = 1L;
44
45 private final Map<Object, ContextualInstanceInfo<?>> contextualInstances;
46
47 private final BeanManager beanManager;
48
49 private final boolean concurrent;
50
51 private final boolean passivationCapable;
52
53
54
55
56
57
58 public ContextualStorage(BeanManager beanManager, boolean concurrent, boolean passivationCapable)
59 {
60 this.beanManager = beanManager;
61 this.concurrent = concurrent;
62 this.passivationCapable = passivationCapable;
63 if (concurrent)
64 {
65 contextualInstances = new ConcurrentHashMap<Object, ContextualInstanceInfo<?>>();
66 }
67 else
68 {
69 contextualInstances = new HashMap<Object, ContextualInstanceInfo<?>>();
70 }
71 }
72
73
74
75
76 public Map<Object, ContextualInstanceInfo<?>> getStorage()
77 {
78 return contextualInstances;
79 }
80
81
82
83
84 public boolean isConcurrent()
85 {
86 return concurrent;
87 }
88
89
90
91
92
93
94
95
96 public <T> T createContextualInstance(Contextual<T> bean, CreationalContext<T> creationalContext)
97 {
98 Object beanKey = getBeanKey(bean);
99 if (isConcurrent())
100 {
101
102 ContextualInstanceInfo<T> instanceInfo = new ContextualInstanceInfo<T>();
103
104 ConcurrentMap<Object, ContextualInstanceInfo<?>> concurrentMap
105 = (ConcurrentHashMap<Object, ContextualInstanceInfo<?>>) contextualInstances;
106
107 ContextualInstanceInfo<T> oldInstanceInfo
108 = (ContextualInstanceInfo<T>) concurrentMap.putIfAbsent(beanKey, instanceInfo);
109
110 if (oldInstanceInfo != null)
111 {
112 instanceInfo = oldInstanceInfo;
113 }
114 synchronized (instanceInfo)
115 {
116 T instance = instanceInfo.getContextualInstance();
117 if (instance == null)
118 {
119 instance = bean.create(creationalContext);
120 instanceInfo.setContextualInstance(instance);
121 instanceInfo.setCreationalContext(creationalContext);
122 }
123
124 return instance;
125 }
126
127 }
128 else
129 {
130
131 ContextualInstanceInfo<T> instanceInfo = new ContextualInstanceInfo<T>();
132 instanceInfo.setCreationalContext(creationalContext);
133 instanceInfo.setContextualInstance(bean.create(creationalContext));
134
135 contextualInstances.put(beanKey, instanceInfo);
136
137 return instanceInfo.getContextualInstance();
138 }
139 }
140
141
142
143
144
145
146
147 public <T> Object getBeanKey(Contextual<T> bean)
148 {
149 if (passivationCapable)
150 {
151
152 return ((PassivationCapable) bean).getId();
153 }
154
155 return bean;
156 }
157
158
159
160
161
162 public Contextual<?> getBean(Object beanKey)
163 {
164 if (passivationCapable)
165 {
166 return beanManager.getPassivationCapableBean((String) beanKey);
167 }
168 else
169 {
170 return (Contextual<?>) beanKey;
171 }
172 }
173 }