1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.liveusers;
16  
17  import com.liferay.portal.SystemException;
18  import com.liferay.portal.kernel.concurrent.ConcurrentHashSet;
19  import com.liferay.portal.kernel.dao.orm.QueryUtil;
20  import com.liferay.portal.kernel.log.Log;
21  import com.liferay.portal.kernel.log.LogFactoryUtil;
22  import com.liferay.portal.model.Group;
23  import com.liferay.portal.model.UserTracker;
24  import com.liferay.portal.service.GroupLocalServiceUtil;
25  import com.liferay.portal.service.UserTrackerLocalServiceUtil;
26  import com.liferay.portal.service.persistence.UserTrackerUtil;
27  import com.liferay.portal.util.PropsValues;
28  import com.liferay.portal.util.WebAppPool;
29  import com.liferay.portal.util.WebKeys;
30  
31  import java.util.ArrayList;
32  import java.util.Date;
33  import java.util.Iterator;
34  import java.util.LinkedHashMap;
35  import java.util.List;
36  import java.util.Map;
37  import java.util.Set;
38  import java.util.concurrent.ConcurrentHashMap;
39  
40  /**
41   * <a href="LiveUsers.java.html"><b><i>View Source</i></b></a>
42   *
43   * @author Charles May
44   * @author Brian Wing Shun Chan
45   */
46  public class LiveUsers {
47  
48      public static void deleteGroup(long companyId, long groupId) {
49          _instance._deleteGroup(companyId, groupId);
50      }
51  
52      public static Set<Long> getGroupUsers(long companyId, long groupId) {
53          return _instance._getGroupUsers(
54              _instance._getLiveUsers(companyId), groupId);
55      }
56  
57      public static int getGroupUsersCount(long companyId, long groupId) {
58          return getGroupUsers(companyId, groupId).size();
59      }
60  
61      public static Map<String, UserTracker> getSessionUsers(long companyId) {
62          return _instance._getSessionUsers(companyId);
63      }
64  
65      public static int getSessionUsersCount(long companyId) {
66          return getSessionUsers(companyId).size();
67      }
68  
69      public static UserTracker getUserTracker(long companyId, String sessionId) {
70          return _instance._getUserTracker(companyId, sessionId);
71      }
72  
73      public static void joinGroup(long companyId, long groupId, long userId) {
74          _instance._joinGroup(companyId, groupId, userId);
75      }
76  
77      public static void joinGroup(long companyId, long groupId, long[] userIds) {
78          _instance._joinGroup(companyId, groupId, userIds);
79      }
80  
81      public static void leaveGroup(long companyId, long groupId, long userId) {
82          _instance._leaveGroup(companyId, groupId, userId);
83      }
84  
85      public static void leaveGroup(
86          long companyId, long groupId, long[] userIds) {
87  
88          _instance._leaveGroup(companyId, groupId, userIds);
89      }
90  
91      public static void signIn(
92              long companyId, long userId, String sessionId, String remoteAddr,
93              String remoteHost, String userAgent)
94          throws SystemException {
95  
96          _instance._signIn(
97              companyId, userId, sessionId, remoteAddr, remoteHost, userAgent);
98      }
99  
100     public static void signOut(long companyId, long userId, String sessionId)
101         throws SystemException {
102 
103         _instance._signOut(companyId, userId, sessionId);
104     }
105 
106     private LiveUsers() {
107     }
108 
109     private void _addUserTracker(
110         long companyId, long userId, UserTracker userTracker) {
111 
112         List<UserTracker> userTrackers = _getUserTrackers(companyId, userId);
113 
114         if (userTrackers != null) {
115             userTrackers.add(userTracker);
116         }
117         else {
118             userTrackers = new ArrayList<UserTracker>();
119 
120             userTrackers.add(userTracker);
121 
122             Map<Long, List<UserTracker>> userTrackersMap =
123                 _getUserTrackersMap(companyId);
124 
125             userTrackersMap.put(userId, userTrackers);
126         }
127     }
128 
129     private void _deleteGroup(long companyId, long groupId) {
130         Map<Long, Set<Long>> liveUsers = _getLiveUsers(companyId);
131 
132         liveUsers.remove(groupId);
133     }
134 
135     private Set<Long> _getGroupUsers(
136         Map<Long, Set<Long>> liveUsers, long groupId) {
137 
138         Set<Long> groupUsers = liveUsers.get(groupId);
139 
140         if (groupUsers == null) {
141             groupUsers = new ConcurrentHashSet<Long>();
142 
143             liveUsers.put(groupId, groupUsers);
144         }
145 
146         return groupUsers;
147     }
148 
149     private Map<Long, Set<Long>> _getLiveUsers(long companyId) {
150         String companyIdString = String.valueOf(companyId);
151 
152         Map<Long, Set<Long>> liveUsers = (Map<Long, Set<Long>>)WebAppPool.get(
153             companyIdString, WebKeys.LIVE_USERS);
154 
155         if (liveUsers == null) {
156             liveUsers = new ConcurrentHashMap<Long, Set<Long>>();
157 
158             WebAppPool.put(companyIdString, WebKeys.LIVE_USERS, liveUsers);
159         }
160 
161         return liveUsers;
162     }
163 
164     private Map<String, UserTracker> _getSessionUsers(long companyId) {
165         String companyIdString = String.valueOf(companyId);
166 
167         Map<String, UserTracker> sessionUsers =
168             (Map<String, UserTracker>)WebAppPool.get(
169                 companyIdString, WebKeys.LIVE_SESSION_USERS);
170 
171         if (sessionUsers == null) {
172             sessionUsers = new ConcurrentHashMap<String, UserTracker>();
173 
174             WebAppPool.put(
175                 companyIdString, WebKeys.LIVE_SESSION_USERS, sessionUsers);
176         }
177 
178         return sessionUsers;
179     }
180 
181     private UserTracker _getUserTracker(long companyId, String sessionId) {
182         Map<String, UserTracker> sessionUsers = _getSessionUsers(companyId);
183 
184         return sessionUsers.get(sessionId);
185     }
186 
187     private List<UserTracker> _getUserTrackers(long companyId, long userId) {
188         Map<Long, List<UserTracker>> userTrackersMap = _getUserTrackersMap(
189             companyId);
190 
191         return userTrackersMap.get(userId);
192     }
193 
194     private Map<Long, List<UserTracker>> _getUserTrackersMap(long companyId) {
195         String companyIdString = String.valueOf(companyId);
196 
197         Map<Long, List<UserTracker>> userTrackersMap =
198             (Map<Long, List<UserTracker>>)WebAppPool.get(
199                 companyIdString, WebKeys.LIVE_USER_TRACKERS);
200 
201         if (userTrackersMap == null) {
202             userTrackersMap = new ConcurrentHashMap<Long, List<UserTracker>>();
203 
204             WebAppPool.put(
205                 companyIdString, WebKeys.LIVE_USER_TRACKERS, userTrackersMap);
206         }
207 
208         return userTrackersMap;
209     }
210 
211     private void _joinGroup(long companyId, long groupId, long userId) {
212         Map<Long, Set<Long>> liveUsers = _getLiveUsers(companyId);
213 
214         Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
215 
216         if (_getUserTrackers(companyId, userId) != null) {
217             groupUsers.add(userId);
218         }
219     }
220 
221     private void _joinGroup(long companyId, long groupId, long[] userIds) {
222         Map<Long, Set<Long>> liveUsers = _getLiveUsers(companyId);
223 
224         Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
225 
226         for (long userId : userIds) {
227             if (_getUserTrackers(companyId, userId) != null) {
228                 groupUsers.add(userId);
229             }
230         }
231     }
232 
233     private void _leaveGroup(long companyId, long userId, long groupId) {
234         Map<Long, Set<Long>> liveUsers = _getLiveUsers(companyId);
235 
236         Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
237 
238         groupUsers.remove(userId);
239     }
240 
241     private void _leaveGroup(long companyId, long groupId, long[] userIds) {
242         Map<Long, Set<Long>> liveUsers = _getLiveUsers(companyId);
243 
244         Set<Long> groupUsers = _getGroupUsers(liveUsers, groupId);
245 
246         for (long userId : userIds) {
247             groupUsers.remove(userId);
248         }
249     }
250 
251     private void _removeUserTracker(
252         long companyId, long userId, UserTracker userTracker) {
253 
254         List<UserTracker> userTrackers = _getUserTrackers(companyId, userId);
255 
256         if (userTrackers != null) {
257             String sessionId = userTracker.getSessionId();
258 
259             Iterator<UserTracker> itr = userTrackers.iterator();
260 
261             while (itr.hasNext()) {
262                 UserTracker curUserTracker = itr.next();
263 
264                 if (sessionId.equals(curUserTracker.getSessionId())) {
265                     itr.remove();
266                 }
267             }
268 
269             if (userTrackers.size() == 0) {
270                 Map<Long, List<UserTracker>> userTrackersMap =
271                     _getUserTrackersMap(companyId);
272 
273                 userTrackersMap.remove(userId);
274             }
275         }
276     }
277 
278     private void _signIn(
279             long companyId, long userId, String sessionId, String remoteAddr,
280             String remoteHost, String userAgent)
281         throws SystemException {
282 
283         _updateGroupStatus(companyId, userId, true);
284 
285         Map<String, UserTracker> sessionUsers = _getSessionUsers(companyId);
286 
287         UserTracker userTracker = sessionUsers.get(sessionId);
288 
289         if ((userTracker == null) &&
290             (PropsValues.SESSION_TRACKER_MEMORY_ENABLED)) {
291 
292             userTracker = UserTrackerUtil.create(0);
293 
294             userTracker.setCompanyId(companyId);
295             userTracker.setUserId(userId);
296             userTracker.setModifiedDate(new Date());
297             userTracker.setSessionId(sessionId);
298             userTracker.setRemoteAddr(remoteAddr);
299             userTracker.setRemoteHost(remoteHost);
300             userTracker.setUserAgent(userAgent);
301 
302             sessionUsers.put(sessionId, userTracker);
303 
304             _addUserTracker(companyId, userId, userTracker);
305         }
306     }
307 
308     private void _signOut(long companyId, long userId, String sessionId)
309         throws SystemException {
310 
311         List<UserTracker> userTrackers = _getUserTrackers(companyId, userId);
312 
313         if ((userTrackers == null) || (userTrackers.size() <= 1)) {
314             _updateGroupStatus(companyId, userId, false);
315         }
316 
317         Map<String, UserTracker> sessionUsers = _getSessionUsers(companyId);
318 
319         UserTracker userTracker = sessionUsers.remove(sessionId);
320 
321         if (userTracker != null) {
322             try {
323                 UserTrackerLocalServiceUtil.addUserTracker(
324                     userTracker.getCompanyId(), userTracker.getUserId(),
325                     userTracker.getModifiedDate(), sessionId,
326                     userTracker.getRemoteAddr(), userTracker.getRemoteHost(),
327                     userTracker.getUserAgent(), userTracker.getPaths());
328             }
329             catch (Exception e) {
330                 if (_log.isWarnEnabled()) {
331                     _log.warn(e.getMessage());
332                 }
333             }
334 
335             _removeUserTracker(companyId, userId, userTracker);
336         }
337     }
338 
339     private Map<Long, Set<Long>> _updateGroupStatus(
340             long companyId, long userId, boolean signedIn)
341         throws SystemException {
342 
343         Map<Long, Set<Long>> liveUsers = _getLiveUsers(companyId);
344 
345         LinkedHashMap<String, Object> groupParams =
346             new LinkedHashMap<String, Object>();
347 
348         groupParams.put("usersGroups", userId);
349 
350         List<Group> communities = GroupLocalServiceUtil.search(
351             companyId, null, null, groupParams, QueryUtil.ALL_POS,
352             QueryUtil.ALL_POS);
353 
354         for (Group community : communities) {
355             Set<Long> groupUsers = _getGroupUsers(
356                 liveUsers, community.getGroupId());
357 
358             if (signedIn) {
359                 groupUsers.add(userId);
360             }
361             else {
362                 groupUsers.remove(userId);
363             }
364         }
365 
366         return liveUsers;
367     }
368 
369     private static Log _log = LogFactoryUtil.getLog(LiveUsers.class);
370 
371     private static LiveUsers _instance = new LiveUsers();
372 
373 }