001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io.remotecontrol.handler; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.net.MalformedURLException; 007import java.net.URL; 008import java.util.Collection; 009import java.util.HashMap; 010 011import org.openstreetmap.josm.Main; 012import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask; 013import org.openstreetmap.josm.actions.downloadtasks.DownloadTask; 014import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 015import org.openstreetmap.josm.tools.Utils; 016 017/** 018 * Handler for import request 019 */ 020public class ImportHandler extends RequestHandler { 021 022 /** 023 * The remote control command name used to import data. 024 */ 025 public static final String command = "import"; 026 027 private URL url; 028 private Collection<DownloadTask> suitableDownloadTasks; 029 030 @Override 031 protected void handleRequest() throws RequestHandlerErrorException { 032 try { 033 if (suitableDownloadTasks != null && !suitableDownloadTasks.isEmpty()) { 034 // TODO: handle multiple suitable download tasks ? 035 suitableDownloadTasks.iterator().next().loadUrl(isLoadInNewLayer(), url.toExternalForm(), null); 036 } 037 } catch (Exception ex) { 038 Main.warn("RemoteControl: Error parsing import remote control request:"); 039 Main.error(ex); 040 throw new RequestHandlerErrorException(ex); 041 } 042 } 043 044 @Override 045 public String[] getMandatoryParams() { 046 return new String[]{"url"}; 047 } 048 049 @Override 050 public String[] getOptionalParams() { 051 return new String[] {"new_layer"}; 052 } 053 054 @Override 055 public String getUsage() { 056 return "downloads the specified OSM file and adds it to the current data set"; 057 } 058 059 @Override 060 public String[] getUsageExamples() { 061 return new String[] { "/import?url="+Main.getJOSMWebsite()+"/browser/josm/trunk/data_nodist/direction-arrows.osm" }; 062 } 063 064 @Override 065 public String getPermissionMessage() { 066 // URL can be any suitable URL giving back OSM data, including OSM API calls, even if calls to the main API 067 // should rather be passed to LoadAndZoomHandler or LoadObjectHandler. 068 // Other API instances will however use the import handler to force JOSM to make requests to this API instance. 069 // (Example with OSM-FR website that makes calls to the OSM-FR API) 070 // For user-friendliness, let's try to decode these OSM API calls to give a better confirmation message. 071 String taskMessage = null; 072 if (suitableDownloadTasks != null && !suitableDownloadTasks.isEmpty()) { 073 // TODO: handle multiple suitable download tasks ? 074 taskMessage = suitableDownloadTasks.iterator().next().getConfirmationMessage(url); 075 } 076 return tr("Remote Control has been asked to import data from the following URL:") 077 + "<br>" + (taskMessage == null ? url.toString() : taskMessage); 078 } 079 080 @Override 081 public PermissionPrefWithDefault getPermissionPref() { 082 return PermissionPrefWithDefault.IMPORT_DATA; 083 } 084 085 @Override 086 protected void parseArgs() { 087 HashMap<String, String> args = new HashMap<>(); 088 if (request.indexOf('?') != -1) { 089 String query = request.substring(request.indexOf('?') + 1); 090 if (query.indexOf("url=") == 0) { 091 args.put("url", decodeParam(query.substring(4))); 092 } else { 093 int urlIdx = query.indexOf("&url="); 094 if (urlIdx != -1) { 095 args.put("url", decodeParam(query.substring(urlIdx + 5))); 096 query = query.substring(0, urlIdx); 097 } else { 098 if (query.indexOf('#') != -1) { 099 query = query.substring(0, query.indexOf('#')); 100 } 101 } 102 String[] params = query.split("&", -1); 103 for (String param : params) { 104 int eq = param.indexOf('='); 105 if (eq != -1) { 106 args.put(param.substring(0, eq), param.substring(eq + 1)); 107 } 108 } 109 } 110 } 111 this.args = args; 112 } 113 114 @Override 115 protected void validateRequest() throws RequestHandlerBadRequestException { 116 String urlString = args.get("url"); 117 if (Main.pref.getBoolean("remotecontrol.importhandler.fix_url_query", true)) { 118 urlString = Utils.fixURLQuery(urlString); 119 } 120 try { 121 // Ensure the URL is valid 122 url = new URL(urlString); 123 } catch (MalformedURLException e) { 124 throw new RequestHandlerBadRequestException("MalformedURLException: "+e.getMessage(), e); 125 } 126 // Find download tasks for the given URL 127 suitableDownloadTasks = Main.main.menu.openLocation.findDownloadTasks(urlString); 128 if (suitableDownloadTasks.isEmpty()) { 129 // It should maybe be better to reject the request in that case ? 130 // For compatibility reasons with older instances of JOSM, arbitrary choice of DownloadOsmTask 131 suitableDownloadTasks.add(new DownloadOsmTask()); 132 } 133 } 134}