1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.cdi.view;
20
21 import javax.enterprise.context.ContextNotActiveException;
22 import javax.enterprise.inject.Typed;
23 import javax.enterprise.inject.spi.BeanManager;
24
25 import java.lang.annotation.Annotation;
26 import java.util.Map;
27 import javax.enterprise.context.spi.Context;
28 import javax.enterprise.context.spi.Contextual;
29 import javax.enterprise.context.spi.CreationalContext;
30 import javax.enterprise.inject.spi.PassivationCapable;
31 import javax.faces.context.ExternalContext;
32 import javax.faces.context.FacesContext;
33 import javax.faces.view.ViewScoped;
34
35 import org.apache.myfaces.cdi.util.BeanProvider;
36 import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
37 import org.apache.myfaces.config.ManagedBeanDestroyer;
38 import org.apache.myfaces.config.RuntimeConfig;
39 import org.apache.myfaces.config.annotation.LifecycleProvider;
40 import org.apache.myfaces.config.annotation.LifecycleProviderFactory;
41 import org.apache.myfaces.view.ViewScopeProxyMap;
42
43
44
45
46
47
48 @Typed()
49 public class ViewScopeContextImpl implements Context
50 {
51
52
53
54
55 private BeanManager beanManager;
56
57
58 public ViewScopeContextImpl(BeanManager beanManager)
59 {
60 this.beanManager = beanManager;
61 }
62
63 protected ViewScopeBeanHolder getViewScopeBeanHolder()
64 {
65 return getViewScopeBeanHolder(FacesContext.getCurrentInstance());
66 }
67
68 protected ViewScopeBeanHolder getViewScopeBeanHolder(FacesContext facesContext)
69 {
70 ViewScopeBeanHolder viewScopeBeanHolder = (ViewScopeBeanHolder)
71 facesContext.getExternalContext().getApplicationMap().get(
72 "oam.view.ViewScopeBeanHolder");
73 if (viewScopeBeanHolder == null)
74 {
75 viewScopeBeanHolder = BeanProvider.getContextualReference(
76 beanManager, ViewScopeBeanHolder.class, false);
77 facesContext.getExternalContext().getApplicationMap().put(
78 "oam.view.ViewScopeBeanHolder", viewScopeBeanHolder);
79 }
80 return viewScopeBeanHolder;
81 }
82
83 public String getCurrentViewScopeId(boolean create)
84 {
85 FacesContext facesContext = FacesContext.getCurrentInstance();
86 ViewScopeProxyMap map = (ViewScopeProxyMap) facesContext.getViewRoot().getViewMap(create);
87 if (map != null)
88 {
89 String id = map.getViewScopeId();
90 if (id == null && create)
91 {
92
93 map.forceCreateWrappedMap(facesContext);
94 id = map.getViewScopeId();
95 }
96 return id;
97 }
98 return null;
99 }
100
101 protected ViewScopeContextualStorage getContextualStorage(boolean createIfNotExist)
102 {
103 String viewScopeId = getCurrentViewScopeId(createIfNotExist);
104 if (createIfNotExist && viewScopeId == null)
105 {
106 throw new ContextNotActiveException(
107 "ViewScopeContextImpl: no viewScopeId set for the current view yet!");
108 }
109 if (viewScopeId != null)
110 {
111 return getViewScopeBeanHolder().getContextualStorage(beanManager, viewScopeId);
112 }
113 return null;
114 }
115
116 public Class<? extends Annotation> getScope()
117 {
118 return ViewScoped.class;
119 }
120
121
122
123
124
125 public boolean isActive()
126 {
127 FacesContext facesContext = FacesContext.getCurrentInstance();
128 return facesContext.getViewRoot() != null;
129 }
130
131 public <T> T get(Contextual<T> bean)
132 {
133 checkActive();
134
135
136 FacesContext.getCurrentInstance().getExternalContext().getSession(true);
137
138 ViewScopeContextualStorage storage = getContextualStorage(false);
139 if (storage == null)
140 {
141 return null;
142 }
143
144 Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
145 ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
146 if (contextualInstanceInfo == null)
147 {
148 return null;
149 }
150
151 return (T) contextualInstanceInfo.getContextualInstance();
152 }
153
154 public <T> T get(Contextual<T> bean, CreationalContext<T> creationalContext)
155 {
156 checkActive();
157
158 if (!(bean instanceof PassivationCapable))
159 {
160 throw new IllegalStateException(bean.toString() +
161 " doesn't implement " + PassivationCapable.class.getName());
162 }
163
164
165 FacesContext.getCurrentInstance().getExternalContext().getSession(true);
166
167 ViewScopeContextualStorage storage = getContextualStorage(true);
168
169 Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
170 ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
171
172 if (contextualInstanceInfo != null)
173 {
174 @SuppressWarnings("unchecked")
175 final T instance = (T) contextualInstanceInfo.getContextualInstance();
176
177 if (instance != null)
178 {
179 return instance;
180 }
181 }
182
183 return storage.createContextualInstance(bean, creationalContext);
184 }
185
186
187
188
189
190
191 public boolean destroy(Contextual bean)
192 {
193 ViewScopeContextualStorage storage = getContextualStorage(false);
194 if (storage == null)
195 {
196 return false;
197 }
198 ContextualInstanceInfo<?> contextualInstanceInfo =
199 storage.getStorage().get(storage.getBeanKey(bean));
200
201 if (contextualInstanceInfo == null)
202 {
203 return false;
204 }
205
206 bean.destroy(contextualInstanceInfo.getContextualInstance(),
207 contextualInstanceInfo.getCreationalContext());
208
209 return true;
210 }
211
212
213
214
215
216 public void destroyAllActive()
217 {
218 ViewScopeContextualStorage storage = getContextualStorage(false);
219 if (storage == null)
220 {
221 return;
222 }
223
224 destroyAllActive(storage);
225 }
226
227 public static void destroyAllActive(ViewScopeContextualStorage storage)
228 {
229 destroyAllActive(storage, FacesContext.getCurrentInstance());
230 }
231
232 public static void destroyAllActive(ViewScopeContextualStorage storage, FacesContext facesContext)
233 {
234 Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
235 ManagedBeanDestroyer mbDestroyer =
236 getManagedBeanDestroyer(facesContext.getExternalContext());
237
238 for (Map.Entry<Object, ContextualInstanceInfo<?>> entry : contextMap.entrySet())
239 {
240 if (!(entry.getKey() instanceof _ContextualKey))
241 {
242 Contextual bean = storage.getBean(facesContext, entry.getKey());
243
244 ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
245 bean.destroy(contextualInstanceInfo.getContextualInstance(),
246 contextualInstanceInfo.getCreationalContext());
247 }
248 else
249 {
250
251 _ContextualKey key = (_ContextualKey) entry.getKey();
252 mbDestroyer.destroy(key.getName(), entry.getValue().getContextualInstance());
253 }
254 }
255
256 contextMap.clear();
257
258 storage.deactivate();
259 }
260
261
262
263
264
265
266 protected void checkActive()
267 {
268 if (!isActive())
269 {
270 throw new ContextNotActiveException("CDI context with scope annotation @"
271 + getScope().getName() + " is not active with respect to the current thread");
272 }
273 }
274
275 protected static ManagedBeanDestroyer getManagedBeanDestroyer(ExternalContext externalContext)
276 {
277 RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
278 LifecycleProvider lifecycleProvider = LifecycleProviderFactory
279 .getLifecycleProviderFactory(externalContext).getLifecycleProvider(externalContext);
280
281 return new ManagedBeanDestroyer(lifecycleProvider, runtimeConfig);
282 }
283 }