1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.push.cdi;
21
22 import java.io.Serializable;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.concurrent.Future;
30 import javax.enterprise.inject.spi.BeanManager;
31 import javax.enterprise.inject.spi.CDI;
32 import javax.faces.FacesException;
33 import javax.faces.context.FacesContext;
34 import javax.faces.push.PushContext;
35 import org.apache.myfaces.cdi.util.CDIUtils;
36
37
38
39
40 public class PushContextImpl implements PushContext
41 {
42
43 private final String channel;
44
45 public PushContextImpl(String channel)
46 {
47 this.channel = channel;
48 }
49
50
51
52
53 public String getChannel()
54 {
55 return channel;
56 }
57
58 @Override
59 public Set<Future<Void>> send(Object message)
60 {
61
62 String channel = getChannel();
63 BeanManager beanManager = null;
64 FacesContext facesContext = FacesContext.getCurrentInstance();
65 if (facesContext != null)
66 {
67 beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
68 }
69 else
70 {
71 beanManager = CDI.current().getBeanManager();
72 }
73
74 WebsocketApplicationBean appTokenBean = CDIUtils.getInstance(beanManager,
75 WebsocketApplicationBean.class, false);
76 WebsocketViewBean viewTokenBean = null;
77 WebsocketSessionBean sessionTokenBean = null;
78
79 if (CDIUtils.isSessionScopeActive(beanManager))
80 {
81 sessionTokenBean = CDIUtils.getInstance(beanManager, WebsocketSessionBean.class, false);
82 if (CDIUtils.isViewScopeActive(beanManager))
83 {
84 viewTokenBean = CDIUtils.getInstance(beanManager, WebsocketViewBean.class, false);
85 }
86 }
87
88 if (appTokenBean == null)
89 {
90
91 return Collections.emptySet();
92 }
93
94 List<String> channelTokens;
95
96 if (viewTokenBean != null && viewTokenBean.isChannelAvailable(channel))
97 {
98
99 channelTokens = viewTokenBean.getChannelTokensFor(channel);
100 }
101 else if (sessionTokenBean != null && sessionTokenBean.isChannelAvailable(getChannel()))
102 {
103
104 channelTokens = sessionTokenBean.getChannelTokensFor(channel);
105 }
106 else if (appTokenBean != null && appTokenBean.isChannelAvailable(getChannel()))
107 {
108
109 channelTokens = appTokenBean.getChannelTokensFor(channel);
110 }
111 else
112 {
113 throw new FacesException("CDI bean not found for push message");
114 }
115
116
117
118 if (channelTokens != null && !channelTokens.isEmpty())
119 {
120 Set<Future<Void>> result = null;
121 for (String channelToken : channelTokens)
122 {
123 if (result == null)
124 {
125 result = WebsocketApplicationSessionHolder.send(channelToken, message);
126 }
127 else
128 {
129 result.addAll(WebsocketApplicationSessionHolder.send(channelToken, message));
130 }
131 }
132 return result;
133 }
134
135 return Collections.emptySet();
136 }
137
138 @Override
139 public <S extends Serializable> Set<Future<Void>> send(Object message, S user)
140 {
141 return send(message, Collections.singleton(user)).get(user);
142 }
143
144 @Override
145 public <S extends Serializable> Map<S, Set<Future<Void>>> send(Object message, Collection<S> users)
146 {
147
148 String channel = getChannel();
149 BeanManager beanManager = null;
150 FacesContext facesContext = FacesContext.getCurrentInstance();
151 if (facesContext != null)
152 {
153 beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
154 }
155 else
156 {
157 beanManager = CDI.current().getBeanManager();
158 }
159
160 WebsocketApplicationBean appTokenBean = CDIUtils.getInstance(beanManager,
161 WebsocketApplicationBean.class, false);
162 WebsocketViewBean viewTokenBean = null;
163 WebsocketSessionBean sessionTokenBean = null;
164
165 if (CDIUtils.isSessionScopeActive(beanManager))
166 {
167 sessionTokenBean = CDIUtils.getInstance(beanManager, WebsocketSessionBean.class, false);
168 if (CDIUtils.isViewScopeActive(beanManager))
169 {
170 viewTokenBean = CDIUtils.getInstance(beanManager, WebsocketViewBean.class, false);
171 }
172 }
173
174 if (appTokenBean == null)
175 {
176
177 return Collections.emptyMap();
178 }
179
180 Map<S, Set<Future<Void>>> result = new HashMap<S, Set<Future<Void>>>();
181
182 if (viewTokenBean != null && viewTokenBean.isChannelAvailable(channel))
183 {
184
185 for (S user : users)
186 {
187 result.put(user, send(viewTokenBean.getChannelTokensFor(channel, user), message));
188 }
189 }
190 else if (sessionTokenBean != null && sessionTokenBean.isChannelAvailable(getChannel()))
191 {
192
193 for (S user : users)
194 {
195 result.put(user, send(sessionTokenBean.getChannelTokensFor(channel, user), message));
196 }
197 }
198 else if (appTokenBean != null && appTokenBean.isChannelAvailable(getChannel()))
199 {
200
201 for (S user : users)
202 {
203 result.put(user, send(appTokenBean.getChannelTokensFor(channel, user), message));
204 }
205 }
206 else
207 {
208 throw new FacesException("CDI bean not found for push message");
209 }
210
211
212 return result;
213 }
214
215 private Set<Future<Void>> send(
216 List<String> channelTokens, Object message)
217 {
218 if (channelTokens != null && !channelTokens.isEmpty())
219 {
220 Set<Future<Void>> result = null;
221 for (int i = 0; i < channelTokens.size(); i++)
222 {
223 String channelToken = channelTokens.get(i);
224 if (result == null)
225 {
226 result = WebsocketApplicationSessionHolder.send(channelToken, message);
227 }
228 else
229 {
230 result.addAll(WebsocketApplicationSessionHolder.send(channelToken, message));
231 }
232 }
233 return result;
234 }
235 return Collections.emptySet();
236 }
237 }