001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions.downloadtasks;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.GraphicsEnvironment;
007import java.util.ArrayList;
008import java.util.Collection;
009import java.util.LinkedHashSet;
010import java.util.Set;
011import java.util.concurrent.CancellationException;
012import java.util.concurrent.ExecutionException;
013import java.util.concurrent.Future;
014
015import javax.swing.JOptionPane;
016import javax.swing.SwingUtilities;
017
018import org.openstreetmap.josm.Main;
019import org.openstreetmap.josm.gui.ExceptionDialogUtil;
020import org.openstreetmap.josm.gui.Notification;
021import org.openstreetmap.josm.tools.ExceptionUtil;
022import org.openstreetmap.josm.tools.Utils;
023
024public class PostDownloadHandler implements Runnable {
025    private final DownloadTask task;
026    private final Future<?> future;
027
028    /**
029     * constructor
030     * @param task the asynchronous download task
031     * @param future the future on which the completion of the download task can be synchronized
032     */
033    public PostDownloadHandler(DownloadTask task, Future<?> future) {
034        this.task = task;
035        this.future = future;
036    }
037
038    @Override
039    public void run() {
040        // wait for downloads task to finish (by waiting for the future to return a value)
041        //
042        try {
043            future.get();
044        } catch (InterruptedException | ExecutionException | CancellationException e) {
045            Main.error(e);
046            return;
047        }
048
049        // make sure errors are reported only once
050        //
051        Set<Object> errors = new LinkedHashSet<>(task.getErrorObjects());
052        if (errors.isEmpty())
053            return;
054
055        // just one error object?
056        //
057        if (errors.size() == 1) {
058            final Object error = errors.iterator().next();
059            if (!GraphicsEnvironment.isHeadless()) {
060                SwingUtilities.invokeLater(() -> {
061                    if (error instanceof Exception) {
062                        ExceptionDialogUtil.explainException((Exception) error);
063                    } else if (tr("No data found in this area.").equals(error)) {
064                        new Notification(error.toString()).setIcon(JOptionPane.WARNING_MESSAGE).show();
065                    } else {
066                        JOptionPane.showMessageDialog(
067                                Main.parent,
068                                error.toString(),
069                                tr("Error during download"),
070                                JOptionPane.ERROR_MESSAGE);
071                    }
072                });
073            }
074            return;
075        }
076
077        // multiple error object? prepare a HTML list
078        //
079        if (!errors.isEmpty()) {
080            final Collection<String> items = new ArrayList<>();
081            for (Object error : errors) {
082                if (error instanceof String) {
083                    items.add((String) error);
084                } else if (error instanceof Exception) {
085                    items.add(ExceptionUtil.explainException((Exception) error));
086                }
087            }
088
089            if (!GraphicsEnvironment.isHeadless()) {
090                SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(
091                        Main.parent,
092                        "<html>"+Utils.joinAsHtmlUnorderedList(items)+"</html>",
093                        tr("Errors during download"),
094                        JOptionPane.ERROR_MESSAGE));
095            }
096            return;
097        }
098    }
099}