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(new Runnable() {
061                    @Override
062                    public void run() {
063                        if (error instanceof Exception) {
064                            ExceptionDialogUtil.explainException((Exception) error);
065                        } else if (tr("No data found in this area.").equals(error)) {
066                            new Notification(error.toString()).setIcon(JOptionPane.WARNING_MESSAGE).show();
067                        } else {
068                            JOptionPane.showMessageDialog(
069                                    Main.parent,
070                                    error.toString(),
071                                    tr("Error during download"),
072                                    JOptionPane.ERROR_MESSAGE);
073                        }
074                    }
075                });
076            }
077            return;
078        }
079
080        // multiple error object? prepare a HTML list
081        //
082        if (!errors.isEmpty()) {
083            final Collection<String> items = new ArrayList<>();
084            for (Object error : errors) {
085                if (error instanceof String) {
086                    items.add((String) error);
087                } else if (error instanceof Exception) {
088                    items.add(ExceptionUtil.explainException((Exception) error));
089                }
090            }
091
092            if (!GraphicsEnvironment.isHeadless()) {
093                SwingUtilities.invokeLater(new Runnable() {
094                    @Override
095                    public void run() {
096                        JOptionPane.showMessageDialog(
097                                Main.parent,
098                                "<html>"+Utils.joinAsHtmlUnorderedList(items)+"</html>",
099                                tr("Errors during download"),
100                                JOptionPane.ERROR_MESSAGE);
101                    }
102                });
103            }
104            return;
105        }
106    }
107}