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 org.apache.myfaces.cdi.JsfApplicationArtifactHolder;
22 import java.io.Serializable;
23 import java.util.Map;
24 import java.util.Random;
25 import java.util.concurrent.ConcurrentHashMap;
26 import javax.annotation.PostConstruct;
27 import javax.annotation.PreDestroy;
28 import javax.enterprise.context.SessionScoped;
29 import javax.enterprise.inject.spi.BeanManager;
30 import javax.faces.context.ExceptionHandler;
31 import javax.faces.context.ExternalContext;
32 import javax.faces.context.FacesContext;
33 import javax.inject.Inject;
34 import javax.servlet.ServletContext;
35 import org.apache.myfaces.context.ReleaseableExternalContext;
36 import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
37 import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
38 import org.apache.myfaces.shared.context.ExceptionHandlerImpl;
39
40
41
42
43
44 @SessionScoped
45 public class ViewScopeBeanHolder implements Serializable
46 {
47
48
49
50
51
52 private Map<String, ViewScopeContextualStorage> storageMap;
53
54 private static final Random RANDOM_GENERATOR = new Random();
55
56 private static final String VIEW_SCOPE_PREFIX = "oam.view.SCOPE";
57
58 public static final String VIEW_SCOPE_PREFIX_KEY = VIEW_SCOPE_PREFIX+".KEY";
59
60 @Inject
61 JsfApplicationArtifactHolder applicationContextBean;
62
63 public ViewScopeBeanHolder()
64 {
65 }
66
67 @PostConstruct
68 public void init()
69 {
70 storageMap = new ConcurrentHashMap<String, ViewScopeContextualStorage>();
71 FacesContext facesContext = FacesContext.getCurrentInstance();
72 facesContext.getExternalContext().getSessionMap().put(VIEW_SCOPE_PREFIX_KEY,
73 1);
74 }
75
76
77
78
79
80
81
82
83
84 public ViewScopeContextualStorage getContextualStorage(
85 BeanManager beanManager, String viewScopeId)
86 {
87 ViewScopeContextualStorage contextualStorage = storageMap.get(viewScopeId);
88 if (contextualStorage == null)
89 {
90 synchronized (this)
91 {
92 contextualStorage = storageMap.get(viewScopeId);
93 if (contextualStorage == null)
94 {
95 contextualStorage = new ViewScopeContextualStorage(beanManager);
96 storageMap.put(viewScopeId, contextualStorage);
97 }
98 }
99 }
100 return contextualStorage;
101 }
102
103 public Map<String, ViewScopeContextualStorage> getStorageMap()
104 {
105 return storageMap;
106 }
107
108
109
110
111
112
113
114
115
116
117
118 public Map<String, ViewScopeContextualStorage> forceNewStorage()
119 {
120 Map<String, ViewScopeContextualStorage> oldStorageMap = storageMap;
121 storageMap = new ConcurrentHashMap<String, ViewScopeContextualStorage>();
122 return oldStorageMap;
123 }
124
125
126
127
128
129
130
131
132
133 public void destroyBeans()
134 {
135
136
137
138 Map<String, ViewScopeContextualStorage> oldWindowContextStorages = forceNewStorage();
139
140 for (ViewScopeContextualStorage contextualStorage : oldWindowContextStorages.values())
141 {
142 ViewScopeContextImpl.destroyAllActive(contextualStorage);
143 }
144 }
145
146 public void destroyBeans(String viewScopeId)
147 {
148 ViewScopeContextualStorage contextualStorage = storageMap.get(viewScopeId);
149 if (contextualStorage != null)
150 {
151 try
152 {
153 FacesContext facesContext = FacesContext.getCurrentInstance();
154 if (facesContext == null &&
155 applicationContextBean.getServletContext() != null)
156 {
157 try
158 {
159 ServletContext servletContext = applicationContextBean.getServletContext();
160 ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, false);
161 ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
162 facesContext = new StartupFacesContextImpl(externalContext,
163 (ReleaseableExternalContext) externalContext, exceptionHandler, false);
164 ViewScopeContextImpl.destroyAllActive(contextualStorage, facesContext);
165 }
166 finally
167 {
168 facesContext.release();
169 }
170 }
171 else
172 {
173 ViewScopeContextImpl.destroyAllActive(contextualStorage, facesContext);
174 }
175 }
176 finally
177 {
178
179 storageMap.remove(viewScopeId);
180 }
181 }
182 }
183
184 @PreDestroy
185 public void destroyBeansOnPreDestroy()
186 {
187
188
189
190
191
192
193
194
195
196 Map<String, ViewScopeContextualStorage> oldWindowContextStorages = forceNewStorage();
197 if (!oldWindowContextStorages.isEmpty())
198 {
199 FacesContext facesContext = FacesContext.getCurrentInstance();
200 if (facesContext == null &&
201 applicationContextBean.getServletContext() != null)
202 {
203 try
204 {
205 ServletContext servletContext = applicationContextBean.getServletContext();
206 ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, false);
207 ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
208 facesContext = new StartupFacesContextImpl(externalContext,
209 (ReleaseableExternalContext) externalContext, exceptionHandler, false);
210 for (ViewScopeContextualStorage contextualStorage : oldWindowContextStorages.values())
211 {
212 ViewScopeContextImpl.destroyAllActive(contextualStorage, facesContext);
213 }
214 }
215 finally
216 {
217 facesContext.release();
218 }
219 }
220 else
221 {
222 for (ViewScopeContextualStorage contextualStorage : oldWindowContextStorages.values())
223 {
224 ViewScopeContextImpl.destroyAllActive(contextualStorage);
225 }
226 }
227 }
228 }
229
230 public String generateUniqueViewScopeId()
231 {
232
233
234 String key;
235 do
236 {
237 key = Integer.toString(RANDOM_GENERATOR.nextInt());
238 } while (storageMap.containsKey(key));
239 return key;
240 }
241
242 }