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.util.ArrayList;
007import java.util.LinkedHashSet;
008import java.util.List;
009import java.util.concurrent.Future;
010
011import javax.swing.JOptionPane;
012import javax.swing.SwingUtilities;
013
014import org.openstreetmap.josm.Main;
015import org.openstreetmap.josm.gui.ExceptionDialogUtil;
016import org.openstreetmap.josm.tools.ExceptionUtil;
017
018public class PostDownloadHandler implements Runnable {
019    private DownloadTask task;
020    private List<Future<?>> futures;
021
022    /**
023     * constructor
024     * @param task the asynchronous download task
025     * @param future the future on which the completion of the download task can be synchronized
026     */
027    public PostDownloadHandler(DownloadTask task, Future<?> future) {
028        this.task = task;
029        this.futures = new ArrayList<Future<?>>();
030        if (future != null) {
031            this.futures.add(future);
032        }
033    }
034
035    /**
036     * constructor
037     * @param task the asynchronous download task
038     * @param futures the futures on which the completion of the download task can be synchronized
039     */
040    public PostDownloadHandler(DownloadTask task, Future<?> ... futures) {
041        this.task = task;
042        this.futures = new ArrayList<Future<?>>();
043        if (futures == null) return;
044        for (Future<?> future: futures) {
045            this.futures.add(future);
046        }
047    }
048
049    /**
050     * constructor
051     * @param task the asynchronous download task
052     * @param futures the futures on which the completion of the download task can be synchronized
053     */
054    public PostDownloadHandler(DownloadTask task, List<Future<?>> futures) {
055        this.task = task;
056        this.futures = new ArrayList<Future<?>>();
057        if (futures == null) return;
058        this.futures.addAll(futures);
059    }
060
061    @Override
062    public void run() {
063        // wait for all downloads task to finish (by waiting for the futures
064        // to return a value)
065        //
066        for (Future<?> future: futures) {
067            try {
068                future.get();
069            } catch(Exception e) {
070                e.printStackTrace();
071                return;
072            }
073        }
074
075        // make sure errors are reported only once
076        //
077        LinkedHashSet<Object> errors = new LinkedHashSet<Object>();
078        errors.addAll(task.getErrorObjects());
079        if (errors.isEmpty())
080            return;
081
082        // just one error object?
083        //
084        if (errors.size() == 1) {
085            final Object error = errors.iterator().next();
086            SwingUtilities.invokeLater(new Runnable() {
087                @Override
088                public void run() {
089                    if (error instanceof Exception) {
090                        ExceptionDialogUtil.explainException((Exception)error);
091                    } else {
092                        JOptionPane.showMessageDialog(
093                                Main.parent,
094                                error.toString(),
095                                tr("Error during download"),
096                                JOptionPane.ERROR_MESSAGE);
097                    }
098                }
099            });
100            return;
101        }
102
103        // multiple error object? prepare a HTML list
104        //
105        if (!errors.isEmpty()) {
106            final StringBuffer sb = new StringBuffer();
107            for (Object error:errors) {
108                if (error instanceof String) {
109                    sb.append("<li>").append(error).append("</li>").append("<br>");
110                } else if (error instanceof Exception) {
111                    sb.append("<li>").append(ExceptionUtil.explainException((Exception)error)).append("</li>").append("<br>");
112                }
113            }
114            sb.insert(0, "<html><ul>");
115            sb.append("</ul></html>");
116
117            SwingUtilities.invokeLater(new Runnable() {
118                @Override
119                public void run() {
120                    JOptionPane.showMessageDialog(
121                            Main.parent,
122                            sb.toString(),
123                            tr("Errors during download"),
124                            JOptionPane.ERROR_MESSAGE);
125                }
126            });
127            return;
128        }
129    }
130}