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.core;
020
021import pt.ua.dicoogle.sdk.datastructs.MoveDestination;
022import java.net.*;
023import java.util.*;
024import java.util.concurrent.ConcurrentHashMap;
025import org.dcm4che2.data.UID;
026import org.slf4j.LoggerFactory;
027import pt.ua.dicoogle.sdk.core.ServerSettingsReader;
028import pt.ua.dicoogle.sdk.core.WebSettingsReader;
029
030import pt.ua.dicoogle.server.web.utils.types.DataTable;
031
032/** Singleton class of all server settings.
033 *
034 * @author Marco Pereira
035 * @author Luís A. Bastião Silva <bastiao@ua.pt>
036 * @author António Novo <antonio.novo@ua.pt>
037 * @author Eduardo Pinho <eduardopinho@ua.pt>
038 * @see XMLSupport
039 */
040public class ServerSettings implements ServerSettingsReader
041{
042    private String AETitle;
043
044    //Access List Settings
045    private String [] CAETitle;
046    private boolean permitAllAETitles;
047
048    private String Path;
049    private String ID;
050    private int storagePort;
051
052    @Deprecated
053    private int rGUIPort;
054    @Deprecated
055    private String RGUIExternalIP;
056
057    //Dicoogle Settings
058    private String dicoogleDir;
059    private boolean fullContentIndex;
060    private boolean saveThumbnails;
061    private String thumbnailsMatrix;
062    //private boolean P2P;
063
064    private boolean storage;
065    private boolean queryRetrieve;
066    private boolean encryptUsersFile;
067
068    /** 
069     * Indicates, for each plugin, if it is to start at server init or not.
070     */
071    private final ConcurrentHashMap<String, Boolean> autoStartPlugin; // NOTE the concurrent hash map is used to prevent having to synchronize the methods that use it
072
073    /**
074     * The name of the Remote GUI setting that indicates the External IP address.
075     */
076    public static final String RGUI_SETTING_EXTERNAL_IP = "External IP";
077
078    /**
079     * The name of the Query Retrieve setting that indicates the Maximum number of Client Associations.
080     */
081    public static final String QUERYRETRIEVE_MAX_ASSOCIATIONS = "Max. Associations";
082    /**
083     * The name of the Query Retrieve setting that indicates the Maximum PDU Length Receive.
084     */
085    public static final String QUERYRETRIEVE_MAX_PDU_RECEIVE = "Max. PDU Receive";
086    /**
087     * The name of the Query Retrieve setting that indicates the Maximum PDU Length Send.
088     */
089    public static final String QUERYRETRIEVE_MAX_PDU_SEND = "Max. PDU Send";
090    /**
091     * The name of the Query Retrieve setting that indicates the Idle Timeout.
092     */
093    public static final String QUERYRETRIEVE_IDLE_TIMEOUT = "Idle Timeout";
094    /**
095     * The name of the Query Retrieve setting that indicates the Accpet Timeout.
096     */
097    public static final String QUERYRETRIEVE_ACCEPT_TIMEOUT = "Accept Timeout";
098    /**
099     * The name of the Query Retrieve setting that indicates the Response Timeout.
100     */
101    public static final String QUERYRETRIEVE_RESPONSE_TIMEOUT = "Response Timeout";
102    /**
103     * The name of the Query Retrieve setting that indicates the Connection Timeout.
104     */
105    public static final String QUERYRETRIEVE_CONNECTION_TIMEOUT = "Connection Timeout";
106
107    /**
108     * The name of the Storage setting that indicates the Servers Destinations.
109     */
110    public static final String STORAGE_SETTING_SERVERS_DESTINATIONS = "Storage Servers Destinations";
111    /**
112     * The name of the Storage setting that indicates the Storage Path.
113     */
114    public static final String STORAGE_SETTING_PATH = "Storage Path";
115
116    /**
117     * The help for the Remote GUI External IP setting.
118     */
119    public static final String RGUI_SETTING_EXTERNAL_IP_HELP = "If your Dicoogle GUI Server is running behind a router, you need to provide your external IP address to have access from outside of the router.\nBesides that, you need to configure your router to open the Remote GUI Port!";
120
121    /**
122     * QueryRetrieve Server
123     */
124    
125    private boolean wlsOn = false ; 
126    
127    /* DEFAULT Brief class description */
128    private String deviceDescription ;
129    /* DEFAULT Process Worklist Server AE Title */
130    private String localAETName ;
131    
132    /* DEFAULT ("any"->null)Permited local interfaces to incomming connection
133     * ('null'->any interface; 'ethx'->only this interface |->separator */
134    private String permitedLocalInterfaces ;
135    
136    /* DEFAULT ("any"->null)Permited remote host name connections
137     * ('null'->any can connect; 'www.x.com'->only this can connect |->separator */
138    private String permitedRemoteHostnames ; 
139    
140    /* DEFAULT Dimse response timeout (in sec) */
141    private int DIMSERspTimeout ;
142    // Connection settings
143    
144    /* DEFAULT Listening TCP port */
145    private int wlsPort ;
146    /* DEFAULT Response delay (in miliseconds) */
147    private int rspDelay ;
148    /* DEFAULT Idle timeout (in sec) */
149    private int idleTimeout ;
150    /* DEFAULT Accept timeout (in sec) */
151    private int acceptTimeout ;
152    /* DEFAULT Connection timeout (in sec) */
153    private int connectionTimeout ;
154    
155    private int maxMessages = 2000;
156    private String SOPClass  ; 
157    private String transfCAP ; 
158    
159     /* DEFAULT Max Client Associations */
160    private int maxClientAssocs  ; 
161   
162    private int maxPDULengthReceive ;
163    private int maxPDULengthSend ;
164
165
166    HashMap<String, String> modalityFind = new HashMap<>();
167
168    ArrayList<MoveDestination> dest = new ArrayList<>();
169
170    private Set<String> priorityAETitles = new HashSet<>();
171
172    private boolean indexAnonymous = false;
173
174    private boolean indexZIPFiles = true;
175    
176    private boolean monitorWatcher = false;
177
178    /**
179     * P2P
180     */
181
182    private String p2pLibrary = "JGroups";
183    private String nodeName = "Dicoogle";
184    private boolean nodeNameDefined = false ;
185
186    private String networkInterfaceName ="";
187
188    /** Indexer */
189    private String indexer = "lucene2.2";
190    private int indexerEffort = 0 ;
191    private HashSet<String> extensionsAllowed = new HashSet<>();
192
193    private boolean gzipStorage = false;
194    private final String aclxmlFileName = "aetitleFilter.xml";
195
196    /**
197     * @return the web
198     */
199    @Override
200    public Web getWeb()
201    {
202        return web;
203    }
204
205    /**
206     * @param web the web to set
207     */
208    public void setWeb(Web web)
209    {
210        this.web = web;
211    }
212
213    /**
214     * @return the p2pLibrary
215     */
216    public String getP2pLibrary() {
217        return p2pLibrary;
218    }
219
220    /**
221     * @param p2pLibrary the p2pLibrary to set
222     */
223    public void setP2pLibrary(String p2pLibrary) {
224        this.p2pLibrary = p2pLibrary;
225    }
226
227    /**
228     * @return the indexer
229     */
230    @Override
231    public String getIndexer() {
232        return indexer;
233    }
234
235    /**
236     * @param indexer the indexer to set
237     */
238    public void setIndexer(String indexer) {
239        this.indexer = indexer;
240    }
241
242    /**
243     * @return the nodeName
244     */
245    @Override
246    public String getNodeName() {
247        return nodeName;
248    }
249
250    /**
251     * @param nodeName the nodeName to set
252     */
253    public void setNodeName(String nodeName) {
254        this.nodeName = nodeName;
255    }
256
257    /**
258     * @return the nodeNameDefined
259     */
260    @Override
261    public boolean isNodeNameDefined() {
262        return nodeNameDefined;
263    }
264
265    /**
266     * @param nodeNameDefined the nodeNameDefined to set
267     */
268    public void setNodeNameDefined(boolean nodeNameDefined) {
269        this.nodeNameDefined = nodeNameDefined;
270    }
271
272    @Override
273    public String getNetworkInterfaceName()
274    {
275        return networkInterfaceName;
276    }
277
278    public void setNetworkInterfaceName(String interfaceName)
279    {
280        this.networkInterfaceName = interfaceName;
281    }
282
283
284    /**
285     * @return the indexerEffort
286     */
287    @Override
288    public int getIndexerEffort() {
289        return indexerEffort;
290    }
291
292    /**
293     * @param indexerEffort the indexerEffort to set
294     */
295    public void setIndexerEffort(int indexerEffort) {
296        this.indexerEffort = indexerEffort;
297    }
298
299    /**
300     * @return the encryptUsersFile
301     */
302    @Override
303    public boolean isEncryptUsersFile() {
304        return encryptUsersFile;
305    }
306
307    /**
308     * @param encryptUsersFile the encryptUsersFile to set
309     */
310    public void setEncryptUsersFile(boolean encryptUsersFile) {
311        this.encryptUsersFile = encryptUsersFile;
312    }
313
314    /**
315     * @return the indexZIPFiles
316     */
317    @Override
318    public boolean isIndexZIPFiles() {
319        return indexZIPFiles;
320    }
321
322    /**
323     * @param indexZIPFiles the indexZIPFiles to set
324     */
325    public void setIndexZIPFiles(boolean indexZIPFiles) {
326        this.indexZIPFiles = indexZIPFiles;
327    }
328
329    /**
330     * @return the RGUIExternalIP
331     */
332    @Deprecated
333    public String getRGUIExternalIP() {
334        return RGUIExternalIP;
335    }
336
337    /**
338     * @param RGUIExternalIP the RGUIExternalIP to set
339     */
340    @Deprecated
341    public void setRGUIExternalIP(String RGUIExternalIP) {
342        this.RGUIExternalIP = RGUIExternalIP;
343    }
344
345    /**
346     * @return the monitorWatcher
347     */
348    @Override
349    public boolean isMonitorWatcher() {
350        return monitorWatcher;
351    }
352
353    /**
354     * @param monitorWatcher the monitorWatcher to set
355     */
356    public void setMonitorWatcher(boolean monitorWatcher) {
357        this.monitorWatcher = monitorWatcher;
358    }
359
360    /**
361     * @return the indexAnonymous
362     */
363    @Override
364    public boolean isIndexAnonymous() {
365        return indexAnonymous;
366    }
367
368    /**
369     * @param indexAnonymous the indexAnonymous to set
370     */
371    public void setIndexAnonymous(boolean indexAnonymous) {
372        this.indexAnonymous = indexAnonymous;
373    }
374
375    /**
376     * @return the gzipStorage
377     */
378    @Override
379    public boolean isGzipStorage() {
380        return gzipStorage;
381    }
382
383    /**
384     * @param gzipStorage the gzipStorage to set
385     */
386    public void setGzipStorage(boolean gzipStorage) {
387        this.gzipStorage = gzipStorage;
388    }
389
390    @Override
391    public String getAccessListFileName() {
392        return this.aclxmlFileName;
393    }
394
395    /**
396     * Web (including web server, webservices, etc)
397     */
398    public class Web implements WebSettingsReader
399    {
400        private boolean webServer = true;
401        private int serverPort = 8080;
402        private String accessControlAllowOrigins = "*";
403
404        @Deprecated
405        private boolean webServices = false;
406        @Deprecated
407        private int servicePort = 6060;
408        
409
410
411        public Web()
412        {
413        }
414
415        /**
416         * @return the webServer
417         */
418        @Override
419        public boolean isWebServer() {
420            return webServer;
421        }
422
423        /**
424         * @param webServer the webServer to set
425         */
426        public void setWebServer(boolean webServer) {
427            this.webServer = webServer;
428        }
429
430        /**
431         * @return the webServices
432         */
433        @Deprecated
434        public boolean isWebServices() {
435            return webServices;
436        }
437
438        /**
439         * @param webServices the webServices to set
440         */
441        @Deprecated
442        public void setWebServices(boolean webServices) {
443            this.webServices = webServices;
444        }
445
446        /**
447         * @return the serverPort
448         */
449        @Override
450        public int getServerPort() {
451            return serverPort;
452        }
453
454        /**
455         * @param serverPort the serverPort to set
456         */
457        public void setServerPort(int serverPort) {
458            this.serverPort = serverPort;
459        }
460
461        /**
462         * @return the servicePort
463         */
464        @Deprecated
465        public int getServicePort() {
466            return servicePort;
467        }
468
469        /**
470         * @param servicePort the servicePort to set
471         */
472        @Deprecated
473        public void setServicePort(int servicePort) {
474            this.servicePort = servicePort;
475        }
476
477        @Override
478        public String getAllowedOrigins() {
479            return this.accessControlAllowOrigins;
480        }
481
482        public void setAllowedOrigins(String origins) {
483            this.accessControlAllowOrigins = origins;
484        }
485
486    }
487
488    private Web web = new Web();
489
490        private boolean wanmode;
491
492    private static ServerSettings instance = null;
493    
494    public static synchronized ServerSettings getInstance()
495    {
496        if (instance == null) {
497            instance = new ServerSettings();
498        }
499        return instance;
500    }
501
502    private ServerSettings()
503    {
504        rGUIPort = 9014;
505        storagePort = 104;
506        AETitle = "DICOOGLE";
507        CAETitle = new String[0];
508        permitAllAETitles = true;
509        Path = "";
510        dicoogleDir = "";
511        fullContentIndex = false;
512        saveThumbnails = false;
513        thumbnailsMatrix = "64";
514
515        encryptUsersFile = false;
516
517        /**
518         * Set default values of QueryRetrieve Server
519         */
520
521        this.deviceDescription = "Dicoogle - Server SCP" ;
522        this.localAETName  = "Dicoogle";
523        this.permitedLocalInterfaces = "any";
524        this.permitedRemoteHostnames = "any";
525        this.wlsPort = 1045 ;  // default: 104
526        this.idleTimeout = 60 ;
527        this.acceptTimeout = 60 ;
528        this.rspDelay = 0 ;        
529        this.DIMSERspTimeout = 60 ;
530        this.connectionTimeout = 60 ;
531        
532        this.transfCAP = UID.ImplicitVRLittleEndian + "|" + UID.ExplicitVRBigEndian + "|" + UID.ExplicitVRLittleEndian;     
533
534        this.SOPClass = UID.StudyRootQueryRetrieveInformationModelFIND 
535        + "|" + UID.PatientRootQueryRetrieveInformationModelFIND;
536               
537        fillModalityFindDefault();
538        this.maxClientAssocs = 20 ; 
539        this.maxPDULengthReceive = 16364 ; 
540        this.maxPDULengthSend = 16364 ;
541        System.setProperty("java.net.preferIPv4Stack", "true");
542
543        autoStartPlugin = new ConcurrentHashMap<>();
544    }
545
546    // Nasty bug fix; no thumbnails references here = null pointers
547    public void setDefaultSettings()
548    {
549        rGUIPort = 9014;
550        storagePort = 6666;
551        AETitle = "DICOOGLE-STORAGE";
552        Path = System.getProperty("java.io.tmpdir");
553        CAETitle = new String[0];
554        permitAllAETitles = true;
555        dicoogleDir = System.getProperty("java.io.tmpdir");
556        fullContentIndex = false;
557        saveThumbnails = false;
558        thumbnailsMatrix = "64";
559        autoStartPlugin.clear();
560
561        setEncryptUsersFile(false);
562    }
563
564    public void setAE(String AE)
565    {
566        AETitle = AE;
567    }
568
569    @Override
570    public String getAE()
571    {
572        return AETitle;
573    }
574
575    public void setID(String I)
576    {
577        ID = I;
578    }
579
580    @Override
581    public String getID()
582    {
583        return ID;
584    }
585
586    public void setCAET(String[] CAET)
587    {
588        CAETitle = CAET;            
589    }
590
591    @Override
592    public String[] getCAET()
593    {
594        return CAETitle;
595    }
596
597    public void setPermitAllAETitles(boolean value){
598        permitAllAETitles = value;
599    }
600
601    @Override
602    public boolean getPermitAllAETitles(){
603        return permitAllAETitles;
604    }
605
606    public void setStoragePort(int p)
607    {
608        storagePort = p;
609    }
610
611    public void setPath(String p)
612    {
613        Path = p;
614    }
615
616    @Override
617    public String getPath()
618    {
619        return Path;
620    }
621
622    @Override
623    public int getStoragePort()
624    {
625        return storagePort;
626    }
627
628    @Deprecated
629    public void setRemoteGUIPort(int port){
630        rGUIPort = port;
631    }
632
633    @Deprecated
634    public int getRemoteGUIPort(){
635        return rGUIPort;
636    }
637
638    @Override
639    public String getDicoogleDir() {
640        return dicoogleDir;
641    }
642
643    public void setDicoogleDir(String dicoogleDir) {
644        this.dicoogleDir = dicoogleDir;
645    }
646
647
648    @Override
649    public boolean getFullContentIndex() {
650        return fullContentIndex;
651    }
652
653    public void setFullContentIndex(boolean fullContentIndex) {
654        this.fullContentIndex = fullContentIndex;
655    }
656
657    @Override
658    public boolean getSaveThumbnails() {
659        return saveThumbnails;
660    }
661
662    public void setSaveThumbnails(boolean saveThumbnails) {
663        this.saveThumbnails = saveThumbnails;
664    }
665    
666    @Override
667    public String getThumbnailsMatrix() {
668        return thumbnailsMatrix;
669    }
670
671    public void setThumbnailsMatrix(String thumbnailsMatrix) {
672        this.thumbnailsMatrix = thumbnailsMatrix;
673    }
674
675    /*
676     * Query Retrieve Server
677     */
678
679    public void setWlsPort(int port)
680    {
681        this.wlsPort = port ;
682    }
683
684    @Override
685    public int getWlsPort()
686    {
687        return this.wlsPort ;
688    }
689
690    public void setIdleTimeout(int timeout)
691    {
692        this.idleTimeout = timeout ;
693    }
694
695    @Override
696    public int getIdleTimeout()
697    {
698        return this.idleTimeout ;
699    }
700
701    public void setRspDelay(int delay)
702    {
703        this.rspDelay = delay ;
704    }
705
706    @Override
707    public int getRspDelay()
708    {
709        return this.rspDelay  ;
710    }
711
712    public void setAcceptTimeout(int timeout)
713    {
714        this.acceptTimeout = timeout ;
715    }
716    @Override
717    public int getAcceptTimeout()
718    {
719        return this.acceptTimeout;
720    }
721
722    public void setConnectionTimeout(int timeout)
723    {
724        this.connectionTimeout = timeout; 
725    }
726    @Override
727    public int getConnectionTimeout()
728    {
729        return this.connectionTimeout ;
730    }
731    
732    public void setSOPClass(String SOPClass)
733    {
734        this.SOPClass = SOPClass ;
735    }
736    
737    @Override
738    public String[] getSOPClasses()
739    {
740        String []tmp = {
741            UID.StudyRootQueryRetrieveInformationModelFIND ,
742            UID.PatientRootQueryRetrieveInformationModelFIND
743        };
744        return tmp ; 
745    }
746
747    @Override
748    public String getSOPClass()
749    {
750        return this.SOPClass ; 
751    }
752    public void setDIMSERspTimeout(int timeout)
753    {
754        this.DIMSERspTimeout = timeout ; 
755    }
756    @Override
757    public int getDIMSERspTimeout()
758    {
759        return this.DIMSERspTimeout ; 
760    }
761    public void setDeviceDescription(String desc)
762    {
763        this.deviceDescription = desc ; 
764    }
765    
766    @Override
767    public String getDeviceDescription()
768    {
769        return this.deviceDescription;
770    }
771    
772    public void setTransfCap(String transfCap)
773    {
774        this.transfCAP = transfCap;
775    }
776        
777    @Override
778    public String getTransfCap()
779    {
780        return this.transfCAP; 
781    }
782    
783    public void setMaxClientAssoc(int maxClients)
784    {
785        this.maxClientAssocs = maxClients; 
786    }
787    
788    @Override
789    public int getMaxClientAssoc()
790    {
791        return this.maxClientAssocs; 
792    }
793    
794    public void setMaxPDULengthReceive(int len)
795    {
796        this.maxPDULengthReceive = len;
797    }
798    
799    @Override
800    public int getMaxPDULengthReceive()
801    {
802        return this.maxPDULengthReceive; 
803    }
804    public void setMaxPDULengthSend(int len)
805    {
806        this.maxPDULengthSend = len;
807    }
808    @Override
809    public int getMaxPDULenghtSend() // FIXME typo
810    {
811        return this.maxPDULengthSend; 
812    }
813    
814    public void setLocalAETName(String name)
815    {
816        this.localAETName = name; 
817    }
818    @Override
819    public String getLocalAETName()
820    {
821        return this.localAETName; 
822    }
823    
824    public void setPermitedLocalInterfaces(String localInterfaces)
825    {
826        this.permitedLocalInterfaces  = localInterfaces; 
827    }
828    
829    @Override
830    public String getPermitedLocalInterfaces()
831    {
832        return this.permitedLocalInterfaces; 
833    }
834    
835    public void setPermitedRemoteHostnames(String remoteHostnames)
836    {
837        this.permitedRemoteHostnames = remoteHostnames; 
838    }
839    
840    @Override
841    public String getPermitedRemoteHostnames()
842    {
843        return this.permitedRemoteHostnames;
844    }
845
846    /**
847     * @return the P2P
848     */
849   /* public boolean isP2P() {
850        return P2P;
851    }*/
852    @Override
853    public boolean isStorage() {
854        return storage;
855    }
856    @Override
857    public boolean isQueryRetrive() {
858        return queryRetrieve;
859    }
860
861    public void add(MoveDestination m)
862    {
863        this.dest.add(m);
864    }
865    public boolean remove(MoveDestination m)
866    {
867        return this.dest.remove(m);
868    }
869    public boolean removeMoveDestination(String AETitle, String ipAddr, int port)
870    {
871        for(int i=0;i<dest.size(); i++)
872        {
873                MoveDestination mv = dest.get(i);
874                if(mv.getAETitle().equals(AETitle) && mv.getIpAddrs().equals(ipAddr) && mv.getPort() == port)
875                {
876                        dest.remove(i);
877                        return true;
878                }
879                        
880        }
881        return false;
882    }
883
884    public boolean removeMoveDestination(String AETitle)
885    {
886        boolean removed = false;
887        Iterator<MoveDestination> it = dest.iterator();
888        while(it.hasNext()) {
889            if(it.next().getAETitle().equals(AETitle)) {
890                it.remove();
891                removed = true;
892            }
893        }
894        return removed;
895    }
896    public boolean contains(MoveDestination m){
897        return this.dest.contains(m);
898    }
899    @Override
900    public ArrayList<MoveDestination> getMoves()
901    {
902        return this.dest ;
903    }
904
905    @Override
906    public Set<String> getPriorityAETitles() {
907        return priorityAETitles;
908    }
909
910    public void addPriorityAETitle(String aet)
911    {
912        this.priorityAETitles.add(aet);
913    }
914    public void removePriorityAETitle(String aet)
915    {
916        this.priorityAETitles.remove(aet);
917    }
918
919    public void setMoves(ArrayList<MoveDestination> moves)
920    {
921        if(moves != null)
922            this.dest = moves;
923    }
924
925
926
927    private void fillModalityFindDefault()
928    {
929         addModalityFind("1.2.840.10008.5.1.4.1.2.2.1",
930                 "Study Root Query/Retrieve Information Model");
931
932         addModalityFind("1.2.840.10008.5.1.4.1.2.1.1",
933                    "Patient Root Query/Retrieve Information Model"
934                 );
935
936    }
937
938    /**
939     * Set default values
940     */
941    public void setDefaultsValues()
942    {
943        this.fillModalityFindDefault();
944    }
945
946    /**
947     * Add a modality
948     * @param sop Number like 1.2.3.5.6.7.32.1
949     * @param description Description like "Modality Worklist Model"
950     */
951    public void addModalityFind(String sop, String description)
952    {
953        this.modalityFind.put(sop, description);
954    }
955
956    /**
957     *
958     * @return HashMap with Modalitys FIND
959     */
960    @Override
961    public HashMap<String, String> getModalityFind()
962    {
963        return this.modalityFind;
964    }
965
966
967    /**
968     * Sets the plugin start on server init value.
969     * <b>NOTE</b>: this method is strictly for plugins, not embedded services.
970     *
971     * @param name the name of the plugin.
972     * @param value true to auto start the plugin on server init.
973     */
974    public void setAutoStartPlugin(String name, boolean value)
975    {
976        // remove the previous setting, if there is one
977        autoStartPlugin.remove(name);
978
979        // insert the new setting
980        autoStartPlugin.put(name, value);
981    }
982
983    /**
984     * Returns if the plugin is to be auto started on server init or not.
985     * The default value (without previous configuration) is to start the plugin.
986     * <b>NOTE</b>: this method is strictly for plugins, not embedded services.
987     *
988     * @param name the name of the plugin.
989     * @return true if the plugin is to be auto started on server init or false if it is not.
990     */
991    @Override
992    public boolean getAutoStartPlugin(String name)
993    {
994        Boolean result = autoStartPlugin.get(name);
995
996        // if there is not such setting return the default value
997        if (result == null) return true; // by default start the plugin
998        return result.booleanValue();
999    }
1000
1001        /**
1002         * Returns the current settings for plugin auto start on server init.
1003         *
1004         * @return the current settings for plugin auto start on server init.
1005         */
1006    @Override
1007        public ConcurrentHashMap<String, Boolean> getAutoStartPluginsSettings()
1008        {
1009                return autoStartPlugin;
1010        }
1011
1012        /**
1013         * Returns the Remote GUI list of settings (name, value/type pairs).
1014         *
1015         * @return and HashMap containing the Remote GUI list of settings (name, value/type pairs).
1016         */
1017    @Deprecated
1018        public HashMap<String, Object> getRGUISettings()
1019        {
1020                HashMap<String, Object> result = new HashMap<String, Object>();
1021
1022                result.put(RGUI_SETTING_EXTERNAL_IP, getRGUIExternalIP());
1023
1024                return result;
1025        }
1026
1027        /**
1028         * Validates the new settings for the Remote GUI service.
1029         *
1030         * @param settings a HashMap containing the new setting values.
1031         * @return true if all the values are valid and can be applied, false otherwise.
1032         */
1033    @Deprecated
1034        public boolean tryRGUISettings(HashMap<String, Object> settings)
1035        {
1036                // TODO
1037                return true;
1038        }
1039
1040        /**
1041         * Tries to apply the new settings for the Remote GUI service.
1042         *
1043         * @param settings a HashMap containing the new setting values.
1044         * @return true if all the values are valid and were applied successfully, false otherwise.
1045         */
1046    @Deprecated
1047        public boolean setRGUISettings(HashMap<String, Object> settings)
1048        {
1049                if (! tryRGUISettings(settings))
1050                        return false;
1051
1052                setRGUIExternalIP((String) settings.get(RGUI_SETTING_EXTERNAL_IP));
1053
1054                return true;
1055        }
1056
1057        /**
1058         * Returns the Remote GUI list of settings help (name,help pairs).
1059         *
1060         * @return and HashMap containing the Remote GUI list of settings help (name, help).
1061         */
1062        public HashMap<String, String> getRGUISettingsHelp()
1063        {
1064                HashMap<String, String> result = new HashMap<String, String>();
1065        
1066                result.put(RGUI_SETTING_EXTERNAL_IP, RGUI_SETTING_EXTERNAL_IP_HELP);
1067
1068                return result;
1069        }
1070
1071        /**
1072         * Returns the Query Retrieve list of settings (name, value/type pairs).
1073         *
1074         * @return and HashMap containing the Query Retrieve list of settings (name, value/type pairs).
1075         */
1076    @Override
1077        public HashMap<String, Object> getQueryRetrieveSettings()
1078        {
1079                HashMap<String, Object> result = new HashMap<>();
1080
1081                result.put(QUERYRETRIEVE_MAX_ASSOCIATIONS, getMaxClientAssoc());
1082                result.put(QUERYRETRIEVE_MAX_PDU_RECEIVE, getMaxPDULengthReceive());
1083                result.put(QUERYRETRIEVE_MAX_PDU_SEND, getMaxPDULenghtSend());
1084                result.put(QUERYRETRIEVE_IDLE_TIMEOUT, getIdleTimeout());
1085                result.put(QUERYRETRIEVE_ACCEPT_TIMEOUT, getAcceptTimeout());
1086                result.put(QUERYRETRIEVE_RESPONSE_TIMEOUT, getRspDelay());
1087                result.put(QUERYRETRIEVE_CONNECTION_TIMEOUT, getConnectionTimeout());
1088
1089                return result;
1090        }
1091
1092        /**
1093         * Validates the new settings for the Query Retrieve service.
1094         *
1095         * @param settings a HashMap containing the new setting values.
1096         * @return true if all the values are valid and can be applied, false otherwise.
1097         */
1098        public boolean tryQueryRetrieveSettings(HashMap<String, Object> settings)
1099        {
1100                // TODO
1101                return true;
1102        }
1103
1104        /**
1105         * Tries to apply the new settings for the Query Retrieve service.
1106         *
1107         * @param settings a HashMap containing the new setting values.
1108         * @return true if all the values are valid and were applied successfully, false otherwise.
1109         */
1110        public boolean setQueryRetrieveSettings(HashMap<String, Object> settings)
1111        {
1112                if (! tryQueryRetrieveSettings(settings))
1113                        return false;
1114
1115                setMaxClientAssoc(((Integer) settings.get(QUERYRETRIEVE_MAX_ASSOCIATIONS)).intValue());
1116                setMaxPDULengthReceive(((Integer) settings.get(QUERYRETRIEVE_MAX_PDU_RECEIVE)).intValue());
1117                setMaxPDULengthSend(((Integer) settings.get(QUERYRETRIEVE_MAX_PDU_SEND)).intValue());
1118                setIdleTimeout(((Integer) settings.get(QUERYRETRIEVE_IDLE_TIMEOUT)).intValue());
1119                setAcceptTimeout(((Integer) settings.get(QUERYRETRIEVE_ACCEPT_TIMEOUT)).intValue());
1120                setRspDelay(((Integer) settings.get(QUERYRETRIEVE_RESPONSE_TIMEOUT)).intValue());
1121                setConnectionTimeout(((Integer) settings.get(QUERYRETRIEVE_CONNECTION_TIMEOUT)).intValue());
1122
1123                return true;
1124        }
1125
1126        /**
1127         * Returns the Query Retrieve list of settings help (name,help pairs).
1128         *
1129         * @return and HashMap containing the Query Retrieve list of settings help (name, help).
1130         */
1131        public HashMap<String, String> getQueryRetrieveSettingsHelp()
1132        {
1133                return null; // no help available
1134        }
1135
1136        /**
1137         * Returns the Storage list of settings (name, value/type pairs).
1138         *
1139         * @return and HashMap containing the Storage list of settings (name, value/type pairs).
1140         */
1141    @Override
1142        public HashMap<String, Object> getStorageSettings()
1143        {
1144                HashMap<String, Object> result = new HashMap<>();
1145
1146                //result.put(STORAGE_SETTING_PATH, new ServerDirectoryPath(getPath()));
1147                // TODO move some of these new classes onto the SDK, so that plugins can also process option types/fields
1148                int destCount = dest.size();
1149                DataTable storageServers = new DataTable(3, destCount);
1150                storageServers.setColumnName(0, "AETitle");
1151                storageServers.setColumnName(1, "IP");
1152                storageServers.setColumnName(2, "Port");
1153                // if there are no rows, then add an empty one (for reference)
1154                if (destCount < 1)
1155                {
1156                        storageServers.addRow();
1157                        storageServers.setCellData(0, 0, "");
1158                        storageServers.setCellData(0, 1, "");
1159                        storageServers.setCellData(0, 2, "");
1160                }
1161                else
1162                        for (int i = 0; i < destCount; i++)
1163                        {
1164                                MoveDestination aDest = dest.get(i);
1165                                storageServers.setCellData(i, 0, aDest.getAETitle());
1166                                storageServers.setCellData(i, 1, aDest.getIpAddrs());
1167                                storageServers.setCellData(i, 2, "" + aDest.getPort());
1168                        }
1169                result.put(STORAGE_SETTING_SERVERS_DESTINATIONS, storageServers);
1170
1171                return result;
1172        }
1173
1174        /**
1175         * Validates the new settings for the Storage service.
1176         *
1177         * @param settings a HashMap containing the new setting values.
1178         * @return true if all the values are valid and can be applied, false otherwise.
1179         */
1180        public boolean tryStorageSettings(HashMap<String, Object> settings)
1181        {
1182                // TODO
1183                return true;
1184        }
1185
1186        /**
1187         * Tries to apply the new settings for the Storage service.
1188         *
1189         * @param settings a HashMap containing the new setting values.
1190         * @return true if all the values are valid and were applied successfully, false otherwise.
1191         */
1192        public boolean setStorageSettings(HashMap<String, Object> settings)
1193        {
1194                if (! tryStorageSettings(settings))
1195                        return false;
1196
1197                //setPath(((ServerDirectoryPath) settings.get(STORAGE_SETTING_PATH)).getPath());
1198                // TODO set the query retrieve options
1199
1200                return true;
1201        }
1202
1203        /**
1204         * Returns the Storage list of settings help (name,help pairs).
1205         *
1206         * @return and HashMap containing the Storage list of settings help (name, help).
1207         */
1208        public HashMap<String, String> getStorageSettingsHelp()
1209        {
1210                return null; // no help available
1211        }
1212
1213    public void setStorage(boolean storage)
1214    {
1215        this.storage = storage;
1216    }
1217
1218    public void setQueryRetrive(boolean queryRetrieve)
1219    {
1220        this.queryRetrieve = queryRetrieve;
1221    }
1222
1223    @Override
1224    public ArrayList<String> getNetworkInterfacesNames()
1225    {
1226        ArrayList<String> interfaces = new ArrayList<String>();
1227        Enumeration<NetworkInterface> nets = null;
1228        try
1229        {
1230            nets = NetworkInterface.getNetworkInterfaces();
1231        } catch (SocketException ex)
1232        {
1233            ex.printStackTrace();
1234        }
1235
1236        
1237        for (NetworkInterface netint : Collections.list(nets))
1238        {
1239            try
1240            {
1241                if (!netint.isLoopback())
1242                {
1243                    Enumeration<InetAddress> addresses = netint.getInetAddresses();
1244                    while (addresses.hasMoreElements())
1245                    {
1246                        if (Inet4Address.class.isInstance(addresses.nextElement()))
1247                        {
1248                            interfaces.add(netint.getDisplayName());
1249                        }
1250                    }
1251                }
1252            } catch (SocketException ex)
1253            {
1254                LoggerFactory.getLogger(ServerSettings.class).error(ex.getMessage(), ex);
1255            }
1256        }
1257        return interfaces;
1258    }
1259
1260    @Override
1261    public String getNetworkInterfaceAddress()
1262    {
1263        Enumeration<NetworkInterface> nets = null;
1264        try
1265        {
1266            nets = NetworkInterface.getNetworkInterfaces();
1267        } catch (SocketException ex)
1268        {
1269            ex.printStackTrace();
1270        }
1271
1272        for(NetworkInterface netint : Collections.list(nets))
1273        {
1274            if(netint.getDisplayName().compareTo(this.networkInterfaceName) == 0)
1275            {
1276                Enumeration<InetAddress> addresses = netint.getInetAddresses();
1277                while(addresses.hasMoreElements())
1278                {
1279                    InetAddress address = addresses.nextElement();
1280                    if(Inet4Address.class.isInstance(address))
1281                    {
1282                        return address.getHostAddress();
1283                    }
1284                }
1285                return null;
1286            }
1287        }
1288        return null;
1289    }
1290    /**
1291     * Add an extension to list of allowed indexing extensions.
1292     * <p>
1293     * All extensions should be added (ie, dicom, etc).
1294     *
1295     * @param ext          It is the extensions of files that should be indexed.
1296     * <b>empty</b> string means that documents without extension will be indexed.
1297     * 
1298     * @see   IndexEngine
1299     */
1300    public void addExtension(String ext)
1301    {
1302        this.extensionsAllowed.add(ext);
1303    }
1304
1305
1306
1307    @Override
1308    public HashSet<String> getExtensionsAllowed()
1309    {
1310        return extensionsAllowed;
1311    }
1312
1313    /**
1314     * @return the maxMessages
1315     */
1316    @Override
1317    public int getMaxMessages() {
1318        return maxMessages;
1319    }
1320
1321    /**
1322     * @param maxMessages the maxMessages to set
1323     */
1324    public void setMaxMessages(int maxMessages) {
1325        this.maxMessages = maxMessages;
1326    }
1327
1328    @Override
1329        public boolean isWANModeEnabled() {
1330                // TODO Auto-generated method stub
1331                return wanmode;
1332        }
1333
1334        public void setWanmode(boolean wanmode) {
1335                this.wanmode = wanmode;
1336        }
1337
1338}