001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.actions.downloadtasks;
003
004 import static org.openstreetmap.josm.tools.I18n.tr;
005
006 import java.util.ArrayList;
007 import java.util.LinkedHashSet;
008 import java.util.List;
009 import java.util.concurrent.Future;
010
011 import javax.swing.JOptionPane;
012 import javax.swing.SwingUtilities;
013
014 import org.openstreetmap.josm.Main;
015 import org.openstreetmap.josm.gui.ExceptionDialogUtil;
016 import org.openstreetmap.josm.tools.ExceptionUtil;
017
018 public 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 public void run() {
062 // wait for all downloads task to finish (by waiting for the futures
063 // to return a value)
064 //
065 for (Future<?> future: futures) {
066 try {
067 future.get();
068 } catch(Exception e) {
069 e.printStackTrace();
070 return;
071 }
072 }
073
074 // make sure errors are reported only once
075 //
076 LinkedHashSet<Object> errors = new LinkedHashSet<Object>();
077 errors.addAll(task.getErrorObjects());
078 if (errors.isEmpty())
079 return;
080
081 // just one error object?
082 //
083 if (errors.size() == 1) {
084 final Object error = errors.iterator().next();
085 SwingUtilities.invokeLater(new Runnable() {
086 @Override
087 public void run() {
088 if (error instanceof Exception) {
089 ExceptionDialogUtil.explainException((Exception)error);
090 } else {
091 JOptionPane.showMessageDialog(
092 Main.parent,
093 error.toString(),
094 tr("Error during download"),
095 JOptionPane.ERROR_MESSAGE);
096 }
097 }
098 });
099 return;
100 }
101
102 // multiple error object? prepare a HTML list
103 //
104 if (!errors.isEmpty()) {
105 final StringBuffer sb = new StringBuffer();
106 for (Object error:errors) {
107 if (error instanceof String) {
108 sb.append("<li>").append(error).append("</li>").append("<br>");
109 } else if (error instanceof Exception) {
110 sb.append("<li>").append(ExceptionUtil.explainException((Exception)error)).append("</li>").append("<br>");
111 }
112 }
113 sb.insert(0, "<html><ul>");
114 sb.append("</ul></html>");
115
116 SwingUtilities.invokeLater(new Runnable() {
117 @Override
118 public void run() {
119 JOptionPane.showMessageDialog(
120 Main.parent,
121 sb.toString(),
122 tr("Errors during download"),
123 JOptionPane.ERROR_MESSAGE);
124 }
125 });
126 return;
127 }
128 }
129 }