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 }