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.web.management;
020
021import java.util.HashMap;
022import java.util.LinkedHashMap;
023import java.util.LinkedList;
024import java.util.List;
025import java.util.Map;
026import org.dcm4che2.data.UID;
027import pt.ua.dicoogle.server.SOPList;
028import pt.ua.dicoogle.server.TransfersStorage;
029import pt.ua.dicoogle.core.ServerSettings;
030import pt.ua.dicoogle.sdk.settings.InvalidSettingValueException;
031import pt.ua.dicoogle.sdk.settings.types.CheckboxWithHint;
032import pt.ua.dicoogle.sdk.settings.types.ComboBox;
033import pt.ua.dicoogle.sdk.settings.types.RangeInteger;
034import pt.ua.dicoogle.sdk.settings.types.ServerDirectoryPath;
035import pt.ua.dicoogle.sdk.settings.types.DataTable;
036import pt.ua.dicoogle.sdk.settings.types.StaticDataTable;
037import static pt.ua.dicoogle.sdk.settings.Utils.parseCheckBoxValue;
038
039/**
040 * A wrapper used to manage the Dicoogle Settings remotely through the web environment/app.
041 */
042public class Dicoogle
043{
044        /**
045         * The current instance of this class.
046         */
047        private static Dicoogle instance;
048
049        /**
050         * Pointer to a object that maintain the ServerSettings configuration.
051         */
052        private static ServerSettings cfg;
053
054        /**
055         * Indexing.
056         */
057
058        /**
059         * The name of the setting that indicates the Dicoogle Directory Monitorization.
060         */
061        public static final String SETTING_DIRECTORY_MONITORIZATION_NAME = "Dicoogle Directory Monitorization";
062        /**
063         * The name of the setting that indicates the Dicoogle Enable Directory Watcher.
064         */
065        public static final String SETTING_DIRECTORY_WATCHER_NAME = "Enable Dicoogle Directory Watcher";
066        /**
067         * The name of the setting that indicates the Indexing Effort.
068         */
069        public static final String SETTING_INDEXING_EFFORT_NAME = "Indexing Effort";
070        /**
071         * The name of the setting that indicates the Thumbnails Size.
072         */
073        public static final String SETTING_THUMBNAILS_SIZE_NAME = "Thumbnails Size";
074        /**
075         * The name of the setting that indicates if Thumbnails are to be Saved.
076         */
077        public static final String SETTING_SAVE_THUMBNAILS_NAME = "Save Thumbnails";
078        /**
079         * The name of the setting that indicates if ZIP files are to be Indexed.
080         */
081        public static final String SETTING_INDEX_ZIP_FILES_NAME = "Index ZIP Files";
082
083        /**
084         * Access List.
085         */
086
087        /**
088         * The name of the setting that indicates the Server AE Title.
089         */
090        public static final String SETTING_SERVER_AE_TITLE_NAME = "Server AE Title";
091        /**
092         * The name of the setting that indicates the Permit All AE Titles.
093         */
094        public static final String SETTING_PERMIT_ALL_AE_TITLES_NAME = "Permit All AE Titles";
095        /**
096         * The name of the setting that indicates the Client Permit Access List.
097         */
098        public static final String SETTING_CLIENT_PERMIT_ACCESS_LIST_NAME = "Client Permit Access List";
099
100        /**
101         * SOP Class/Transfer Storage.
102         */
103
104        /**
105         * The name of the setting that indicates if Accept All SOP Classes.
106         */
107        public static final String SETTING_SOP_CLASS_ACCEPT_ALL_NAME = "Accept All";
108        /**
109         * The name of the setting that indicates the Global Transfer Storage settings.
110         */
111        public static final String SETTING_SOP_CLASS_GLOBAL_TRANSFER_STORAGE_NAME = "Global Transfer Storage";
112
113        /**
114         * Indexing Help.
115         */
116
117        /**
118         * The help of the Indexing Effort setting.
119         */
120        public static final String SETTING_INDEXING_EFFORT_HELP = "How agressive should the indexing effort be.\n\n0 - Lower\n100 - Intensive";
121
122        /**
123         * Access List Help.
124         */
125
126        /**
127         * The help for the setting that indicates the Server AE Title.
128         */
129        public static final String SETTING_SERVER_AE_TITLE_HELP = "Setting an AE Title will force the server to only accept connections adressed to the given AE Title.";
130        /**
131         * The help of the setting that indicates the Permit All AE Titles.
132         */
133        public static final String SETTING_PERMIT_ALL_AE_TITLES_HELP = "Overrides the Client Permit Access List settings, making the server accept connection from clients with any AE Title.";
134        /**
135         * The help for the setting that indicates the Client Permit Access List.
136         */
137        public static final String SETTING_CLIENT_PERMIT_ACCESS_LIST_HELP = "Adding an AE Title to the Access Control List will force the server to only accept connections from clients with those AE Titles.";
138
139        private Dicoogle()
140        {
141                cfg = ServerSettings.getInstance();
142        }
143
144        /**
145         * Returns the current instance of this class.
146         *
147         * @return the current instance of this class.
148         */
149        public synchronized static Dicoogle getInstance()
150        {
151                if (instance == null)
152                        instance = new Dicoogle();
153
154                return instance;
155        }
156
157        /**
158         * Indexing.
159         */
160
161        /**
162         * Returns a Map containing the current settings.
163         *
164         * @return a Map containing the current settings.
165         */
166        public HashMap<String, Object> getIndexingSettings()
167        {
168                HashMap<String, Object> settings = new LinkedHashMap<String, Object>();
169
170                settings.put(SETTING_DIRECTORY_WATCHER_NAME, new Boolean(cfg.isMonitorWatcher()));
171                settings.put(SETTING_DIRECTORY_MONITORIZATION_NAME, new ServerDirectoryPath(cfg.getDicoogleDir()));
172                settings.put(SETTING_INDEX_ZIP_FILES_NAME, cfg.isIndexZIPFiles());
173                settings.put(SETTING_INDEXING_EFFORT_NAME, new RangeInteger(0, 100, cfg.getIndexerEffort()));
174                settings.put(SETTING_SAVE_THUMBNAILS_NAME, cfg.getSaveThumbnails());
175                settings.put(SETTING_THUMBNAILS_SIZE_NAME, cfg.getThumbnailsMatrix()); // TODO add more descritive type
176
177                return settings;
178        }
179
180        /**
181         * Returns the settings help.
182         *
183         * @return a HashMap containing the setting help.
184         */
185        public HashMap<String, String> getIndexingSettingsHelp()
186        {
187                HashMap<String, String> settings = new HashMap<String, String>();
188
189                // right now this is the only settingg that needs some help describing it
190                settings.put(SETTING_INDEXING_EFFORT_NAME, SETTING_INDEXING_EFFORT_HELP);
191
192                return settings;
193        }
194
195        /**
196         * Validates the settings supplied and checks if they are valid ones.
197         *
198         * @param map a Map containing the settings.
199         * @return true if all the settings are valid.
200         * @throws InvalidSettingValueException if at least one of the settings is invalid.
201         */
202        public boolean tryIndexingSettings(HashMap<String, Object> map) throws InvalidSettingValueException
203        {
204                // TODO remmember to check for null, all the params are supplied, all have valid types, and oly then all have valid values
205
206                return true;
207        }
208
209        /**
210         * Tries to set the supplied settings as the new settings.
211         *
212         * @param settings a Map containing the new settings.
213         * @return true if all settings were successfully changed to the ones supplied, false otherwise (no settings changed).
214         */
215        public boolean setIndexingSettings(HashMap<String, Object> settings)
216        {
217                // validate the settings
218                boolean valid = false;
219                try
220                {
221                        valid = tryIndexingSettings(settings);
222                }
223                catch (InvalidSettingValueException ex)
224                {
225                        // at least one of the setting is invalid, abort
226                        return false;
227                }
228                if (! valid) //settings not valid due to unknown reason, also abort
229                        return false;
230
231                // all the settings were correctly validated, so apply them all
232                cfg.setDicoogleDir(((ServerDirectoryPath) settings.get(SETTING_DIRECTORY_MONITORIZATION_NAME)).getPath());
233                cfg.setMonitorWatcher(((Boolean) settings.get(SETTING_DIRECTORY_WATCHER_NAME)).booleanValue());
234                cfg.setIndexerEffort(((RangeInteger) settings.get(SETTING_INDEXING_EFFORT_NAME)).getValue());
235                cfg.setThumbnailsMatrix((String) settings.get(SETTING_THUMBNAILS_SIZE_NAME));
236                cfg.setSaveThumbnails(((Boolean) settings.get(SETTING_SAVE_THUMBNAILS_NAME)).booleanValue());
237                cfg.setIndexZIPFiles(((Boolean) settings.get(SETTING_INDEX_ZIP_FILES_NAME)).booleanValue());
238
239                // return success
240                return true;
241        }
242
243        /**
244         * Access List.
245         */
246
247        /**
248         * Returns a Map containing the current settings.
249         *
250         * @return a Map containing the current settings.
251         */
252        public HashMap<String, Object> getAccessListSettings()
253        {
254                HashMap<String, Object> settings = new LinkedHashMap<String, Object>();
255
256                settings.put(SETTING_SERVER_AE_TITLE_NAME, cfg.getAE());
257                settings.put(SETTING_PERMIT_ALL_AE_TITLES_NAME, new Boolean(cfg.getPermitAllAETitles()));
258                String[] caet = cfg.getCAET();
259                DataTable clientPermitACL = new DataTable(1, caet.length);
260                clientPermitACL.setColumnName(0, "Client AE Title");
261                if (caet.length < 1)
262                {
263                        clientPermitACL.addRow();
264                        clientPermitACL.setCellData(0, 0, "");
265                }
266                else
267                {
268                        for (int i = 0; i < caet.length; i++)
269                                clientPermitACL.setCellData(i, 0, caet[i]);
270                }
271                settings.put(SETTING_CLIENT_PERMIT_ACCESS_LIST_NAME, clientPermitACL);
272
273                return settings;
274        }
275
276        /**
277         * Returns the settings help.
278         *
279         * @return a HashMap containing the setting help.
280         */
281        public HashMap<String, String> getAccessListSettingsHelp()
282        {
283                HashMap<String, String> settings = new HashMap<String, String>();
284
285                settings.put(SETTING_SERVER_AE_TITLE_NAME, SETTING_SERVER_AE_TITLE_HELP);
286                settings.put(SETTING_PERMIT_ALL_AE_TITLES_NAME, SETTING_PERMIT_ALL_AE_TITLES_HELP);
287                settings.put(SETTING_CLIENT_PERMIT_ACCESS_LIST_NAME, SETTING_CLIENT_PERMIT_ACCESS_LIST_HELP);
288
289                return settings;
290        }
291
292        /**
293         * Validates the settings supplied and checks if they are valid ones.
294         *
295         * @param map a Map containing the settings.
296         * @return true if all the settings are valid.
297         * @throws InvalidSettingValueException if at least one of the settings is invalid.
298         */
299        public boolean tryAccessListSettings(HashMap<String, Object> map) throws InvalidSettingValueException
300        {
301                // TODO remmember to check for null, all the params are supplied, all have valid types, and oly then all have valid values
302
303                return true;
304        }
305
306        /**
307         * Tries to set the supplied settings as the new settings.
308         *
309         * @param settings a Map containing the new settings.
310         * @return true if all settings were successfully changed to the ones supplied, false otherwise (no settings changed).
311         */
312        public boolean setAccessListSettings(HashMap<String, Object> settings)
313        {
314                // validate the settings
315                boolean valid = false;
316                try
317                {
318                        valid = tryAccessListSettings(settings);
319                }
320                catch (InvalidSettingValueException ex)
321                {
322                        // at least one of the setting is invalid, abort
323                        return false;
324                }
325                if (! valid) //settings not valid due to unknown reason, also abort
326                        return false;
327
328                // all the settings were correctly validated, so apply them all
329                cfg.setAE((String) settings.get(SETTING_SERVER_AE_TITLE_NAME));
330                cfg.setPermitAllAETitles(((Boolean) settings.get(SETTING_PERMIT_ALL_AE_TITLES_NAME)).booleanValue());
331                DataTable clientPermitACL = (DataTable) settings.get(SETTING_CLIENT_PERMIT_ACCESS_LIST_NAME);
332                LinkedList<String> caet = new LinkedList<String>();
333                if ((clientPermitACL.getRowCount() != 1) || (clientPermitACL.getCellData(0, 0) != ""))
334                        for (int i = 0; i < clientPermitACL.getRowCount(); i++)
335                                caet.add((String) clientPermitACL.getCellData(i, 0));
336                cfg.setCAET(caet.toArray(new String[caet.size()]));
337
338                // return success
339                return true;
340        }
341
342        /**
343         * SOP Classes / Transfer Storage.
344         */
345
346        /**
347         * Returns a Map containing the current settings.
348         *
349         * @return a Map containing the current settings.
350         */
351        public HashMap<String, Object> getSOPClassGlobalSettings()
352        {
353                HashMap<String, Object> settings = new LinkedHashMap<String, Object>();
354
355                Object[] set = getTransferSettingsForAllSOPClasses();
356
357                ComboBox tristate = new ComboBox();
358                tristate.addElement("As Is (No Change)", "");
359                tristate.addElement("Allow All", "On"); // try to emulate a regular checkbox :)
360                tristate.addElement("Forbid All", "Off");
361                tristate.setCurrentByValue(""); // FIXME default is "no change", always (for the time being)
362                settings.put(SETTING_SOP_CLASS_ACCEPT_ALL_NAME, tristate);
363                settings.put(SETTING_SOP_CLASS_GLOBAL_TRANSFER_STORAGE_NAME, set[1]);
364
365                return settings;
366        }
367
368        /**
369         * Returns the settings help.
370         *
371         * @return a HashMap containing the setting help.
372         */
373        public HashMap<String, String> getSOPClassGlobalSettingsHelp()
374        {
375                HashMap<String, String> settings = new HashMap<String, String>();
376
377                // TODO
378
379                return settings;
380        }
381
382        /**
383         * Validates the settings supplied and checks if they are valid ones.
384         *
385         * @param map a Map containing the settings.
386         * @return true if all the settings are valid.
387         * @throws InvalidSettingValueException if at least one of the settings is invalid.
388         */
389        public boolean trySOPClassGlobalSettings(HashMap<String, Object> map) throws InvalidSettingValueException
390        {
391                // TODO remmember to check for null, all the params are supplied, all have valid types, and oly then all have valid values
392
393                return true;
394        }
395
396        /**
397         * Tries to set the supplied settings as the new settings.
398         *
399         * @param settings a Map containing the new settings.
400         * @return true if all settings were successfully changed to the ones supplied, false otherwise (no settings changed).
401         */
402        public boolean setSOPClassGlobalSettings(HashMap<String, Object> settings)
403        {
404                // validate the settings
405                boolean valid = false;
406                try
407                {
408                        valid = tryAccessListSettings(settings);
409                }
410                catch (InvalidSettingValueException ex)
411                {
412                        // at least one of the setting is invalid, abort
413                        return false;
414                }
415                if (! valid) //settings not valid due to unknown reason, also abort
416                        return false;
417
418                // all the settings were correctly validated, so apply them all
419                ComboBox tristate = (ComboBox) settings.get(SETTING_SOP_CLASS_ACCEPT_ALL_NAME);
420                Boolean accepted = null;
421                if (! tristate.getCurrentValue().isEmpty()) // NOTE: empty ("") means no change, see the getter for this settings
422                        accepted = new Boolean(parseCheckBoxValue(tristate.getCurrentValue()));
423                StaticDataTable table = (StaticDataTable) settings.get(SETTING_SOP_CLASS_GLOBAL_TRANSFER_STORAGE_NAME);
424
425                setTransferSettingsForAllSOPClasses(accepted, table);
426
427                // return success
428                return true;
429        }
430
431        /**
432         * Holds and provides information about the accepted SOP Classes and
433         * Transfer Storages allowed within Dicoogle.
434         */
435        public static class SOPClassSettings
436        {
437                /**
438                 * Holds a pointer to the SOPList that holds the SOP Classes settings.
439                 */
440                private SOPList sopList;
441
442                /**
443                 * Holds the list of SOP Classes UIDs and their respective "regular" name.
444                 */
445                private HashMap<String, String> sopClasses;
446                /**
447                 * Holds the list of Transfer Storage UIDs and their respective "regular" name.
448                 */
449                private HashMap<String, String> transferSettings;
450                /**
451                 * Holds the list of Transfer Storage UIDs and their respective index on the TS object.
452                 */
453                private HashMap<String, Integer> transferSettingsIndex;
454
455                /**
456                 * Holds the current instance of this class.
457                 */
458                private static SOPClassSettings instance;
459
460                private SOPClassSettings()
461                {
462                        sopList = SOPList.getInstance();
463
464                        sopClasses = new HashMap<String, String>();
465                        transferSettings = new HashMap<String, String>();
466                        transferSettingsIndex = new HashMap<String, Integer>();
467
468                        sopClasses.put(UID.BasicStudyContentNotificationSOPClassRetired, "BasicStudyContentNotification (Retired)");
469                        sopClasses.put(UID.StoredPrintStorageSOPClassRetired, "StoredPrintStorage (Retired)");
470                        sopClasses.put(UID.HardcopyGrayscaleImageStorageSOPClassRetired, "HardcopyGrayscaleImageStorage (Retired)");
471                        sopClasses.put(UID.HardcopyColorImageStorageSOPClassRetired, "HardcopyColorImageStorage (Retired)");
472                        sopClasses.put(UID.ComputedRadiographyImageStorage, "ComputedRadiographyImageStorage");
473                        sopClasses.put(UID.DigitalXRayImageStorageForPresentation, "DigitalXRayImageStorageForPresentation");
474                        sopClasses.put(UID.DigitalXRayImageStorageForProcessing, "DigitalXRayImageStorageForProcessing");
475                        sopClasses.put(UID.DigitalMammographyXRayImageStorageForPresentation, "DigitalMammographyXRayImageStorageForPresentation");
476                        sopClasses.put(UID.DigitalMammographyXRayImageStorageForProcessing, "DigitalMammographyXRayImageStorageForProcessing");
477                        sopClasses.put(UID.DigitalIntraOralXRayImageStorageForPresentation, "DigitalIntraoralXRayImageStorageForPresentation");
478                        sopClasses.put(UID.DigitalIntraOralXRayImageStorageForProcessing, "DigitalIntraoralXRayImageStorageForProcessing");
479                        sopClasses.put(UID.StandaloneModalityLUTStorageRetired, "StandaloneModalityLUTStorage (Retired)");
480                        sopClasses.put(UID.EncapsulatedPDFStorage, "EncapsulatedPDFStorage");
481                        sopClasses.put(UID.StandaloneVOILUTStorageRetired, "StandaloneVOILUTStorage (Retired)");
482                        sopClasses.put(UID.GrayscaleSoftcopyPresentationStateStorageSOPClass, "GrayscaleSoftcopyPresentationStateStorage");
483                        sopClasses.put(UID.ColorSoftcopyPresentationStateStorageSOPClass, "ColorSoftcopyPresentationStateStorage");
484                        sopClasses.put(UID.PseudoColorSoftcopyPresentationStateStorageSOPClass, "PseudoColorSoftcopyPresentationStateStorage");
485                        sopClasses.put(UID.BlendingSoftcopyPresentationStateStorageSOPClass, "BlendingSoftcopyPresentationStateStorage");
486                        sopClasses.put(UID.XRayAngiographicImageStorage, "XRayAngiographicImageStorage");
487                        sopClasses.put(UID.EnhancedXAImageStorage, "EnhancedXAImageStorage");
488                        sopClasses.put(UID.XRayRadiofluoroscopicImageStorage, "XRayRadiofluoroscopicImageStorage");
489                        sopClasses.put(UID.EnhancedXRFImageStorage, "EnhancedXRFImageStorage");
490                        sopClasses.put(UID.XRayAngiographicBiPlaneImageStorageRetired, "XRayAngiographicBiPlaneImageStorage (Retired)");
491                        sopClasses.put(UID.PositronEmissionTomographyImageStorage, "PositronEmissionTomographyImageStorage");
492                        sopClasses.put(UID.StandalonePETCurveStorageRetired, "StandalonePETCurveStorage (Retired)");
493                        sopClasses.put(UID.CTImageStorage, "CTImageStorage");
494                        sopClasses.put(UID.EnhancedCTImageStorage, "EnhancedCTImageStorage");
495                        sopClasses.put(UID.NuclearMedicineImageStorage, "NuclearMedicineImageStorage");
496                        sopClasses.put(UID.UltrasoundMultiFrameImageStorageRetired, "UltrasoundMultiframeImageStorage (Retired)");
497                        sopClasses.put(UID.UltrasoundMultiFrameImageStorage, "UltrasoundMultiframeImageStorage");
498                        sopClasses.put(UID.MRImageStorage, "MRImageStorage");
499                        sopClasses.put(UID.EnhancedMRImageStorage, "EnhancedMRImageStorage");
500                        sopClasses.put(UID.MRSpectroscopyStorage, "MRSpectroscopyStorage");
501                        sopClasses.put(UID.RTImageStorage, "RTImageStorage");
502                        sopClasses.put(UID.RTDoseStorage, "RTDoseStorage");
503                        sopClasses.put(UID.RTStructureSetStorage, "RTStructureSetStorage");
504                        sopClasses.put(UID.RTBeamsTreatmentRecordStorage, "RTBeamsTreatmentRecordStorage");
505                        sopClasses.put(UID.RTPlanStorage, "RTPlanStorage");
506                        sopClasses.put(UID.RTBrachyTreatmentRecordStorage, "RTBrachyTreatmentRecordStorage");
507                        sopClasses.put(UID.RTTreatmentSummaryRecordStorage, "RTTreatmentSummaryRecordStorage");
508                        sopClasses.put(UID.NuclearMedicineImageStorageRetired, "NuclearMedicineImageStorage (Retired)");
509                        sopClasses.put(UID.UltrasoundImageStorageRetired, "UltrasoundImageStorage (Retired)");
510                        sopClasses.put(UID.UltrasoundImageStorage, "UltrasoundImageStorage");
511                        sopClasses.put(UID.RawDataStorage, "RawDataStorage");
512                        sopClasses.put(UID.SpatialRegistrationStorage, "SpatialRegistrationStorage");
513                        sopClasses.put(UID.SpatialFiducialsStorage, "SpatialFiducialsStorage");
514                        sopClasses.put(UID.RealWorldValueMappingStorage, "RealWorldValueMappingStorage");
515                        sopClasses.put(UID.SecondaryCaptureImageStorage, "SecondaryCaptureImageStorage");
516                        sopClasses.put(UID.MultiFrameSingleBitSecondaryCaptureImageStorage, "MultiframeSingleBitSecondaryCaptureImageStorage");
517                        sopClasses.put(UID.MultiFrameGrayscaleByteSecondaryCaptureImageStorage, "MultiframeGrayscaleByteSecondaryCaptureImageStorage");
518                        sopClasses.put(UID.MultiFrameGrayscaleWordSecondaryCaptureImageStorage, "MultiframeGrayscaleWordSecondaryCaptureImageStorage");
519                        sopClasses.put(UID.MultiFrameTrueColorSecondaryCaptureImageStorage, "MultiframeTrueColorSecondaryCaptureImageStorage");
520                        sopClasses.put(UID.VLImageStorageTrialRetired, "VLImageStorage (Retired)");
521                        sopClasses.put(UID.VLEndoscopicImageStorage, "VLEndoscopicImageStorage");
522                        sopClasses.put(UID.VideoEndoscopicImageStorage, "VideoEndoscopicImageStorage");
523                        sopClasses.put(UID.VLMicroscopicImageStorage, "VLMicroscopicImageStorage");
524                        sopClasses.put(UID.VideoMicroscopicImageStorage, "VideoMicroscopicImageStorage");
525                        sopClasses.put(UID.VLSlideCoordinatesMicroscopicImageStorage, "VLSlideCoordinatesMicroscopicImageStorage");
526                        sopClasses.put(UID.VLPhotographicImageStorage, "VLPhotographicImageStorage");
527                        sopClasses.put(UID.VideoPhotographicImageStorage, "VideoPhotographicImageStorage");
528                        sopClasses.put(UID.OphthalmicPhotography8BitImageStorage, "OphthalmicPhotography8BitImageStorage");
529                        sopClasses.put(UID.OphthalmicPhotography16BitImageStorage, "OphthalmicPhotography16BitImageStorage");
530                        sopClasses.put(UID.StereometricRelationshipStorage, "StereometricRelationshipStorage");
531                        sopClasses.put(UID.VLMultiFrameImageStorageTrialRetired, "VLMultiframeImageStorage (Retired)");
532                        sopClasses.put(UID.StandaloneOverlayStorageRetired, "StandaloneOverlayStorage (Retired)");
533                        sopClasses.put(UID.BasicTextSRStorage, "BasicTextSR");
534                        sopClasses.put(UID.EnhancedSRStorage, "EnhancedSR");
535                        sopClasses.put(UID.ComprehensiveSRStorage, "ComprehensiveSR");
536                        sopClasses.put(UID.ProcedureLogStorage, "ProcedureLogStorage");
537                        sopClasses.put(UID.MammographyCADSRStorage, "MammographyCADSR");
538                        sopClasses.put(UID.KeyObjectSelectionDocumentStorage, "KeyObjectSelectionDocument");
539                        sopClasses.put(UID.ChestCADSRStorage,  "ChestCADSR");
540                        sopClasses.put(UID.StandaloneCurveStorageRetired, "StandaloneCurveStorage (Retired)");
541                        sopClasses.put(UID.GeneralECGWaveformStorage, "GeneralECGWaveformStorage");
542                        sopClasses.put(UID.AmbulatoryECGWaveformStorage,  "AmbulatoryECGWaveformStorage");
543                        sopClasses.put(UID.HemodynamicWaveformStorage, "HemodynamicWaveformStorage");
544                        sopClasses.put(UID.CardiacElectrophysiologyWaveformStorage, "CardiacElectrophysiologyWaveformStorage");
545                        sopClasses.put(UID.BasicVoiceAudioWaveformStorage, "BasicVoiceAudioWaveformStorage");
546                        sopClasses.put(UID.HangingProtocolStorage, "HangingProtocolStorage");
547                        sopClasses.put(UID.SiemensCSANonImageStorage, "SiemensCSANonImageStorage");
548                        sopClasses.put(UID.VLWholeSlideMicroscopyImageStorage, "VLWholeSlideMicroscopyImageStorage");
549                        sopClasses.put(UID.BreastTomosynthesisImageStorage, "BreastTomosynthesisImageStorage");
550
551                        transferSettings.put(UID.ImplicitVRLittleEndian, "ImplicitVRLittleEndian");
552                        transferSettings.put(UID.ExplicitVRLittleEndian, "ExplicitVRLittleEndian");
553                        transferSettings.put(UID.DeflatedExplicitVRLittleEndian, "DeflatedExplicitVRLittleEndian");
554                        transferSettings.put(UID.ExplicitVRBigEndian, "ExplicitVRBigEndian");
555                        transferSettings.put(UID.JPEGLossless, "JPEG Lossless");
556                        transferSettings.put(UID.JPEGLSLossless, "JPEG Lossless LS");
557                        transferSettings.put(UID.JPEGLosslessNonHierarchical14, "JPEG Lossless, Non-Hierarchical (Process 14) ");
558                        transferSettings.put(UID.JPEG2000LosslessOnly, "JPEG2000 Lossless Only");
559                        transferSettings.put(UID.JPEGBaseline1, "JPEG Baseline 1");
560                        transferSettings.put(UID.JPEGExtended24, "JPEG Extended (Process 2 & 4)");
561                        transferSettings.put(UID.JPEGLSLossyNearLossless, "JPEG LS Lossy Near Lossless");
562                        transferSettings.put(UID.JPEG2000, "JPEG2000");
563                        transferSettings.put(UID.RLELossless, "RLE Lossless");
564                        transferSettings.put(UID.MPEG2, "MPEG2");
565
566                        transferSettingsIndex.put(UID.ImplicitVRLittleEndian, 0);
567                        transferSettingsIndex.put(UID.ExplicitVRLittleEndian, 1);
568                        transferSettingsIndex.put(UID.DeflatedExplicitVRLittleEndian, 2);
569                        transferSettingsIndex.put(UID.ExplicitVRBigEndian, 3);
570                        transferSettingsIndex.put(UID.JPEGLossless, 4);
571                        transferSettingsIndex.put(UID.JPEGLSLossless, 5);
572                        transferSettingsIndex.put(UID.JPEGLosslessNonHierarchical14, 6);
573                        transferSettingsIndex.put(UID.JPEG2000LosslessOnly, 7);
574                        transferSettingsIndex.put(UID.JPEGBaseline1, 8);
575                        transferSettingsIndex.put(UID.JPEGExtended24, 9);
576                        transferSettingsIndex.put(UID.JPEGLSLossyNearLossless, 10);
577                        transferSettingsIndex.put(UID.JPEG2000, 11);
578                        transferSettingsIndex.put(UID.RLELossless, 12);
579                        transferSettingsIndex.put(UID.MPEG2, 13);
580                }
581
582                /**
583                 * Returns the SOP Classes UID and "regular" name translation list.
584                 *
585                 * @return the SOP Classes UID and "regular" name translation list.
586                 */
587                public HashMap<String, String> getSOPClasses()
588                {
589                        return sopClasses;
590                }
591
592                /**
593                 * Returns the TransferStorage UID and "regular" name translation list.
594                 *
595                 * @return the TransferStorage UID and "regular" name translation list.
596                 */
597                public HashMap<String, String> getTransferSettings()
598                {
599                        return transferSettings;
600                }
601
602                /**
603                 * Returns the TransferStorage UID and their index on the TS object translation list.
604                 *
605                 * @return the TransferStorage UID and their index on the TS object translation list.
606                 */
607                public HashMap<String, Integer> getTransferSettingsIndex()
608                {
609                        return transferSettingsIndex;
610                }
611
612                /**
613                 * Returns the current instance of this class.
614                 *
615                 * @return the current instance of this class.
616                 */
617                public static synchronized SOPClassSettings getInstance()
618                {
619                        if (instance == null)
620                                instance = new SOPClassSettings();
621
622                        return instance;
623                }
624
625                /**
626                 * Returns the TransferStorage settings fo a SOP Class UID.
627                 *
628                 * @param sopClassUID the SOP Class UID.
629                 * @return the TransferStorage settings fo a SOP Class UID.
630                 */
631                public synchronized TransfersStorage getSOPClassSettings(String sopClassUID)
632                {
633                        return sopList.getTS(sopClassUID);
634                }
635
636                /**
637                 * Defines all the settings values related to all SOP Classes UIDs.
638                 *
639                 * @param accepted if this SOP Class is accepted. Can be null and if so, the target accepted value will remain the same.
640                 * @param allowedTransStore a HashMap indicating which TransferStore UIDs are accepted.
641                 */
642                public synchronized void setAllSOPClassesSettings(Boolean accepted, HashMap<String, Boolean> allowedTransStore)
643                {
644                        // for all the sop classes
645                        List keys = sopList.getKeys();
646                        for (int i = 0; i < keys.size(); i++)
647                        {
648                                // get the sop class uid
649                                String sopClassUID = (String) keys.get(i);
650
651                                // apply the settings
652                                setSOPClassSettings(sopClassUID, accepted, allowedTransStore);
653                        }
654                }
655
656                /**
657                 * Defines all the settings values related to a SOP Class UID.
658                 *
659                 * @param sopClassUID the SOP Class UID.
660                 * @param accepted if this SOP Class is accepted. Can be null and if so, the target accepted value will remain the same.
661                 * @param allowedTransStore a HashMap indicating which TransferStore UIDs are accepted.
662                 */
663                public synchronized void setSOPClassSettings(String sopClassUID, Boolean accepted, HashMap<String, Boolean> allowedTransStore)
664                {
665                        // get the transfer storage object for this sop class uid
666                        TransfersStorage trans = sopList.getTS(sopClassUID);
667
668                        // apply the settings
669                        setTransferStorageSettings(trans, accepted, allowedTransStore);
670                }
671
672                /**
673                 * Defines all the settings values related to a TransferStorage object.
674                 *
675                 * @param trans the TransferStorage object.
676                 * @param accepted if this SOP Class is accepted. Can be null and if so, the target accepted value will remain the same.
677                 * @param allowedTransStore a HashMap indicating which TransferStore UIDs are accepted.
678                 */
679                public synchronized void setTransferStorageSettings(TransfersStorage trans, Boolean accepted, HashMap<String, Boolean> allowedTransStore)
680                {
681                        // accept this sop class, if necessary
682                        if (accepted != null)
683                                trans.setAccepted(accepted.booleanValue());
684                        // accept all the transfer storage settings
685                        for (String transStoreUID : transferSettings.keySet())
686                        {
687                                // skip this transfer store uid if it is not referenced on the allowedTransStore // FIXME is this right, or should non-defined entries be set as false?!?
688                                if (! allowedTransStore.containsKey(transStoreUID))
689                                        continue;
690
691                                trans.setTS(allowedTransStore.get(transStoreUID).booleanValue(), transferSettingsIndex.get(transStoreUID).intValue());
692                        }
693                }
694        }
695
696        /**
697         * Returns a StaticDataTable containing the TransferStorages for a
698         * specific SOP Class UID.
699         *
700         * @param sopClassUID a SOP Class UID.
701         * @return an Object array containing as first elements a Boolean object
702         * indicating if this SOP Class is accepted and as second element a
703         * StaticDataTable that contains the TransferStorages for this specific
704         * SOP Class UID.
705         */
706        public Object[] getTransferSettingsForSOPClass(String sopClassUID)
707        {
708                SOPClassSettings sops = SOPClassSettings.getInstance();
709                TransfersStorage ts = sops.getSOPClassSettings(sopClassUID);
710
711                // this settings will be returned on a StaticDataTable, to guarantee that the user does not change the entry count and only their values
712                StaticDataTable table = new StaticDataTable(1, sops.getTransferSettings().size());
713                // for each setting on the transfer storage settings...
714                int i = 0;
715                for (Map.Entry<String, String> entry : sops.getTransferSettings().entrySet())
716                {
717                        // get its UID, "visual/regular" name and index (relative to the TS settings array)
718                        String uid = entry.getKey();
719                        String name = entry.getValue();
720                        int index = sops.getTransferSettingsIndex().get(uid).intValue();
721
722                        // create a HintedCheckbox with the info gotten above and the current value of the setting
723                        CheckboxWithHint box = new CheckboxWithHint(ts.getTS()[index], name, uid);
724                        // and add the checkbox to the data table
725                        table.setCellData(i, 0, box);
726
727                        i++;
728                }
729
730                // mount the return object array
731                Object[] result = new Object[2];
732                // and add the proper objects to it
733                result[0] = new Boolean(ts.getAccepted());
734                result[1] = table;
735
736                return result;
737        }
738
739        /**
740         * Returns a StaticDataTable containing the TransferStorages settings
741         * for all SOP Classes UIDs.
742         *
743         * @return an Object array containing as first elements a Boolean object
744         * indicating if all SOP Classes are accepted and as second element a
745         * StaticDataTable that contains the TransferStorages for all SOP Classes
746         * UIDs.
747         */
748        public Object[] getTransferSettingsForAllSOPClasses()
749        {
750                SOPClassSettings sops = SOPClassSettings.getInstance();
751
752                // get the first SOP Class UID // FIXME using the first SOP Class settings as global does not accurately represent the common settings for all SOP classes, but it's close enough (if they get applied :) )
753                String sopClassUID = sops.getSOPClasses().entrySet().iterator().next().getKey();
754                // and its TransferStorage settings
755                TransfersStorage ts = sops.getSOPClassSettings(sopClassUID);
756
757                // this settings will be returned on a StaticDataTable, to guarantee that the user does not change the entry count and only their values
758                StaticDataTable table = new StaticDataTable(1, sops.getTransferSettings().size());
759                table.setColumnName(0, "Transfer Storage");
760                // for each setting on the transfer storage settings...
761                int i = 0;
762                for (Map.Entry<String, String> entry : sops.getTransferSettings().entrySet())
763                {
764                        // get its UID, "visual/regular" name and index (relative to the TS settings array)
765                        String uid = entry.getKey();
766                        String name = entry.getValue();
767                        int index = sops.getTransferSettingsIndex().get(uid).intValue();
768
769                        // create a HintedCheckbox with the info gotten above and the current value of the setting
770                        CheckboxWithHint box = new CheckboxWithHint(ts.getTS()[index], name, uid);
771                        // and add the checkbox to the data table
772                        table.setCellData(i, 0, box);
773
774                        i++;
775                }
776
777                // mount the return object array
778                Object[] result = new Object[2];
779                // and add the proper objects to it
780                result[0] = new Boolean(ts.getAccepted());
781                result[1] = table;
782
783                return result;
784        }
785
786        /**
787         * Applies the Transfer Storage settings present on a StaticDataTable to
788         * a specific SOP Class UID.
789         *
790         * @param sopClassUID the target SOP Class UID.
791         * @param accepted if the SOP Class UID is accepted. Can be null and if so, the target accepted value will remain the same.
792         * @param table a StaticDataTable with the Transfer Storage settings.
793         */
794        public void setTransferSettingsForSOPClass(String sopClassUID, Boolean accepted, StaticDataTable table)
795        {
796                SOPClassSettings sops = SOPClassSettings.getInstance();
797                TransfersStorage ts = sops.getSOPClassSettings(sopClassUID);
798
799                // for each transfer storage setting on the datatable...
800                for (int i = 0 ; i < table.getRowCount(); i++)
801                {
802                        // get the current row/cell setting
803                        CheckboxWithHint box = (CheckboxWithHint) table.getCellData(i, 0);
804
805                        // get its UID and index (relative to the TS settings array)
806                        String uid = box.getHint();
807                        int index = sops.getTransferSettingsIndex().get(uid).intValue();
808
809                        // set the transfer storge setting value
810                        ts.setTS(box.isChecked(), index);
811                        if (accepted != null)
812                                ts.setAccepted(accepted.booleanValue());
813                }
814        }
815
816        /**
817         * Applies the Transfer Storage settings present on a StaticDataTable to
818         * all SOP Classes UIDs.
819         *
820         * @param accepted if all SOP Classes UIDs are accepted. Can be null and if so, the target accepted value will remain the same.
821         * @param table a StaticDataTable with the Transfer Storage settings.
822         */
823        public void setTransferSettingsForAllSOPClasses(Boolean accepted, StaticDataTable table)
824        {
825                SOPClassSettings sops = SOPClassSettings.getInstance();
826
827                HashMap<String, Boolean> allowed = new HashMap<String, Boolean>();
828
829                // for each transfer storage setting on the datatable...
830                for (int i = 0 ; i < table.getRowCount(); i++)
831                {
832                        // get the current row/cell setting
833                        CheckboxWithHint box = (CheckboxWithHint) table.getCellData(i, 0);
834
835                        // get its UID
836                        String uid = box.getHint();
837
838                        allowed.put(uid, new Boolean(box.isChecked()));
839                }
840
841                // set the transfer storage settings
842                sops.setAllSOPClassesSettings(accepted, allowed);
843        }
844}