1
22
23 package com.liferay.portal.util;
24
25 import com.liferay.portal.SystemException;
26 import com.liferay.portal.kernel.servlet.HttpHeaders;
27 import com.liferay.portal.kernel.util.GetterUtil;
28 import com.liferay.portal.model.Group;
29 import com.liferay.portal.model.UserTracker;
30 import com.liferay.portal.security.auth.CompanyThreadLocal;
31 import com.liferay.portal.service.GroupLocalServiceUtil;
32 import com.liferay.portal.service.UserTrackerLocalServiceUtil;
33 import com.liferay.portal.service.persistence.UserTrackerUtil;
34 import com.liferay.util.ConcurrentHashSet;
35 import com.liferay.util.dao.hibernate.QueryUtil;
36
37 import java.util.ArrayList;
38 import java.util.Date;
39 import java.util.Iterator;
40 import java.util.LinkedHashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Set;
44 import java.util.concurrent.ConcurrentHashMap;
45
46 import javax.servlet.http.HttpServletRequest;
47 import javax.servlet.http.HttpSession;
48
49 import org.apache.commons.logging.Log;
50 import org.apache.commons.logging.LogFactory;
51
52
59 public class LiveUsers {
60
61 public static void deleteGroup(long groupId) {
62 _instance._deleteGroup(groupId);
63 }
64
65 public static Set<Long> getGroupUsers(long groupId) {
66 return _instance._getGroupUsers(_instance._getLiveUsers(), groupId);
67 }
68
69 public static int getGroupUsersCount(long groupId) {
70 return getGroupUsers(groupId).size();
71 }
72
73 public static Map<String, UserTracker> getSessionUsers() {
74 return _instance._getSessionUsers();
75 }
76
77 public static int getSessionUsersCount() {
78 return getSessionUsers().size();
79 }
80
81 public static UserTracker getUserTracker(String sesId) {
82 return _instance._getUserTracker(sesId);
83 }
84
85 public static void joinGroup(long userId, long groupId) {
86 _instance._joinGroup(userId, groupId);
87 }
88
89 public static void joinGroup(long[] userIds, long groupId) {
90 _instance._joinGroup(userIds, groupId);
91 }
92
93 public static void leaveGroup(long userId, long groupId) {
94 _instance._leaveGroup(userId, groupId);
95 }
96
97 public static void leaveGroup(long[] userIds, long groupId) {
98 _instance._leaveGroup(userIds, groupId);
99 }
100
101 public static void signIn(HttpServletRequest req) throws SystemException {
102 _instance._signIn(req);
103 }
104
105 public static void signOut(String sesId, long userId)
106 throws SystemException {
107
108 _instance._signOut(sesId, userId);
109 }
110
111 private LiveUsers() {
112 }
113
114 private void _addUserTracker(long userId, UserTracker userTracker) {
115 List<UserTracker> userTrackers = _getUserTrackers(userId);
116
117 if (userTrackers != null) {
118 userTrackers.add(userTracker);
119 }
120 else {
121 userTrackers = new ArrayList<UserTracker>();
122
123 userTrackers.add(userTracker);
124
125 Map<Long, List<UserTracker>> userTrackersMap =
126 _getUserTrackersMap();
127
128 userTrackersMap.put(userId, userTrackers);
129 }
130 }
131
132 private void _deleteGroup(long groupId) {
133 Map<Long, Set<Long>> liveUsers = _getLiveUsers();
134
135 liveUsers.remove(groupId);
136 }
137
138 private Set<Long> _getGroupUsers(
139 Map<Long, Set<Long>> liveUsers, long groupId) {
140
141 Set<Long> groupUsers = liveUsers.get(groupId);
142
143 if (groupUsers == null) {
144 groupUsers = new ConcurrentHashSet<Long>();
145
146 liveUsers.put(groupId, groupUsers);
147 }
148
149 return groupUsers;
150 }
151
152 private Map<Long, Set<Long>> _getLiveUsers() {
153 String companyIdString = String.valueOf(
154 CompanyThreadLocal.getCompanyId());
155
156 Map<Long, Set<Long>> liveUsers = (Map<Long, Set<Long>>)WebAppPool.get(
157 companyIdString, WebKeys.LIVE_USERS);
158
159 if (liveUsers == null) {
160 liveUsers = new ConcurrentHashMap<Long, Set<Long>>();
161
162 WebAppPool.put(companyIdString, WebKeys.LIVE_USERS, liveUsers);
163 }
164
165 return liveUsers;
166 }
167
168 private Map<String, UserTracker> _getSessionUsers() {
169 String companyIdString = String.valueOf(
170 CompanyThreadLocal.getCompanyId());
171
172 Map<String, UserTracker> sessionUsers =
173 (Map<String, UserTracker>)WebAppPool.get(
174 companyIdString, WebKeys.LIVE_SESSION_USERS);
175
176 if (sessionUsers == null) {
177 sessionUsers = new ConcurrentHashMap<String, UserTracker>();
178
179 WebAppPool.put(
180 companyIdString, WebKeys.LIVE_SESSION_USERS, sessionUsers);
181 }
182
183 return sessionUsers;
184 }
185
186 private UserTracker _getUserTracker(String sesId) {
187 Map<String, UserTracker> sessionUsers = _getSessionUsers();
188
189 return sessionUsers.get(sesId);
190 }
191
192 private List<UserTracker> _getUserTrackers(long userId) {
193 Map<Long, List<UserTracker>> userTrackersMap = _getUserTrackersMap();
194
195 return userTrackersMap.get(userId);
196 }
197
198 private Map<Long, List<UserTracker>> _getUserTrackersMap() {
199 String companyIdString = String.valueOf(
200 CompanyThreadLocal.getCompanyId());
201
202 Map<Long, List<UserTracker>> userTrackersMap =
203 (Map<Long, List<UserTracker>>)WebAppPool.get(
204 companyIdString, WebKeys.LIVE_USER_TRACKERS);
205
206 if (userTrackersMap == null) {
207 userTrackersMap = new ConcurrentHashMap<Long, List<UserTracker>>();
208
209 WebAppPool.put(
210 companyIdString, WebKeys.LIVE_USER_TRACKERS, userTrackersMap);
211 }
212
213 return userTrackersMap;
214 }
215
216 private void _joinGroup(long userId, long groupId) {
217 Map<Long, Set<Long>> liveUsers = _getLiveUsers();
218
219 Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
220
221 if (_getUserTrackers(userId) != null) {
222 groupUsers.add(userId);
223 }
224 }
225
226 private void _joinGroup(long[] userIds, long groupId) {
227 Map<Long, Set<Long>> liveUsers = _getLiveUsers();
228
229 Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
230
231 for (long userId : userIds) {
232 if (_getUserTrackers(userId) != null) {
233 groupUsers.add(userId);
234 }
235 }
236 }
237
238 private void _leaveGroup(long userId, long groupId) {
239 Map<Long, Set<Long>> liveUsers = _getLiveUsers();
240
241 Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
242
243 groupUsers.remove(userId);
244 }
245
246 private void _leaveGroup(long[] userIds, long groupId) {
247 Map<Long, Set<Long>> liveUsers = _getLiveUsers();
248
249 Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
250
251 for (long userId : userIds) {
252 groupUsers.remove(userId);
253 }
254 }
255
256 private void _removeUserTracker(long userId, UserTracker userTracker) {
257 List<UserTracker> userTrackers = _getUserTrackers(userId);
258
259 if (userTrackers != null) {
260 Iterator<UserTracker> itr = userTrackers.iterator();
261
262 while (itr.hasNext()) {
263 UserTracker curUserTracker = itr.next();
264
265 if (userTracker.equals(curUserTracker)) {
266 itr.remove();
267 }
268 }
269
270 if (userTrackers.size() == 0) {
271 Map<Long, List<UserTracker>> userTrackersMap =
272 _getUserTrackersMap();
273
274 userTrackersMap.remove(userId);
275 }
276 }
277 }
278
279 private void _signIn(HttpServletRequest req) throws SystemException {
280 HttpSession ses = req.getSession();
281
282 long companyId = CompanyThreadLocal.getCompanyId();
283 long userId = GetterUtil.getLong(req.getRemoteUser());
284
285 _updateGroupStatus(userId, true);
286
287 Map<String, UserTracker> sessionUsers = _getSessionUsers();
288
289 List<UserTracker> userTrackers = _getUserTrackers(userId);
290
291 if (!PropsValues.AUTH_SIMULTANEOUS_LOGINS) {
292 if (userTrackers != null) {
293 for (UserTracker userTracker : userTrackers) {
294
295
297 userTracker.getHttpSession().setAttribute(
298 WebKeys.STALE_SESSION, Boolean.TRUE);
299 }
300 }
301 }
302
303 UserTracker userTracker = sessionUsers.get(ses.getId());
304
305 if ((userTracker == null) &&
306 (PropsValues.SESSION_TRACKER_MEMORY_ENABLED)) {
307
308 userTracker = UserTrackerUtil.create(0);
309
310 userTracker.setCompanyId(companyId);
311 userTracker.setUserId(userId);
312 userTracker.setModifiedDate(new Date());
313 userTracker.setHttpSession(ses);
314 userTracker.setRemoteAddr(req.getRemoteAddr());
315 userTracker.setRemoteHost(req.getRemoteHost());
316 userTracker.setUserAgent(req.getHeader(HttpHeaders.USER_AGENT));
317
318 sessionUsers.put(ses.getId(), userTracker);
319
320 _addUserTracker(userId, userTracker);
321 }
322 }
323
324 private void _signOut(String sesId, long userId) throws SystemException {
325 List<UserTracker> userTrackers = _getUserTrackers(userId);
326
327 if ((userTrackers == null) || (userTrackers.size() <= 1)) {
328 _updateGroupStatus(userId, false);
329 }
330
331 Map<String, UserTracker> sessionUsers = _getSessionUsers();
332
333 UserTracker userTracker = sessionUsers.remove(sesId);
334
335 if (userTracker != null) {
336 try {
337 UserTrackerLocalServiceUtil.addUserTracker(
338 userTracker.getCompanyId(), userTracker.getUserId(),
339 userTracker.getModifiedDate(), sesId,
340 userTracker.getRemoteAddr(), userTracker.getRemoteHost(),
341 userTracker.getUserAgent(), userTracker.getPaths());
342 }
343 catch (Exception e) {
344 if (_log.isWarnEnabled()) {
345 _log.warn(e.getMessage());
346 }
347 }
348
349 _removeUserTracker(userId, userTracker);
350 }
351 }
352
353 private Map<Long, Set<Long>> _updateGroupStatus(
354 long userId, boolean signedIn)
355 throws SystemException {
356
357 long companyId = CompanyThreadLocal.getCompanyId();
358
359 Map<Long, Set<Long>> liveUsers = _getLiveUsers();
360
361 LinkedHashMap<String, Object> groupParams =
362 new LinkedHashMap<String, Object>();
363
364 groupParams.put("usersGroups", userId);
365
366 List<Group> communities = GroupLocalServiceUtil.search(
367 companyId, null, null, groupParams, QueryUtil.ALL_POS,
368 QueryUtil.ALL_POS);
369
370 for (Group community : communities) {
371 Set<Long> groupUsers = _getGroupUsers(
372 liveUsers, community.getGroupId());
373
374 if (signedIn) {
375 groupUsers.add(userId);
376 }
377 else {
378 groupUsers.remove(userId);
379 }
380 }
381
382 return liveUsers;
383 }
384
385 private static Log _log = LogFactory.getLog(LiveUsers.class);
386
387 private static LiveUsers _instance = new LiveUsers();
388
389 }