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