1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
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.CollectionFactory;
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  
45  import javax.servlet.http.HttpServletRequest;
46  import javax.servlet.http.HttpSession;
47  
48  import org.apache.commons.logging.Log;
49  import org.apache.commons.logging.LogFactory;
50  
51  /**
52   * <a href="LiveUsers.java.html"><b><i>View Source</i></b></a>
53   *
54   * @author Charles May
55   * @author Brian Wing Shun Chan
56   *
57   */
58  public class LiveUsers {
59  
60      public static void deleteGroup(long groupId) {
61          _instance._deleteGroup(groupId);
62      }
63  
64      public static Set getGroupUsers(long groupId) {
65          return _instance._getGroupUsers(_instance._getLiveUsers(), groupId);
66      }
67  
68      public static int getGroupUsersCount(long groupId) {
69          return getGroupUsers(groupId).size();
70      }
71  
72      public static Map getSessionUsers() {
73          return _instance._getSessionUsers(_instance._getLiveUsers());
74      }
75  
76      public static int getSessionUsersCount() {
77          return getSessionUsers().size();
78      }
79  
80      public static UserTracker getUserTracker(String sesId) {
81          return _instance._getUserTracker(sesId);
82      }
83  
84      public static void joinGroup(long userId, long groupId) {
85          _instance._joinGroup(userId, groupId);
86      }
87  
88      public static void joinGroup(long[] userIds, long groupId) {
89          _instance._joinGroup(userIds, groupId);
90      }
91  
92      public static void leaveGroup(long userId, long groupId) {
93          _instance._leaveGroup(userId, groupId);
94      }
95  
96      public static void leaveGroup(long[] userIds, long groupId) {
97          _instance._leaveGroup(userIds, groupId);
98      }
99  
100     public static void signIn(HttpServletRequest req) throws SystemException {
101         _instance._signIn(req);
102     }
103 
104     public static void signOut(String sesId, long userId)
105         throws SystemException {
106 
107         _instance._signOut(sesId, userId);
108     }
109 
110     private LiveUsers() {
111     }
112 
113     private void _addUserTracker(long userId, UserTracker userTracker) {
114         List userTrackers = _getUserTrackers(userId);
115 
116         if (userTrackers != null) {
117             userTrackers.add(userTracker);
118         }
119         else {
120             userTrackers = new ArrayList();
121 
122             userTrackers.add(userTracker);
123 
124             Map userTrackersMap = _getUserTrackersMap();
125 
126             userTrackersMap.put(new Long(userId), userTrackers);
127         }
128     }
129 
130     private void _deleteGroup(long groupId) {
131         Map liveUsers = _getLiveUsers();
132 
133         liveUsers.remove(new Long(groupId));
134     }
135 
136     private Set _getGroupUsers(Map liveUsers, long groupId) {
137         Long groupIdObj = new Long(groupId);
138 
139         Set groupUsers = (Set)liveUsers.get(groupIdObj);
140 
141         if (groupUsers == null) {
142             groupUsers = CollectionFactory.getSyncHashSet();
143 
144             liveUsers.put(groupIdObj, groupUsers);
145         }
146 
147         return groupUsers;
148     }
149 
150     private Map _getLiveUsers() {
151         String companyIdString = String.valueOf(
152             CompanyThreadLocal.getCompanyId());
153 
154         Map liveUsers = (Map)WebAppPool.get(
155             companyIdString, WebKeys.LIVE_USERS);
156 
157         if (liveUsers == null) {
158             liveUsers = CollectionFactory.getSyncHashMap();
159 
160             WebAppPool.put(companyIdString, WebKeys.LIVE_USERS, liveUsers);
161         }
162 
163         return liveUsers;
164     }
165 
166     private Map _getSessionUsers(Map liveUsers) {
167         Long groupIdObj = new Long(0);
168 
169         Map sessionUsers = (Map)liveUsers.get(groupIdObj);
170 
171         if (sessionUsers == null) {
172             sessionUsers = CollectionFactory.getSyncHashMap();
173 
174             liveUsers.put(groupIdObj, sessionUsers);
175         }
176 
177         return sessionUsers;
178     }
179 
180     private UserTracker _getUserTracker(String sesId) {
181         Map liveUsers = _getLiveUsers();
182 
183         Map sessionUsers = _getSessionUsers(liveUsers);
184 
185         return (UserTracker)sessionUsers.get(sesId);
186     }
187 
188     private List _getUserTrackers(long userId) {
189         Map userTrackersMap = _getUserTrackersMap();
190 
191         return (List)userTrackersMap.get(new Long(userId));
192     }
193 
194     private Map _getUserTrackersMap() {
195         Map liveUsers = _getLiveUsers();
196 
197         Long groupIdObj = new Long(-1);
198 
199         Map userTrackersMap = (Map)liveUsers.get(groupIdObj);
200 
201         if (userTrackersMap == null) {
202             userTrackersMap = CollectionFactory.getSyncHashMap();
203 
204             liveUsers.put(groupIdObj, userTrackersMap);
205         }
206 
207         return userTrackersMap;
208     }
209 
210     private void _joinGroup(long userId, long groupId) {
211         Map liveUsers = _getLiveUsers();
212 
213         Set groupUsers = _getGroupUsers(liveUsers, groupId);
214 
215         if (_getUserTrackers(userId) != null) {
216             groupUsers.add(new Long(userId));
217         }
218     }
219 
220     private void _joinGroup(long[] userIds, long groupId) {
221         Map liveUsers = _getLiveUsers();
222 
223         Set groupUsers = _getGroupUsers(liveUsers, groupId);
224 
225         for (int i = 0; i < userIds.length; i++) {
226             long userId = userIds[i];
227 
228             if (_getUserTrackers(userId) != null) {
229                 groupUsers.add(new Long(userId));
230             }
231         }
232     }
233 
234     private void _leaveGroup(long userId, long groupId) {
235         Map liveUsers = _getLiveUsers();
236 
237         Set groupUsers = _getGroupUsers(liveUsers, groupId);
238 
239         groupUsers.remove(new Long(userId));
240     }
241 
242     private void _leaveGroup(long[] userIds, long groupId) {
243         Map liveUsers = _getLiveUsers();
244 
245         Set groupUsers = _getGroupUsers(liveUsers, groupId);
246 
247         for (int i = 0; i < userIds.length; i++) {
248             long userId = userIds[i];
249 
250             groupUsers.remove(new Long(userId));
251         }
252     }
253 
254     private void _removeUserTracker(long userId, UserTracker userTracker) {
255         List userTrackers = _getUserTrackers(userId);
256 
257         if (userTrackers != null) {
258             Iterator itr = userTrackers.iterator();
259 
260             while (itr.hasNext()) {
261                 UserTracker curUserTracker = (UserTracker)itr.next();
262 
263                 if (userTracker.equals(curUserTracker)) {
264                     itr.remove();
265                 }
266             }
267 
268             if (userTrackers.size() == 0) {
269                 Map userTrackersMap = _getUserTrackersMap();
270 
271                 userTrackersMap.remove(new Long(userId));
272             }
273         }
274     }
275 
276     private void _signIn(HttpServletRequest req) throws SystemException {
277         HttpSession ses = req.getSession();
278 
279         long companyId = CompanyThreadLocal.getCompanyId();
280         long userId = GetterUtil.getLong(req.getRemoteUser());
281 
282         Map liveUsers = _updateGroupStatus(userId, true);
283 
284         Map sessionUsers = _getSessionUsers(liveUsers);
285 
286         boolean simultaenousLogins = GetterUtil.getBoolean(
287             PropsUtil.get(PropsUtil.AUTH_SIMULTANEOUS_LOGINS), true);
288 
289         List userTrackers = _getUserTrackers(userId);
290 
291         if (!simultaenousLogins) {
292             if (userTrackers != null) {
293                 for (int i = 0; i < userTrackers.size(); i++) {
294                     UserTracker userTracker = (UserTracker)userTrackers.get(i);
295 
296                     // Disable old login
297 
298                     userTracker.getHttpSession().setAttribute(
299                         WebKeys.STALE_SESSION, Boolean.TRUE);
300                 }
301             }
302         }
303 
304         UserTracker userTracker = (UserTracker)sessionUsers.get(ses.getId());
305 
306         if ((userTracker == null) &&
307             (GetterUtil.getBoolean(PropsUtil.get(
308                 PropsUtil.SESSION_TRACKER_MEMORY_ENABLED)))) {
309 
310             userTracker = UserTrackerUtil.create(0);
311 
312             userTracker.setCompanyId(companyId);
313             userTracker.setUserId(userId);
314             userTracker.setModifiedDate(new Date());
315             userTracker.setHttpSession(ses);
316             userTracker.setRemoteAddr(req.getRemoteAddr());
317             userTracker.setRemoteHost(req.getRemoteHost());
318             userTracker.setUserAgent(req.getHeader(HttpHeaders.USER_AGENT));
319 
320             sessionUsers.put(ses.getId(), userTracker);
321 
322             _addUserTracker(userId, userTracker);
323         }
324     }
325 
326     private void _signOut(String sesId, long userId) throws SystemException {
327         List userTrackers = _getUserTrackers(userId);
328 
329         Map liveUsers = null;
330 
331         if ((userTrackers == null) || (userTrackers.size() <= 1)) {
332             liveUsers = _updateGroupStatus(userId, false);
333         }
334 
335         if (liveUsers == null) {
336             liveUsers = _getLiveUsers();
337         }
338 
339         Map sessionUsers = _getSessionUsers(liveUsers);
340 
341         UserTracker userTracker = (UserTracker)sessionUsers.remove(sesId);
342 
343         if (userTracker != null) {
344             try {
345                 UserTrackerLocalServiceUtil.addUserTracker(
346                     userTracker.getCompanyId(), userTracker.getUserId(),
347                     userTracker.getModifiedDate(), sesId,
348                     userTracker.getRemoteAddr(), userTracker.getRemoteHost(),
349                     userTracker.getUserAgent(), userTracker.getPaths());
350             }
351             catch (Exception e) {
352                 if (_log.isWarnEnabled()) {
353                     _log.warn(e.getMessage());
354                 }
355             }
356 
357             _removeUserTracker(userId, userTracker);
358         }
359     }
360 
361     private Map _updateGroupStatus(long userId, boolean signedIn)
362         throws SystemException {
363 
364         Long userIdObj = new Long(userId);
365 
366         long companyId = CompanyThreadLocal.getCompanyId();
367 
368         Map liveUsers = _getLiveUsers();
369 
370         LinkedHashMap groupParams = new LinkedHashMap();
371 
372         groupParams.put("usersGroups", userIdObj);
373 
374         List communities = GroupLocalServiceUtil.search(
375             companyId, null, null, groupParams, QueryUtil.ALL_POS,
376             QueryUtil.ALL_POS);
377 
378         for (int i = 0; i < communities.size(); i++) {
379             Group community = (Group)communities.get(i);
380 
381             Set groupUsers = _getGroupUsers(liveUsers, community.getGroupId());
382 
383             if (signedIn) {
384                 groupUsers.add(userIdObj);
385             }
386             else {
387                 groupUsers.remove(userIdObj);
388             }
389         }
390 
391         return liveUsers;
392     }
393 
394     private static Log _log = LogFactory.getLog(LiveUsers.class);
395 
396     private static LiveUsers _instance = new LiveUsers();
397 
398 }