001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions.downloadtasks; 003 004import java.util.ArrayList; 005import java.util.List; 006 007import org.openstreetmap.josm.data.ProjectionBounds; 008import org.openstreetmap.josm.io.XmlWriter; 009 010/** 011 * Common abstract implementation of other download tasks. 012 * @param <T> The downloaded data type 013 * @since 2322 014 */ 015public abstract class AbstractDownloadTask<T> implements DownloadTask { 016 private final List<Object> errorMessages; 017 private boolean canceled; 018 private boolean failed; 019 protected T downloadedData; 020 protected boolean zoomAfterDownload = true; 021 022 /** 023 * Constructs a new {@code AbstractDownloadTask}. 024 */ 025 public AbstractDownloadTask() { 026 errorMessages = new ArrayList<>(); 027 } 028 029 /** 030 * Determines if the download task has been canceled. 031 * @return {@code true} if the download task has been canceled 032 */ 033 public boolean isCanceled() { 034 return canceled; 035 } 036 037 /** 038 * Marks this download task as canceled. 039 * @param canceled {@code true} to mark this download task as canceled 040 */ 041 public void setCanceled(boolean canceled) { 042 this.canceled = canceled; 043 } 044 045 /** 046 * Determines if the download task has failed. 047 * @return {@code true} if the download task has failed 048 */ 049 public boolean isFailed() { 050 return failed; 051 } 052 053 /** 054 * Marks this download task as failed. 055 * @param failed {@code true} to mark this download task as failed 056 */ 057 public void setFailed(boolean failed) { 058 this.failed = failed; 059 } 060 061 protected final void rememberErrorMessage(String message) { 062 errorMessages.add(message); 063 } 064 065 protected final void rememberException(Exception exception) { 066 errorMessages.add(exception); 067 } 068 069 protected final void rememberDownloadedData(T data) { 070 this.downloadedData = data; 071 } 072 073 /** 074 * Replies the downloaded data. 075 * @return The downloaded data. 076 */ 077 public final T getDownloadedData() { 078 return downloadedData; 079 } 080 081 @Override 082 public final void setZoomAfterDownload(boolean zoomAfterDownload) { 083 this.zoomAfterDownload = zoomAfterDownload; 084 } 085 086 @Override 087 public List<Object> getErrorObjects() { 088 return errorMessages; 089 } 090 091 @Override 092 public String acceptsDocumentationSummary() { 093 StringBuilder buff = new StringBuilder(128) 094 .append("<tr><td>") 095 .append(getTitle()) 096 .append(":</td><td>"); 097 String[] patterns = getPatterns(); 098 if (patterns.length > 0) { 099 buff.append("<ul>"); 100 for (String pattern: patterns) { 101 buff.append("<li>") 102 .append(XmlWriter.encode(pattern)) 103 .append("</li>"); 104 } 105 buff.append("</ul>"); 106 } 107 buff.append("</td></tr>"); 108 return buff.toString(); 109 } 110 111 /** 112 * Determines if the given URL is accepted by {@link #getPatterns}. 113 * Can be overridden for more complex checking logic. 114 * @param url URL to donwload 115 * @return {@code true} if this URL is accepted 116 */ 117 public boolean acceptsUrl(String url) { 118 if (url == null) 119 return false; 120 for (String p: getPatterns()) { 121 if (url.matches(p)) { 122 return true; 123 } 124 } 125 return false; 126 } 127 128 /** 129 * Check / decide if the task is safe for remotecontrol. 130 * 131 * Keep in mind that a potential attacker has full control over the content 132 * of the file that will be downloaded. 133 * If it is possible to run arbitrary code or write to the local file 134 * system, then the task is (obviously) not save for remote execution. 135 * 136 * The default value is false = unsafe. Override in a subclass to 137 * allow running the task via remotecontol. 138 * 139 * @return true if it is safe to download and open any file of the 140 * corresponding format, false otherwise 141 */ 142 public boolean isSafeForRemotecontrolRequests() { 143 return false; 144 } 145 146 @Override 147 public boolean acceptsUrl(String url, boolean isRemotecontrol) { 148 if (isRemotecontrol && !isSafeForRemotecontrolRequests()) 149 return false; 150 return acceptsUrl(url); 151 } 152 153 // Default name to keep old plugins compatible 154 @Override 155 public String getTitle() { 156 return getClass().getName(); 157 } 158 159 @Override 160 public String toString() { 161 return this.getTitle(); 162 } 163 164 // Default pattern to keep old plugins compatible 165 @Override 166 public String[] getPatterns() { 167 return new String[]{}; 168 } 169 170 /** 171 * Returns the projection bounds of downloaded data. 172 * @return the projection bounds of downloaded data or {@code null} 173 * @since 11774 174 */ 175 public ProjectionBounds getDownloadProjectionBounds() { 176 return null; 177 } 178}