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