001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions.downloadtasks; 003 004import java.net.URL; 005import java.util.List; 006import java.util.Objects; 007import java.util.concurrent.Future; 008import java.util.stream.Collectors; 009 010import org.openstreetmap.josm.data.Bounds; 011import org.openstreetmap.josm.gui.progress.NullProgressMonitor; 012import org.openstreetmap.josm.gui.progress.ProgressMonitor; 013import org.openstreetmap.josm.tools.ExceptionUtil; 014 015/** 016 * Interface defining a general download task used to download geographic data (OSM data, GPX tracks, etc.) for a given URL or geographic area. 017 */ 018public interface DownloadTask { 019 020 /** 021 * Asynchronously launches the download task for a given bounding box. 022 * 023 * Set <code>progressMonitor</code> to null, if the task should create, open, and close a progress monitor. 024 * Set progressMonitor to {@link NullProgressMonitor#INSTANCE} if progress information is to 025 * be discarded. 026 * 027 * You can wait for the asynchronous download task to finish by synchronizing on the returned 028 * {@link Future}, but make sure not to freeze up JOSM. Example: 029 * <pre> 030 * Future<?> future = task.download(...); 031 * // DON'T run this on the Swing EDT or JOSM will freeze 032 * future.get(); // waits for the dowload task to complete 033 * </pre> 034 * 035 * The following example uses a pattern which is better suited if a task is launched from 036 * the Swing EDT: 037 * <pre> 038 * final Future<?> future = task.download(...); 039 * Runnable runAfterTask = new Runnable() { 040 * public void run() { 041 * // this is not strictly necessary because of the type of executor service 042 * // Main.worker is initialized with, but it doesn't harm either 043 * // 044 * future.get(); // wait for the download task to complete 045 * doSomethingAfterTheTaskCompleted(); 046 * } 047 * } 048 * MainApplication.worker.submit(runAfterTask); 049 * </pre> 050 * 051 * @param settings download settings 052 * 053 * @param downloadArea the area to download 054 * @param progressMonitor the progressMonitor 055 * @return the future representing the asynchronous task 056 * @since 13927 057 */ 058 Future<?> download(DownloadParams settings, Bounds downloadArea, ProgressMonitor progressMonitor); 059 060 /** 061 * Asynchronously launches the download task for a given bounding URL. 062 * 063 * Set progressMonitor to null, if the task should create, open, and close a progress monitor. 064 * Set progressMonitor to {@link NullProgressMonitor#INSTANCE} if progress information is to 065 * be discarded. 066 067 * @param settings download settings 068 * @param url the url to download from 069 * @param progressMonitor the progressMonitor 070 * @return the future representing the asynchronous task 071 * 072 * @see #download(DownloadParams, Bounds, ProgressMonitor) 073 * @since 13927 074 */ 075 Future<?> loadUrl(DownloadParams settings, String url, ProgressMonitor progressMonitor); 076 077 /** 078 * Returns true if the task is able to open the given URL, false otherwise. 079 * @param url the url to download from 080 * @param isRemotecontrol True if download request comes from remotecontrol. 081 * @return True if the task is able to open the given URL, false otherwise. 082 * Return false, if the request comes from remotecontrol, but the task is not 083 * safe for remotecontrol. 084 * A task is not safe for remotecontrol if it is possible to prepare a file 085 * for download which does something unintended, e.g. gain access to the 086 * local file system. 087 */ 088 boolean acceptsUrl(String url, boolean isRemotecontrol); 089 090 /** 091 * Returns a short HTML documentation string, describing acceptable URLs. 092 * @return The HTML documentation 093 * @since 6031 094 */ 095 String acceptsDocumentationSummary(); 096 097 /** 098 * Returns human-readable description of the task 099 * @return The task description 100 * @since 6031 101 */ 102 String getTitle(); 103 104 /** 105 * Returns regular expressions that match the URLs 106 * @return The array of accepted URL patterns 107 * @since 6031 108 */ 109 String[] getPatterns(); 110 111 /** 112 * Replies the error objects of the task. Empty list, if no error messages are available. 113 * 114 * Error objects are either {@link String}s with error messages or {@link Exception}s. 115 * 116 * @return the list of error objects 117 */ 118 List<Object> getErrorObjects(); 119 120 /** 121 * Replies the error messages of the task. Empty list, if no error messages are available. 122 * 123 * @return the list of error messages 124 * @since 17330 125 */ 126 default List<String> getErrorMessages() { 127 return getErrorObjects().stream().map(o -> { 128 if (o instanceof String) { 129 return (String) o; 130 } else if (o instanceof Exception) { 131 return ExceptionUtil.explainException((Exception) o).replace("<html>", "").replace("</html>", ""); 132 } else { 133 return (String) null; 134 } 135 }).filter(Objects::nonNull).collect(Collectors.toList()); 136 } 137 138 /** 139 * Cancels the asynchronous download task. 140 * 141 */ 142 void cancel(); 143 144 /** 145 * Replies the HTML-formatted confirmation message to be shown to user when the given URL needs to be confirmed before loading. 146 * @param url The URL to be confirmed 147 * @return The HTML-formatted confirmation message to be shown to user 148 * @since 5691 149 */ 150 String getConfirmationMessage(URL url); 151 152 /** 153 * Sets whether the map view will zoom to download area after download 154 * @param zoomAfterDownload if true, the map view will zoom to download area after download 155 * @since 13261 156 */ 157 void setZoomAfterDownload(boolean zoomAfterDownload); 158}