ijfx.ui.explorer.DefaultFolderManagerService.java Source code

Java tutorial

Introduction

Here is the source code for ijfx.ui.explorer.DefaultFolderManagerService.java

Source

/*
This file is part of ImageJ FX.
    
ImageJ FX is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
ImageJ FX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with ImageJ FX.  If not, see <http://www.gnu.org/licenses/>. 
    
 Copyright 2015,2016 Cyril MONGIS, Michael Knop
       
 */
package ijfx.ui.explorer;

import ijfx.core.imagedb.MetaDataExtractionService;
import ijfx.core.metadata.MetaData;
import ijfx.core.stats.IjfxStatisticService;
import ijfx.service.ui.JsonPreferenceService;
import ijfx.service.ui.LoadingScreenService;
import ijfx.service.uicontext.UiContextService;
import ijfx.ui.explorer.event.FolderAddedEvent;
import ijfx.ui.explorer.event.FolderDeletedEvent;
import ijfx.ui.explorer.event.FolderUpdatedEvent;
import ijfx.ui.main.ImageJFX;
import ijfx.ui.notification.DefaultNotification;
import ijfx.ui.notification.NotificationService;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
import mongis.utils.AsyncCallable;
import mongis.utils.CallbackTask;
import mongis.utils.ProgressHandler;
import mongis.utils.SilentProgressHandler;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
import org.scijava.Context;
import org.scijava.event.EventHandler;
import org.scijava.event.EventService;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;
import org.scijava.service.AbstractService;
import org.scijava.service.Service;

/**
 *
 * @author cyril
 */
@Plugin(type = Service.class)
public class DefaultFolderManagerService extends AbstractService implements FolderManagerService {

    List<Folder> folderList;

    Folder currentFolder;

    @Parameter
    ExplorerService explorerService;

    @Parameter
    EventService eventService;

    @Parameter
    Context context;

    @Parameter
    UiContextService uiContextService;

    @Parameter
    JsonPreferenceService jsonPrefService;

    @Parameter
    MetaDataExtractionService metaDataExtractionService;

    @Parameter
    LoadingScreenService loadingScreenService;

    @Parameter
    IjfxStatisticService statsService;

    @Parameter
    NotificationService notificationService;

    private static String FOLDER_PREFERENCE_FILE = "folder_db.json";

    Logger logger = ImageJFX.getLogger();

    ExplorationMode currentExplorationMode;

    List<Explorable> currentItems;

    ExecutorService executorService = Executors.newFixedThreadPool(1);

    @Override
    public Folder addFolder(File file) {
        Folder f = new DefaultFolder(file);
        context.inject(f);
        return addFolder(f);
    }

    protected Folder addFolder(Folder f) {
        getFolderList().add(f);

        if (folderList.size() == 1) {
            setCurrentFolder(f);
        }

        eventService.publish(new FolderAddedEvent().setObject(f));
        save();
        return f;
    }

    @Override
    public List<Folder> getFolderList() {

        if (folderList == null) {
            folderList = new ArrayList<>();
            load();
        }

        return folderList;
    }

    @Override
    public Folder getCurrentFolder() {
        return currentFolder;
    }

    @Override
    public void setCurrentFolder(Folder folder) {
        currentFolder = folder;

        if (currentFolder == null) {

            setItems(new ArrayList<>());
            updateExploredElements();
        } else {

            logger.info("Setting current folder " + folder.getName());

            explorerService.setItems(currentFolder.getFileList());

            uiContextService.enter("explore-files");
            uiContextService.update();
            updateExploredElements();
        }
    }

    @EventHandler
    public void onFolderUpdated(FolderUpdatedEvent event) {
        logger.info("Folder updated ! " + event.getObject().getName());
        if (currentFolder == event.getObject()) {
            updateExploredElements();
        }
    }

    @Override
    public void setExplorationMode(ExplorationMode mode) {
        if (mode == currentExplorationMode) {
            return;
        }
        currentExplorationMode = mode;
        eventService.publish(new ExplorationModeChangeEvent().setObject(mode));
        updateExploredElements();
    }

    private void updateExploredElements() {

        ExplorationMode mode = currentExplorationMode;

        AsyncCallable<List<Explorable>> task = new AsyncCallable<>();
        task.setTitle("Fetching elements...");

        if (currentFolder == null) {
            return;
        } else {

            if (null != mode) {
                switch (mode) {
                case FILE:
                    task.run(currentFolder::getFileList);
                    break;
                case PLANE:
                    task.run(currentFolder::getPlaneList);
                    break;
                default:
                    task.run(currentFolder::getObjectList);
                    break;
                }
            }
            task.then(this::setItems);
            task.start();
            loadingScreenService.frontEndTask(task, false);
        }
        logger.info("Exploration mode changed : " + mode.toString());
    }

    private void setItems(List<Explorable> items) {
        explorerService.setItems(items);

    }

    private Integer fetchMoreStatistics(ProgressHandler progress, List<Explorable> explorableList) {
        if (progress == null)
            progress = new SilentProgressHandler();
        progress.setStatus("Completing statistics of the objects");
        Integer elementAnalyzedCount = 0;
        int elements = explorableList.size();
        int i = 0;
        for (Explorable e : explorableList) {
            if (!e.getMetaDataSet().containsKey(MetaData.STATS_PIXEL_MIN)) {
                progress.setProgress(i, elements);
                if (e instanceof ImageRecordIconizer) {
                    ImageRecordIconizer iconizer = (ImageRecordIconizer) e;
                    SummaryStatistics stats = statsService.getStatistics(iconizer.getImageRecord().getFile());
                    iconizer.getMetaDataSet().putGeneric(MetaData.STATS_PIXEL_MIN, stats.getMin());
                    iconizer.getMetaDataSet().putGeneric(MetaData.STATS_PIXEL_MAX, stats.getMax());
                    iconizer.getMetaDataSet().putGeneric(MetaData.STATS_PIXEL_MEAN, stats.getMean());
                    iconizer.getMetaDataSet().putGeneric(MetaData.STATS_PIXEL_STD_DEV, stats.getMean());
                    elementAnalyzedCount++;
                }
            }
            i++;
        }
        return elementAnalyzedCount;
    }

    @Override
    public ExplorationMode getCurrentExplorationMode() {
        return currentExplorationMode;
    }

    private void save() {
        HashMap<String, String> folderMap = new HashMap<>();
        for (Folder f : getFolderList()) {
            folderMap.put(f.getName(), f.getDirectory().getAbsolutePath());
        }
        jsonPrefService.savePreference(folderMap, FOLDER_PREFERENCE_FILE);
    }

    private synchronized void load() {
        Map<String, String> folderMap = jsonPrefService.loadMapFromJson(FOLDER_PREFERENCE_FILE, String.class,
                String.class);
        folderMap.forEach((name, folderPath) -> {
            DefaultFolder folder = new DefaultFolder(new File(folderPath));
            context.inject(folder);
            folder.setName(name);
            folderList.add(folder);
        });
    }

    @Override
    public void completeStatistics() {
        loadingScreenService
                .frontEndTask(new CallbackTask<List<Explorable>, Integer>().run(this::fetchMoreStatistics)
                        .setInput(getCurrentFolder().getFileList()).then(this::onStatisticComputingEnded).start());

    }

    private void onStatisticComputingEnded(Integer computedImages) {
        notificationService.publish(new DefaultNotification("Statistic Computation",
                String.format("%d images where computed.", computedImages)));
    }

    public void removeFolder(Folder folder) {
        folderList.remove(folder);
        eventService.publish(new FolderDeletedEvent().setObject(folder));
    }

}