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