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