001/*
002 * GWTEventService
003 * Copyright (c) 2011 and beyond, strawbill UG (haftungsbeschr?nkt)
004 *
005 * This is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU Lesser General Public License as
007 * published by the Free Software Foundation; either version 3 of
008 * the License, or (at your option) any later version.
009 * Other licensing for GWTEventService may also be possible on request.
010 * Please view the license.txt of the project for more information.
011 *
012 * This software is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this software; if not, write to the Free
019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021 */
022package de.novanic.eventservice.service.registry.user;
023
024import java.util.*;
025import java.util.concurrent.ConcurrentHashMap;
026import java.util.concurrent.ConcurrentMap;
027
028/**
029 * The UserManager is a container for {@link de.novanic.eventservice.service.registry.user.UserInfo} and provides various
030 * methods to manage users. To activate the user timeout recognition, the method {@link UserManager#activateUserActivityScheduler()})
031 * must be called. The UserManager can be created with {@link de.novanic.eventservice.service.registry.user.UserManagerFactory#getUserManager(long)})
032 * as a singleton.
033 *
034 * @author sstrohschein
035 *         <br>Date: 27.01.2009
036 *         <br>Time: 22:05:42
037 */
038public class DefaultUserManager implements UserManager
039{
040    private final ConcurrentMap<String, UserInfo> myUserMap;
041    private final UserActivityScheduler myUserActivityScheduler;
042
043    /**
044     * Creates a new UserManager. To create the UserManager as a singleton (default), the UserManager can be created with
045     * {@link de.novanic.eventservice.service.registry.user.UserManagerFactory#getUserManager(long)})
046     * @param aTimeoutInterval timeout interval (is only required if the {@link de.novanic.eventservice.service.registry.user.UserActivityScheduler}
047     * needs to be started).
048     */
049    public DefaultUserManager(long aTimeoutInterval) {
050        myUserMap = new ConcurrentHashMap<String, UserInfo>();
051        myUserActivityScheduler = new UserActivityScheduler(myUserMap.values(), aTimeoutInterval);
052    }
053
054    /**
055     * Creates and adds the {@link de.novanic.eventservice.service.registry.user.UserInfo} for the user id.
056     * @param aUserId id of the user to add
057     * @return created {@link de.novanic.eventservice.service.registry.user.UserInfo}
058     */
059    public UserInfo addUser(String aUserId) {
060        UserInfo theUserInfo = null;
061        if(aUserId != null) {
062            UserInfo theNewUserInfo = new UserInfo(aUserId);
063            theUserInfo = myUserMap.putIfAbsent(aUserId, theNewUserInfo);
064            if(theUserInfo == null) {
065                theUserInfo = theNewUserInfo;
066            }
067        }
068        return theUserInfo;
069    }
070
071    /**
072     * Adds the {@link de.novanic.eventservice.service.registry.user.UserInfo} to the UserManager.
073     * @param aUserInfo {@link de.novanic.eventservice.service.registry.user.UserInfo} to add
074     */
075    public void addUser(UserInfo aUserInfo) {
076        if(aUserInfo != null) {
077            myUserMap.put(aUserInfo.getUserId(), aUserInfo);
078        }
079    }
080
081    /**
082     * Removes the {@link de.novanic.eventservice.service.registry.user.UserInfo} for the user id.
083     * @param aUserId user id of the {@link de.novanic.eventservice.service.registry.user.UserInfo} to remove
084     * @return removed {@link de.novanic.eventservice.service.registry.user.UserInfo}
085     */
086    public UserInfo removeUser(String aUserId) {
087        if(aUserId != null) {
088            final UserInfo theUserInfo = myUserMap.remove(aUserId);
089            if(theUserInfo != null) {
090                theUserInfo.notifyEventListening();
091            }
092            return theUserInfo;
093        }
094        return null;
095    }
096
097    /**
098     * Removes the {@link de.novanic.eventservice.service.registry.user.UserInfo}.
099     * Observing threads get informed because it is not required to observe the removed user (anymore).
100     * @param aUserInfo {@link de.novanic.eventservice.service.registry.user.UserInfo} to remove
101     * @return true if it had an effect, otherwise false
102     */
103    public boolean removeUser(UserInfo aUserInfo) {
104        return aUserInfo != null && (removeUser(aUserInfo.getUserId()) != null);
105    }
106
107    /**
108     * Removes all added {@link UserInfo} objects.
109     * Observing threads get informed because it is not required to observe the removed users (anymore).
110     */
111    public void removeUsers() {
112        for(UserInfo theUserInfo: myUserMap.values()) {
113            theUserInfo.notifyEventListening();
114        }
115        myUserMap.clear();
116    }
117
118    /**
119     * Checks if a user is added to a domain.
120     * @param aUserInfo user
121     * @return true when the user is added to a domain, otherwise false
122     */
123    public boolean isUserContained(UserInfo aUserInfo) {
124        return myUserMap.containsKey(aUserInfo.getUserId());
125    }
126
127    /**
128     * Returns the {@link de.novanic.eventservice.service.registry.user.UserInfo} for the user id. It returns NULL when no
129     * {@link de.novanic.eventservice.service.registry.user.UserInfo} for the user id is added.
130     * @param aUserId user id of the requested {@link de.novanic.eventservice.service.registry.user.UserInfo}
131     * @return {@link de.novanic.eventservice.service.registry.user.UserInfo} for the user id. NULL when no
132     * {@link de.novanic.eventservice.service.registry.user.UserInfo} for the user id is added.
133     */
134    public UserInfo getUser(String aUserId) {
135        if(aUserId != null) {
136            return myUserMap.get(aUserId);
137        }
138        return null;
139    }
140
141    /**
142     * Returns the count of the added {@link de.novanic.eventservice.service.registry.user.UserInfo} objects.
143     * @return count of the added {@link de.novanic.eventservice.service.registry.user.UserInfo} objects
144     */
145    public int getUserCount() {
146        return myUserMap.size();
147    }
148
149    /**
150     * Returns all added {@link de.novanic.eventservice.service.registry.user.UserInfo} objects. It returns an empty
151     * {@link java.util.Collection} when no
152     * {@link de.novanic.eventservice.service.registry.user.UserInfo} objects are added.
153     * @return all added {@link de.novanic.eventservice.service.registry.user.UserInfo} objects
154     */
155    public Collection<UserInfo> getUsers() {
156        return myUserMap.values();
157    }
158
159    /**
160     * Activates the {@link UserActivityScheduler} to observe the user activities. When the users/clients should be
161     * removed automatically, please use {@link de.novanic.eventservice.service.registry.user.UserManager#activateUserActivityScheduler(boolean)}.
162     */
163    public void activateUserActivityScheduler() {
164        activateUserActivityScheduler(false);
165    }
166
167    /**
168     * Activates the {@link UserActivityScheduler} to observe the user activities.
169     * @param isAutoClean when set to true, the users/clients are removed automatically on timeout
170     */
171    public void activateUserActivityScheduler(boolean isAutoClean) {
172        myUserActivityScheduler.start(isAutoClean);
173    }
174
175    /**
176     * Deactivates the {@link UserActivityScheduler}. See {@link UserActivityScheduler} for more information.
177     */
178    public void deactivateUserActivityScheduler() {
179        myUserActivityScheduler.stop();
180    }
181
182    /**
183     * Returns the {@link UserActivityScheduler} which is instantiated with the UserManager. The method
184     * {@link UserManager#activateUserActivityScheduler()} must be called to start the {@link UserActivityScheduler}.
185     * @return the {@link UserActivityScheduler} which is instantiated with the UserManager
186     */
187    public UserActivityScheduler getUserActivityScheduler() {
188        return myUserActivityScheduler;
189    }
190
191    /**
192     * Resets the UserManager (removes all users, stops the user activity scheduler, etc.)
193     * Observing threads get informed because it is not required to observe the removed users (anymore).
194     */
195    public void reset() {
196        deactivateUserActivityScheduler();
197        removeUsers();
198    }
199}