ome.formats.importer.gui.ImportHandler.java Source code

Java tutorial

Introduction

Here is the source code for ome.formats.importer.gui.ImportHandler.java

Source

/*
 * ome.formats.importer.gui.History
 *
 *------------------------------------------------------------------------------
 *
 *  Copyright (C) 2005 Open Microscopy Environment
 *      Massachusetts Institute of Technology,
 *      National Institutes of Health,
 *      University of Dundee
 *
 *
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation; either
 *    version 2.1 of the License, or (at your option) any later version.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *------------------------------------------------------------------------------
 */

package ome.formats.importer.gui;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.ScheduledExecutorService;

import javax.swing.JOptionPane;

import loci.formats.FormatException;
import ome.formats.importer.IObservable;
import ome.formats.importer.IObserver;
import ome.formats.importer.ImportConfig;
import ome.formats.importer.ImportContainer;
import ome.formats.importer.ImportEvent;
import ome.formats.importer.ImportLibrary;
import omero.ResourceError;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Importer is master file format importer for all supported formats and imports
 * the files to an OMERO database
 * 
 * @author Brian W. Loranger
 * @basedOnCodeFrom Curtis Rueden ctrueden at wisc.edu
 */
public class ImportHandler implements IObservable {

    private static Log log = LogFactory.getLog(ImportHandler.class);

    private static boolean runState = false;

    private final ImportLibrary library;
    private final ImportContainer[] importContainer;
    private final HistoryTableStore db; // THIS SHOULD NOT BE HERE!

    private final GuiImporter viewer;
    private final FileQueueTable qTable;

    private int numOfPendings = 0;
    private int numOfDone = 0;

    final ArrayList<IObserver> observers = new ArrayList<IObserver>();

    private ImportConfig config;

    /**
     * @param ex -scheduled executor service for background processing
     * @param viewer - parent
     * @param qTable - fileQueueTable to receive notifications
     * @param config - passed in config
     * @param library - passed in library
     * @param containers - importContainers
     */
    public ImportHandler(final ScheduledExecutorService ex, GuiImporter viewer, FileQueueTable qTable,
            ImportConfig config, ImportLibrary library, ImportContainer[] containers) {

        this.config = config;
        this.library = library;
        this.importContainer = containers;
        if (viewer.getHistoryTable() != null) {
            this.db = viewer.getHistoryTable().db;
        } else {
            this.db = null;
        }

        if (runState == true) {
            log.error("ImportHandler running twice");
            throw new RuntimeException("ImportHandler running twice");
        }
        runState = true;
        try {
            this.viewer = viewer;
            this.qTable = qTable;
            library.addObserver(qTable);
            library.addObserver(viewer);
            library.addObserver(viewer.getErrorHandler());
            library.addObserver(new IObserver() {
                public void update(IObservable importLibrary, ImportEvent event) {
                    if (ex.isShutdown()) {
                        log.info("Cancelling import");
                        throw new RuntimeException("CLIENT SHUTDOWN");
                    }

                }
            });

            Runnable run = new Runnable() {
                public void run() {
                    log.info("Background: Importing images");
                    importImages();
                }
            };
            ex.execute(run);
        } finally {
            runState = false; // FIXME this should be set from inside the thread, right?
        }
    }

    /**
     * Begin the import process, importing first the meta data, and then each
     * plane of the binary image data.
     */
    private void importImages() {
        long timestampIn;
        long timestampOut;
        long timestampDiff;
        long timeInSeconds;
        long hours, minutes, seconds;
        Date date = null;

        notifyObservers(new ImportEvent.IMPORT_QUEUE_STARTED());

        // record initial timestamp and record total running time for the import
        timestampIn = System.currentTimeMillis();
        date = new Date(timestampIn);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String myDate = formatter.format(date);

        viewer.appendToOutputLn("> Starting import at: " + myDate + "\n");
        viewer.getStatusBar().setStatusIcon("gfx/import_icon_16.png", "Now importing.");

        numOfPendings = 0;
        int importKey = 0;
        int importStatus = 0;

        importKey = addHistoryPendingImport();

        for (int i = 0; i < importContainer.length; i++) {
            if (qTable.setProgressPending(i)) {
                numOfPendings++;
                try {
                    if (db != null && db.historyEnabled == true) {
                        // FIXME: This is now "broken" with targets now able to
                        // be of type Screen or Dataset.                       
                        db.addItemTableRow(library.getExperimenterID(), importKey, i,
                                importContainer[i].getFile().getAbsolutePath(), importContainer[i].getProjectID(),
                                importContainer[i].getTarget().getId().getValue(), "pending",
                                importContainer[i].getFile());
                    }
                } catch (Exception e) {
                    log.error("Generic error while inserting history.", e);
                    viewer.appendToDebug(e.toString());
                }
            }
        }

        if (db != null)
            db.notifyObservers(new ImportEvent.QUICKBAR_UPDATE());
        viewer.getStatusBar().setProgressMaximum(numOfPendings);

        numOfDone = 0;
        for (int j = 0; j < importContainer.length; j++) {
            ImportContainer container = importContainer[j];

            if (qTable.getTable().getValueAt(j, 2).equals("pending") && qTable.cancel == false) {
                numOfDone++;
                String filename = container.getFile().getAbsolutePath();

                viewer.appendToOutputLn("> [" + j + "] Importing \"" + filename + "\"");

                try {
                    library.importImage(container, j, numOfDone, numOfPendings);
                    /*
                     library.importImage(importContainer[j].getFile(), j, numOfDone,
                        numOfPendings, importContainer[j]
                                .getCustomImageName(), null, // Description
                        container.getArchive(), config.companionFile.get(), // Metadata file creation
                        // (TODO: Enable in container and UI)
                        container.getUserPixels(), container.getTarget());
                        */
                    this.library.clear();

                    updateHistoryWithDoneImport(importKey, j);
                } catch (FormatException fe) {
                    log.error("Format exception while importing image.", fe);
                    qTable.setProgressFailed(j);
                    viewer.appendToOutputLn("> [" + j + "] Failure importing.");
                    if (importStatus < 0)
                        importStatus = -3;
                    else
                        importStatus = -1;

                    if (fe.getMessage() == "Cannot locate JPEG decoder") {
                        viewer.appendToOutputLn("> [" + j + "] Lossless JPEG not supported.");
                        /*
                         * See " +
                         * "http://trac.openmicroscopy.org.uk/omero/wiki/LosslessJPEG for "
                         * + "details on this error.");
                         */
                        JOptionPane.showMessageDialog(viewer,
                                "\nThe importer cannot import the lossless JPEG images used by the file" + "\n"
                                        + importContainer[j].getFile().getAbsolutePath() + "");
                        /*
                         * "
                         * "\n\nThere maybe be a native library available for your operating system"
                         * +
                         * "\nthat will support this format. For details on this error, check:"
                         * +
                         * "\nhttp://trac.openmicroscopy.org.uk/omero/wiki/LosslessJPEG"
                         * );
                         */
                    }
                    updateHistoryWithFailedImport(importKey, j);
                } catch (IOException ioe) {
                    log.error("I/O error while importing image.", ioe);
                    qTable.setProgressUnknown(j);
                    viewer.appendToOutputLn("> [" + j + "] Failure importing.");
                    if (importStatus < 0)
                        importStatus = -3;
                    else
                        importStatus = -1;
                    updateHistoryWithFailedImport(importKey, j);
                } catch (ResourceError e) {
                    log.error("Resource error while importing image.", e);
                    JOptionPane.showMessageDialog(viewer,
                            "Your file import has failed because the server has reported a\n"
                                    + "resource error (and may be out of space).\n\n"
                                    + "Please contact your server administrator or try your import\n"
                                    + "again. Further details about this error can be found under the\n"
                                    + "the debug tab.");
                    qTable.setProgressFailed(j);
                    if (importStatus < 0)
                        importStatus = -3;
                    else
                        importStatus = -2;
                    qTable.cancel = true;
                    qTable.abort = true;
                    qTable.importing = false;
                    updateHistoryWithFailedImport(importKey, j);
                } catch (Throwable error) {
                    log.error("Generic error while importing image.", error);
                    viewer.appendToDebug(ome.formats.importer.util.ErrorHandler.getStackTrace(error));
                    qTable.setProgressFailed(j);
                    viewer.appendToOutputLn("> [" + j + "] Failure importing.");

                    if (importStatus < 0)
                        importStatus = -3;
                    else
                        importStatus = -2;

                    updateHistoryWithFailedImport(importKey, j);
                }
            }
        }

        viewer.getStatusBar().setProgress(false, 0, "");
        viewer.getStatusBar().setStatusIcon("gfx/import_done_16.png", "Import complete.");
        if (importStatus >= 0)
            updateHistoryWithCompleteImport(importKey);

        timestampOut = System.currentTimeMillis();
        timestampDiff = timestampOut - timestampIn;

        // calculate hour/min/sec time for the run
        timeInSeconds = timestampDiff / 1000;
        hours = timeInSeconds / 3600;
        timeInSeconds = timeInSeconds - (hours * 3600);
        minutes = timeInSeconds / 60;
        timeInSeconds = timeInSeconds - (minutes * 60);
        seconds = timeInSeconds;

        viewer.appendToOutputLn("> Total import time: " + hours + " hour(s), " + minutes + " minute(s), " + seconds
                + " second(s).");

        viewer.appendToOutputLn("> Image import completed!");
        notifyObservers(new ImportEvent.IMPORT_QUEUE_DONE());
    }

    /**
     * Add historyTable pending base status row
     * 
     * @return new baseUID
     */
    private int addHistoryPendingImport() {
        int importKey = 0;
        try {
            if (db != null && db.historyEnabled == true) {
                db.addBaseTableRow(library.getExperimenterID(), "pending");
                importKey = db.getLastBaseUid();
                log.debug("New importKey for history db is: " + importKey);
            }
        } catch (Exception e) {
            log.error("addBaseTableRow exception: experimenterID '" + library.getExperimenterID() + "', 'pending'",
                    e);
        }
        return importKey;
    }

    /**
     * Update the historyTable, noting a incomplete/failed import status
     * 
     * @param importKey - 'base' import key for this import session
     * @param index - index of file in this session
     */
    private void updateHistoryWithFailedImport(int importKey, int index) {
        try {
            if (db != null && db.historyEnabled == true) {
                db.updateBaseStatus(importKey, "incomplete");
                viewer.getHistoryTable().updateOutlookBar();
            }
        } catch (Exception e) {
            log.error("updateBaseStatus exception: importKey '" + importKey + "', 'incomplete'", e);
        }

        try {
            if (db != null && db.historyEnabled == true) {
                db.updateItemStatus(importKey, index, "failed");
            }
        } catch (Exception e) {
            log.error("updateItemStatus exception: importKey '" + importKey + "', index '" + index + "', 'failed'",
                    e);
        }
    }

    /**
     * Update the historyTable, noting a 'complete' import status
     * 
     * @param importKey - 'base' import key for this import session
     */
    private void updateHistoryWithCompleteImport(int importKey) {
        try {
            if (db != null && db.historyEnabled == true) {
                db.updateBaseStatus(importKey, "complete");
                viewer.getHistoryTable().updateOutlookBar();
            }
        } catch (Exception e) {
            log.error("updateBaseStatus exception: importKey '" + importKey + "', 'complete'", e);
            e.printStackTrace();
        }
    }

    /**
     * Update the historyTable, noting a 'done' import file status
     * 
     * @param importKey - 'base' import key for this import session
     *  @param index - index of file in this session
     */
    private void updateHistoryWithDoneImport(int importKey, int index) {
        try {
            if (db != null && db.historyEnabled == true)
                db.updateItemStatus(importKey, index, "done");
        } catch (Exception e) {
            log.error("updateItemStatus exception: importKey '" + importKey + "', index '" + index + "', 'done'",
                    e);
            e.printStackTrace();
        }
    }

    /* (non-Javadoc)
     * @see ome.formats.importer.IObservable#addObserver(ome.formats.importer.IObserver)
     */
    public boolean addObserver(IObserver object) {
        return observers.add(object);
    }

    /* (non-Javadoc)
     * @see ome.formats.importer.IObservable#deleteObserver(ome.formats.importer.IObserver)
     */
    public boolean deleteObserver(IObserver object) {
        return observers.remove(object);

    }

    /* (non-Javadoc)
     * @see ome.formats.importer.IObservable#notifyObservers(ome.formats.importer.ImportEvent)
     */
    public void notifyObservers(ImportEvent event) {
        for (IObserver observer : observers) {
            observer.update(this, event);
        }
    }
}