001/**
002 * Copyright (C) 2014  Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
003 *
004 * This file is part of Dicoogle/dicoogle.
005 *
006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * Dicoogle/dicoogle is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with Dicoogle.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package pt.ua.dicoogle.server.users;
020
021import java.rmi.RemoteException;
022import java.util.HashMap;
023import java.util.Iterator;
024import org.slf4j.LoggerFactory;
025import pt.ua.dicoogle.rGUI.interfaces.controllers.IActiveSessions;
026import pt.ua.dicoogle.rGUI.server.UserFeatures;
027
028/**
029 *
030 * @author Samuel Campos <samuelcampos@ua.pt>
031 */
032public class UserSessions implements IActiveSessions {
033
034    //Active users lists
035    private HashMap<Integer, UserON> usersTable;
036    private HashMap<Integer, UserFeatures> usersFeatures;
037    // Saves the current administrator's user
038    private int adminID;
039    // Actual ID in Table
040    private int ID;
041    private static UserSessions instance = null;
042
043    public static synchronized UserSessions getInstance() {
044        if (instance == null) {
045            instance = new UserSessions();
046        }
047
048        return instance;
049    }
050
051    private UserSessions() {
052        usersTable = new HashMap<Integer, UserON>();
053        usersFeatures = new HashMap<Integer, UserFeatures>();
054
055        ID = 0;
056        adminID = - 1;
057    }
058
059    /**
060     *
061     * @param username
062     * @param host
063     * @return user session ID
064     */
065    public int userLogin(User user, String host, UserFeatures userF) {
066        if (userF == null) {
067            throw new NullPointerException("UserFeatures can't be null!");
068        }
069
070        int id = login(user, host, false);
071
072        usersFeatures.put(id, userF);
073        return id;
074    }
075
076    /**
077     *
078     * @param username
079     * @param host
080     * @return false if the administrator is already connected
081     */
082    public synchronized int adminLogin(User adminUser, String host) {
083        if (adminID == -1 && adminUser.isAdmin()) {
084            adminID = login(adminUser, host, true);
085
086            return adminID;
087        }
088
089        return -1;
090    }
091
092    private int login(User user, String host, boolean admin) {
093        int returnValue = ID;
094
095        usersTable.put(ID, new UserON(ID, user.getUsername(), host));
096
097        //write the log
098        LoggerFactory.getLogger(UserSessions.class).info("{} - {} : {} logged in",
099                new Object[]{host, user.getUsername(), admin ? "administrator" : "user"});
100//        UserSessionsLog.getInstance().login(user.getUsername(), host, admin);
101
102        //increase and mantain ID as a positive integer
103        ID = (ID + 1) & Integer.MAX_VALUE;
104
105        return returnValue;
106    }
107
108    /**
109     * Set the UserFeatures related to admin
110     * @param userF
111     * @return
112     */
113    public boolean setAdminUserFeatures(UserFeatures userF) {
114        if (!usersFeatures.containsKey(adminID)) {
115            usersFeatures.put(adminID, userF);
116            return true;
117        }
118
119        return false;
120    }
121
122    /**
123     * Remove one user from active users list
124     *
125     * @param userID
126     * @return  true if the user exists and has been removed from the list
127     */
128    public boolean userLogout(UserFeatures userF) {
129        int id;
130        Iterator<Integer> en = usersFeatures.keySet().iterator();
131
132        while (en.hasNext()) {
133            id = en.next();
134
135            //this is a workarround, must be more efficient
136            if (usersFeatures.get(id) == userF) {
137                //usersFeatures.remove(id);
138                en.remove();
139                UserON user = usersTable.remove(id);
140
141                if (user != null) {
142                    LoggerFactory.getLogger(UserSessions.class).info("{} - {} : user logged out",
143                            user.getHost(), user.getUsername());
144//                    UserSessionsLog.getInstance().logout(user.getUsername(), user.getHost(), false);
145                }
146
147                return true;
148            }
149        }
150
151        return false;
152    }
153
154    public synchronized void adminLogout() {
155        if (adminID != -1) {
156            UserON user = usersTable.get(adminID);
157
158            if (user != null) {
159                    LoggerFactory.getLogger(UserSessions.class).info("{} - {} : administrator logged out",
160                            user.getHost(), user.getUsername());
161//                UserSessionsLog.getInstance().logout(user.getUsername(), user.getHost(), true);
162            }
163        }
164        adminID = -1;
165    }
166
167    /**
168     *
169     * @return the current usersTable
170     * @throws RemoteException
171     */
172    @Override
173    public HashMap<Integer, UserON> getUsersTable() throws RemoteException {
174        return usersTable;
175    }
176
177    /**
178     * Logout one user 
179     *
180     * @param userID
181     * @return
182     * @throws RemoteException
183     */
184    @Override
185    public boolean adminLogoutUser(int userID) throws RemoteException {
186        boolean value = false;
187
188        UserFeatures userF;
189
190        if ((userF = usersFeatures.get(userID)) != null) {
191            try {
192                userF.logout();
193                value = true;
194
195            } catch (RemoteException ex) {
196                LoggerFactory.getLogger(UserSessions.class).error(ex.getMessage(), ex);
197            }
198        }
199
200        return value;
201    }
202
203    @Override
204    public int getAdminID() throws RemoteException {
205        return adminID;
206    }
207
208    /*
209     * Logout All Users
210     */
211    public void adminLogoutAllUsers() throws RemoteException {
212        Iterator<Integer> en = usersFeatures.keySet().iterator();
213        UserFeatures userF;
214
215        while (en.hasNext()) {
216            userF = usersFeatures.get(en.next());
217            if (userF != null) {
218                try {
219                    userF.logout();
220                } catch (RemoteException ex) {
221                    LoggerFactory.getLogger(UserSessions.class).error(ex.getMessage(), ex);
222                }
223            }
224        }
225    }
226
227    public void loginFailed(String username, String host, boolean admin) {
228        LoggerFactory.getLogger(UserSessions.class).info("{} - {} : {} login failed",
229                new Object[]{username, host, admin ? "administrator" : "user"});
230        //UserSessionsLog.getInstance().loginFailed(username, host, admin);
231    }
232}