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.io.File;
022import java.net.URI;
023import java.net.URISyntaxException;
024import java.util.ArrayList;
025import java.util.HashMap;
026import java.util.List;
027import org.slf4j.LoggerFactory;
028
029
030import pt.ua.dicoogle.core.ServerSettings;
031import pt.ua.dicoogle.plugins.PluginController;
032import pt.ua.dicoogle.sdk.datastructs.Report;
033import pt.ua.dicoogle.sdk.task.Task;
034
035/**
036 * A wrapper used to manage the indexer remotely through the web environment/app.
037 *
038 * @author António Novo <antonio.novo@ua.pt>
039 */
040public class Indexer{
041        /**
042         * The current instance of this class.
043         */
044        private static Indexer instance;
045
046        /**
047         * Pointer to a object that maintain the IndexEngine information.
048         */
049
050        private static ServerSettings cfg;
051        
052        private static List<Task> taskList;
053
054
055        /**
056         * The name of the setting that indicates the Dicoogle Directory Monitorization.
057         */
058        public static final String SETTING_DIRECTORY_MONITORIZATION_NAME = "Dicoogle Directory Monitorization";
059        /**
060         * The name of the setting that indicates the Indexing Effort.
061         */
062        public static final String SETTING_INDEXING_EFFORT_NAME = "Indexing Effort";
063        /**
064         * The name of the setting that indicates the Thumbnails Size.
065         */
066        public static final String SETTING_THUMBNAILS_SIZE_NAME = "Thumbnails Size";
067        /**
068         * The name of the setting that indicates if Thumbnails are to be Saved.
069         */
070        public static final String SETTING_SAVE_THUMBNAILS_NAME = "Save Thumbnails";
071        /**
072         * The name of the setting that indicates if ZIP files are to be Indexed.
073         */
074        public static final String SETTING_INDEX_ZIP_FILES_NAME = "Index ZIP Files";
075
076        /**
077         * The help of the Indexing Effort setting.
078         */
079        public static final String SETTING_INDEXING_EFFORT_HELP = "How agressive should the indexing effort be.\n\n0 - Lower\n100 - Intensive";
080
081        private Indexer(){
082                
083                cfg = ServerSettings.getInstance();
084                taskList = new ArrayList<Task>();
085        }
086
087        /**
088         * Returns the current instance of this class.
089         *
090         * @return the current instance of this class.
091         */
092        public synchronized static Indexer getInstance(){
093                if (instance == null)
094                        instance = new Indexer();
095
096                return instance;
097        }
098
099        /**
100         * Returns a Map containing the current settings.
101         *
102         * @return a Map containing the current settings.
103         */
104        public HashMap<String, Object> getSettings()
105        {
106                HashMap<String, Object> settings = new HashMap<String, Object>();
107
108                //settings.put(SETTING_DIRECTORY_MONITORIZATION_NAME, new ServerDirectoryPath(cfg.getDicoogleDir()));
109                //settings.put(SETTING_INDEXING_EFFORT_NAME, new RangeInteger(0, 100, cfg.getIndexerEffort()));
110                settings.put(SETTING_THUMBNAILS_SIZE_NAME, cfg.getThumbnailsMatrix()); // TODO add more descritive type
111                settings.put(SETTING_SAVE_THUMBNAILS_NAME, cfg.getSaveThumbnails());
112                settings.put(SETTING_INDEX_ZIP_FILES_NAME, cfg.isIndexZIPFiles());
113
114                return settings;
115        }
116
117        /**
118         * Tries to set the supplied settings as the new settings.
119         *
120         * @param settings a Map containing the new settings.
121         * @return true if all settings were successfully changed to the ones supplied, false otherwise (no settings changed).
122         */
123        public boolean setSettings(HashMap<String, Object> settings)
124        {
125                // validate the settings
126                boolean valid = false;
127                try
128                {
129                        valid = trySettings(settings);
130                }
131                catch (/*InvalidSettingValueException ex*/ Exception ex)
132                {
133                        // at least one of the setting is invalid, abort
134                        return false;
135                }
136                if (! valid) //settings not valid due to unknown reason, also abort
137                        return false;
138
139                // all the settings were correctly validated, so apply them all
140                //cfg.setDicoogleDir(((ServerDirectoryPath) settings.get(SETTING_DIRECTORY_MONITORIZATION_NAME)).getPath());
141                //cfg.setIndexerEffort(((RangeInteger) settings.get(SETTING_INDEXING_EFFORT_NAME)).getValue());
142                cfg.setThumbnailsMatrix((String) settings.get(SETTING_THUMBNAILS_SIZE_NAME));
143                cfg.setSaveThumbnails(((Boolean) settings.get(SETTING_SAVE_THUMBNAILS_NAME)).booleanValue());
144                cfg.setIndexZIPFiles(((Boolean) settings.get(SETTING_INDEX_ZIP_FILES_NAME)).booleanValue());
145
146                // return success
147                return true;
148        }
149
150        /**
151         * Validates the settings supplied and checks if they are valid ones.
152         *
153         * @param map a Map containing the settings.
154         * @return true if all the settings are valid.
155         * @throws InvalidSettingValueException if at least one of the settings is invalid.
156         */
157        public boolean trySettings(HashMap<String, Object> map) /*throws InvalidSettingValueException*/
158        {
159                // TODO remmember to check for null, all the params are supplied, all have valid types, and oly then all have valid values
160
161                return true;
162        }
163
164        /**
165         * Returns the settings help.
166         *
167         * @return a HashMap containing the setting help.
168         */
169        public HashMap<String, String> getSettingsHelp(){
170                HashMap<String, String> settings = new HashMap<String, String>();
171                // right now this is the only settingg that needs some help describing it
172                settings.put(SETTING_INDEXING_EFFORT_NAME, SETTING_INDEXING_EFFORT_HELP);
173                return settings;
174        }
175
176        /**
177         * Starts the indexing process.
178         */
179        public void startIndexing(){
180                File dir = new File(cfg.getDicoogleDir());
181                if ((dir == null) || (! dir.isDirectory()))
182                        return;
183                String path = dir.getAbsolutePath();
184                if (path == null)
185                        return;
186                
187                URI uri = null;
188                try {
189                    uri = new URI(path);
190                } catch (URISyntaxException ex) {
191                    LoggerFactory.getLogger(Indexer.class).error(ex.getMessage(), ex);
192                }
193                if (uri != null)
194                {
195                    List<Task<Report>> tmpList = PluginController.getInstance().index(uri);
196                    
197                    for (Task _t : tmpList)
198                    {
199                        taskList.add(_t);
200                    }
201                    
202                }
203        }
204
205        /**
206         * Stops the indexing process.
207         */
208        public void stopIndexing()
209        {
210            
211            for (Task _t : taskList)
212            {
213                        _t.cancel(true);
214            }
215                    
216        }
217
218        /**
219         * Returns if the Index Engine is currently indexing.
220         *
221         * @return if the Index Engine is currently indexing.
222         */
223        public boolean isIndexing(){
224                
225            
226            int numberOfActiveTasks = 0;
227            for (Task _t : taskList)
228            {
229                if (_t.getProgress()<100)
230                {
231                    numberOfActiveTasks++;
232                }
233            }
234            return numberOfActiveTasks!=0;
235        }
236
237        /**
238         * Returns the current progress (percentual) of the indexing operation.
239         *
240         * @return the current progress (percentual) of the indexing operation.
241         */
242        public int indexingPercentCompleted(){
243                
244            
245            int numberOfTasks = 0;
246            float all=0;
247            for (Task _t : taskList)
248            {
249                
250                all = all + _t.getProgress();
251                numberOfTasks++;
252                
253            }
254            return (int)(all*100.0/(100*numberOfTasks));
255            
256        }
257
258        /**
259         * Sets the Dicoogle indexing path.
260         *
261         * @param path the Dicoogle indexing path.
262         */
263        public void setDicooglePath(String path){
264                cfg.setDicoogleDir(path);
265        }
266
267        /**
268         * Gets the Dicoogle indexing path.
269         *
270         * @return the Dicoogle indexing path.
271         */
272        public String getDicooglePath(){
273                return cfg.getDicoogleDir();
274        }
275}