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}