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.rGUI.server;
020
021import java.rmi.NoSuchObjectException;
022import java.util.Timer;
023import java.util.TimerTask;
024import org.slf4j.LoggerFactory;
025
026import java.rmi.RemoteException;
027import java.rmi.server.UnicastRemoteObject;
028import javax.rmi.ssl.SslRMIServerSocketFactory;
029
030import pt.ua.dicoogle.Main;
031import pt.ua.dicoogle.rGUI.interfaces.controllers.INetworkInterfaces;
032import pt.ua.dicoogle.rGUI.interfaces.controllers.IPluginControllerAdmin;
033
034import pt.ua.dicoogle.server.ControlServices;
035import pt.ua.dicoogle.core.ServerSettings;
036import pt.ua.dicoogle.core.XMLSupport;
037import pt.ua.dicoogle.rGUI.MultihomeSslRMIClientSocketFactory;
038
039import pt.ua.dicoogle.rGUI.RFileBrowser.IRemoteFileSystem;
040import pt.ua.dicoogle.rGUI.RFileBrowser.RemoteFileSystemServer;
041
042import pt.ua.dicoogle.rGUI.interfaces.IAdmin;
043import pt.ua.dicoogle.rGUI.interfaces.IUser;
044import pt.ua.dicoogle.rGUI.interfaces.controllers.IAccessList;
045import pt.ua.dicoogle.rGUI.interfaces.controllers.IDirectory;
046import pt.ua.dicoogle.rGUI.interfaces.controllers.IIndexOptions;
047import pt.ua.dicoogle.rGUI.interfaces.controllers.ILogs;
048import pt.ua.dicoogle.rGUI.interfaces.controllers.IQRServers;
049import pt.ua.dicoogle.rGUI.interfaces.controllers.IQueryRetrieve;
050import pt.ua.dicoogle.rGUI.interfaces.controllers.ISOPClass;
051import pt.ua.dicoogle.rGUI.interfaces.controllers.IServices;
052import pt.ua.dicoogle.rGUI.interfaces.controllers.IStartupServ;
053import pt.ua.dicoogle.rGUI.interfaces.controllers.ITaskList;
054import pt.ua.dicoogle.rGUI.interfaces.controllers.IUsersManager;
055import pt.ua.dicoogle.rGUI.interfaces.controllers.IActiveSessions;
056import pt.ua.dicoogle.rGUI.interfaces.controllers.IPendingMessages;
057
058import pt.ua.dicoogle.rGUI.server.controllers.AccessList;
059import pt.ua.dicoogle.rGUI.server.controllers.DirectorySettings;
060import pt.ua.dicoogle.rGUI.server.controllers.IndexOptions;
061import pt.ua.dicoogle.rGUI.server.controllers.Logs;
062import pt.ua.dicoogle.rGUI.server.controllers.PendingMessages;
063import pt.ua.dicoogle.rGUI.server.controllers.QRServers;
064import pt.ua.dicoogle.rGUI.server.controllers.QueryRetrieve;
065import pt.ua.dicoogle.rGUI.server.controllers.SOPClass;
066import pt.ua.dicoogle.rGUI.server.controllers.StartupServices;
067import pt.ua.dicoogle.rGUI.server.controllers.TaskList;
068import pt.ua.dicoogle.rGUI.server.controllers.UsersManager;
069import pt.ua.dicoogle.rGUI.server.controllers.NetworkInterfaces;
070import pt.ua.dicoogle.rGUI.server.controllers.PluginController4Admin;
071import pt.ua.dicoogle.server.users.User;
072import pt.ua.dicoogle.server.users.UserSessions;
073
074/**
075 * This class serves to provide access to administration features
076 *
077 * @author Samuel Campos <samuelcampos@ua.pt>
078 */
079@Deprecated
080public class AdminFeatures implements IAdmin {
081
082    private static AdminFeatures instance = null;
083
084    private XMLSupport xmlSupport;
085
086    private Timer timer;
087    private static int timeoutTime = 15000; //15 seconds
088    private TimerTask task;
089    private boolean timeoutCanceled = false;
090
091    private User user;
092
093    private int port;
094
095    private IUser userStub = null;     //reference to stub of UserFeatures
096
097    public static synchronized AdminFeatures getInstance() {
098        if (instance == null) {
099            instance = new AdminFeatures();
100        }
101
102        return instance;
103    }
104
105    private AdminFeatures() {
106        xmlSupport = new XMLSupport();
107
108        port = ServerSettings.getInstance().getRemoteGUIPort();
109    }
110
111    @Override
112    public IServices getServices() throws RemoteException {
113        try{
114            return (IServices) UnicastRemoteObject.toStub(ControlServices.getInstance());
115        }catch(NoSuchObjectException ex){
116            return (IServices) UnicastRemoteObject.exportObject(ControlServices.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
117        }
118    }
119
120    @Override
121    public IQRServers getQRServers() throws RemoteException {
122        try{
123            return (IQRServers) UnicastRemoteObject.toStub(QRServers.getInstance());
124        }catch(NoSuchObjectException ex){
125            return (IQRServers) UnicastRemoteObject.exportObject(QRServers.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
126        }
127    }
128
129    @Override
130    public ILogs getLogs() throws RemoteException {
131        try{
132            return (ILogs) UnicastRemoteObject.toStub(Logs.getInstance());
133        }catch(NoSuchObjectException ex){
134            return (ILogs) UnicastRemoteObject.exportObject(Logs.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
135        }
136    }
137
138    @Override
139    public IStartupServ getStartupServ() throws RemoteException {
140        try{
141            return (IStartupServ) UnicastRemoteObject.toStub(StartupServices.getInstance());
142        }catch(NoSuchObjectException ex){
143            return (IStartupServ) UnicastRemoteObject.exportObject(StartupServices.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
144        }
145    }
146
147    @Override
148    public IQueryRetrieve getQueryRetrive() throws RemoteException {
149        try{
150            return (IQueryRetrieve) UnicastRemoteObject.toStub(QueryRetrieve.getInstance());
151        }catch(NoSuchObjectException ex){
152            return (IQueryRetrieve) UnicastRemoteObject.exportObject(QueryRetrieve.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
153        }
154    }
155
156    @Override
157    public IAccessList getAccessList() throws RemoteException {
158        try{
159            return (IAccessList) UnicastRemoteObject.toStub(AccessList.getInstance());
160        }catch(NoSuchObjectException ex){
161            return (IAccessList) UnicastRemoteObject.exportObject(AccessList.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
162        }
163    }
164
165    @Override
166    public IIndexOptions getIndexOptions() throws RemoteException {
167        try{
168            return (IIndexOptions) UnicastRemoteObject.toStub(IndexOptions.getInstance());
169        }catch(NoSuchObjectException ex){
170            return (IIndexOptions) UnicastRemoteObject.exportObject(IndexOptions.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
171        }
172    }
173
174    @Override
175    public ISOPClass getSOPClass() throws RemoteException {
176        try{
177            return (ISOPClass) UnicastRemoteObject.toStub(SOPClass.getInstance());
178        }catch(NoSuchObjectException ex){
179            return (ISOPClass) UnicastRemoteObject.exportObject(SOPClass.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
180        }
181    }
182
183    @Override
184    public IDirectory getDirectorySettings() throws RemoteException {
185        try{
186            return (IDirectory) UnicastRemoteObject.toStub(DirectorySettings.getInstance());
187        }catch(NoSuchObjectException ex){
188            return (IDirectory) UnicastRemoteObject.exportObject(DirectorySettings.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
189        }
190    }
191
192    @Override
193    public IUsersManager getUsersManager() throws RemoteException {
194        try{
195            return (IUsersManager) UnicastRemoteObject.toStub(UsersManager.getInstance());
196        }catch(NoSuchObjectException ex){
197            return (IUsersManager) UnicastRemoteObject.exportObject(UsersManager.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
198        }
199    }
200
201
202    @Override
203    public IActiveSessions getActiveSessions() throws RemoteException {
204        try{
205            return (IActiveSessions) UnicastRemoteObject.toStub(UserSessions.getInstance());
206        }catch(NoSuchObjectException ex){
207            return (IActiveSessions) UnicastRemoteObject.exportObject(UserSessions.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
208        }
209    }
210
211
212    /**
213     * @return the taskList
214     */
215    @Override
216    public ITaskList getTaskList() throws RemoteException{
217        try{
218            return (ITaskList) UnicastRemoteObject.toStub(TaskList.getInstance());
219        }catch(NoSuchObjectException ex){
220            return (ITaskList) UnicastRemoteObject.exportObject(TaskList.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
221        }
222    }
223
224    /**
225     * @return the pending messages controler remote reference
226     */
227    @Override
228    public IPendingMessages getPendingMessages() throws RemoteException{
229        try{
230            return (IPendingMessages) UnicastRemoteObject.toStub(PendingMessages.getInstance());
231        }catch(NoSuchObjectException ex){
232            return (IPendingMessages) UnicastRemoteObject.exportObject(PendingMessages.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
233        }
234    }
235
236    @Override
237    public IRemoteFileSystem getRFS() throws RemoteException {
238        try{
239            return (IRemoteFileSystem) UnicastRemoteObject.toStub(RemoteFileSystemServer.getInstance());
240        }catch(NoSuchObjectException ex){
241            return (IRemoteFileSystem) UnicastRemoteObject.exportObject(RemoteFileSystemServer.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
242        }
243    }
244    
245    @Override
246    public IPluginControllerAdmin getPluginController() throws RemoteException
247    {
248        try{
249            return (IPluginControllerAdmin) UnicastRemoteObject.toStub(PluginController4Admin.getInstance());
250        }catch(NoSuchObjectException ex){
251            return (IPluginControllerAdmin) UnicastRemoteObject.exportObject(PluginController4Admin.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
252        }
253
254    }
255
256    
257    @Override
258    public INetworkInterfaces getNetworkInterface() throws RemoteException {
259        try{
260            return (INetworkInterfaces) UnicastRemoteObject.toStub(NetworkInterfaces.getInstance());
261        }catch(NoSuchObjectException ex){
262            return (INetworkInterfaces) UnicastRemoteObject.exportObject(NetworkInterfaces.getInstance(), port, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
263        }
264    }
265
266
267    /**
268     * Unexport all the remote objects related to the administration
269     * 
270     * @throws RemoteException
271     */
272    @Override
273    public void logout() throws RemoteException {
274        timer.cancel();
275
276        // reset the signalBack object reference
277        TaskList.getInstance().resetSignalBack();
278        Logs.getInstance().resetSignalBack();
279        PendingMessages.getInstance().resetSignalBack();
280
281        try {
282            UnicastRemoteObject.unexportObject(ControlServices.getInstance(), true);
283        } catch (NoSuchObjectException ex) {}; 
284
285        try {
286            UnicastRemoteObject.unexportObject(QRServers.getInstance(), true);
287        } catch (NoSuchObjectException ex) {}; 
288
289        try {
290            UnicastRemoteObject.unexportObject(Logs.getInstance(), true);
291        } catch (NoSuchObjectException ex) {}; 
292
293        try {
294            UnicastRemoteObject.unexportObject(StartupServices.getInstance(), true);
295        } catch (NoSuchObjectException ex) {}; 
296
297        try {
298            UnicastRemoteObject.unexportObject(QueryRetrieve.getInstance(), true);
299        } catch (NoSuchObjectException ex) {}; 
300
301        try {
302            UnicastRemoteObject.unexportObject(AccessList.getInstance(), true);
303        } catch (NoSuchObjectException ex) {}; 
304
305        try {
306            UnicastRemoteObject.unexportObject(IndexOptions.getInstance(), true);
307        } catch (NoSuchObjectException ex) {}; 
308
309        try {
310            UnicastRemoteObject.unexportObject(SOPClass.getInstance(), true);
311        } catch (NoSuchObjectException ex) {}; 
312
313        try {
314            UnicastRemoteObject.unexportObject(DirectorySettings.getInstance(), true);
315        } catch (NoSuchObjectException ex) {}; 
316
317        try {
318            UnicastRemoteObject.unexportObject(UsersManager.getInstance(), true);
319        } catch (NoSuchObjectException ex) {}; 
320        
321        try {
322            UnicastRemoteObject.unexportObject(UserSessions.getInstance(), true);
323        } catch (NoSuchObjectException ex) {}; 
324
325        try {
326            UnicastRemoteObject.unexportObject(RemoteFileSystemServer.getInstance(), true);
327        } catch (NoSuchObjectException ex) {}; 
328        
329        
330        try {
331            UnicastRemoteObject.unexportObject(TaskList.getInstance(), true);
332        } catch (NoSuchObjectException ex) {}; 
333        
334        try {
335            UnicastRemoteObject.unexportObject(PendingMessages.getInstance(), true);
336        } catch (NoSuchObjectException ex) {}; 
337
338        try {
339            UnicastRemoteObject.unexportObject(NetworkInterfaces.getInstance(), true);
340        } catch (NoSuchObjectException ex) {};  
341        
342        try {
343            UnicastRemoteObject.unexportObject(PluginController4Admin.getInstance(), true);
344        } catch (NoSuchObjectException ex) {};  
345        
346        
347        resetSettings();
348
349        this.user = null;
350        userStub = null;
351        timeoutCanceled = false;
352
353        //removes the administrator session
354        UserSessions.getInstance().adminLogout();
355        
356        // unexport this object
357        try {
358            UnicastRemoteObject.unexportObject(this, true);
359        } catch (NoSuchObjectException ex) {};    
360    }
361
362    /**
363     * Save ServerSettings
364     *  This funcion has to call the other "save" functions of the administration object
365     *  Finnaly it has to print XML with new ServerSettings
366     *
367     * @throws RemoteException
368     */
369    @Override
370    public void saveSettings() throws RemoteException {
371
372        StartupServices.getInstance().saveSettings();
373        QueryRetrieve.getInstance().saveSettings();
374        AccessList.getInstance().saveSettings();
375        IndexOptions.getInstance().saveSettings();
376        DirectorySettings.getInstance().saveSettings();
377        QRServers.getInstance().saveSettings();
378        UsersManager.getInstance().saveSettings();
379
380        xmlSupport.printXML();
381        /**
382         * ATTENTION: this settings are stored appart from the others in the
383         * filepath: /plugins/settings/PLUGIN_NAME.settings
384         * They are also stored in binary format instead of XML.
385         */
386        PluginController4Admin.getInstance().saveSettings();
387        
388        //DebugManager.getInstance().debug("Settings saved!");
389    }
390
391    /**
392     * check if there ara unsaved Settings
393     *
394     * @return true if there are unsaved settings
395     * @throws RemoteException
396     */
397    @Override
398    public boolean unsavedSettings() throws RemoteException {
399        return StartupServices.getInstance().unsavedSettings() || QueryRetrieve.getInstance().unsavedSettings()
400                || AccessList.getInstance().unsavedSettings() || IndexOptions.getInstance().unsavedSettings()
401                || DirectorySettings.getInstance().unsavedSettings() || QRServers.getInstance().unsavedSettings()
402                || UsersManager.getInstance().unsavedSettings();
403    }
404
405    
406
407    @Override
408    public String getDefaultFilePath() throws RemoteException {
409        return ServerSettings.getInstance().getPath();
410    }
411
412    
413    /**
414     * Restore settings, discard all unsaved settings
415     * 
416     * @throws RemoteException
417     */
418    @Override
419    public void resetSettings() throws RemoteException {
420        if (StartupServices.getInstance().unsavedSettings()) {
421            StartupServices.getInstance().loadSettings();
422        }
423
424        if (QueryRetrieve.getInstance().unsavedSettings()) {
425            QueryRetrieve.getInstance().loadSettings();
426        }
427
428        if (AccessList.getInstance().unsavedSettings()) {
429            AccessList.getInstance().loadSettings();
430        }
431
432        if (IndexOptions.getInstance().unsavedSettings()) {
433            IndexOptions.getInstance().loadSettings();
434        }
435
436        if (DirectorySettings.getInstance().unsavedSettings()) {
437            DirectorySettings.getInstance().loadSettings();
438        }
439
440        if (QRServers.getInstance().unsavedSettings()) {
441            QRServers.getInstance().loadSettings();
442        }
443
444        if (UsersManager.getInstance().unsavedSettings()) {
445            UsersManager.getInstance().loadSettings();
446        }
447    }
448
449    @Override
450    public String getUsername() throws RemoteException {
451        if (user != null) {
452            return user.getUsername();
453        }
454
455        return null;
456    }
457
458    @Override
459    public void KeepAlive() throws RemoteException {
460        if(!timeoutCanceled){
461            task.cancel();
462            timer.purge();
463
464            task = new TimeOut();
465            timer.schedule(task, timeoutTime, timeoutTime);
466        }
467    }
468
469    @Override
470    public IUser getUser() throws RemoteException {
471        if (userStub == null) {
472            UserFeatures userF = new UserFeatures(user);
473            UserSessions.getInstance().setAdminUserFeatures(userF); //saves the UserFeatures of this admin
474
475            userStub = (IUser) UnicastRemoteObject.exportObject(userF, 0, new MultihomeSslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
476        }
477
478        return userStub;
479    }
480
481    
482    public void setUser(User user) {
483        this.user = user;
484        
485        timer = new Timer();
486        task = new TimeOut();
487
488        timer.schedule(task, timeoutTime, timeoutTime); 
489    }
490
491    @Override
492    public void shutdownServer() throws RemoteException {
493        //shutdown the services
494        ControlServices.getInstance().stopAllServices();
495
496        //logout the admin
497        this.logout();
498
499        //logout the users
500        UserSessions.getInstance().adminLogoutAllUsers();
501
502        //DebugManager.getInstance().debug("The Server is Shutting Down!");
503        
504        //close Dicoogle Server
505        System.exit(0);
506    }
507
508    
509    /**
510     * If the number is equal to the number randomly generated
511     * in Main class, the timetout stops.
512     *
513     * @param number
514     * @return if the number is equal or not
515     * @throws RemoteException
516     */
517    @Override
518    public boolean shtudownTimeout(int number) throws RemoteException {
519        if(number == Main.randomInteger){
520            timeoutCanceled = true;
521            task.cancel();
522            timer.purge();
523
524            return true;
525        }
526        return false;
527    }
528
529
530    /**
531     * This class extends TimerTask
532     * and when the run method is called the admin logout
533     */
534    private class TimeOut extends TimerTask {
535
536        @Override
537        public void run() {
538            try {
539                logout();
540            } catch (RemoteException ex) {
541                LoggerFactory.getLogger(UserFeatures.class).error(ex.getMessage(), ex);
542            }
543        }
544    }
545}