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.LinkedHashSet; 010import java.util.Set; 011 012import org.openstreetmap.josm.Main; 013import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask; 014import org.openstreetmap.josm.actions.downloadtasks.DownloadTask; 015import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault; 016import org.openstreetmap.josm.tools.Utils; 017 018/** 019 * Handler for import request 020 */ 021public class ImportHandler extends RequestHandler.RawURLParseRequestHandler { 022 023 /** 024 * The remote control command name used to import data. 025 */ 026 public static final String command = "import"; 027 028 private URL url; 029 private Collection<DownloadTask> suitableDownloadTasks; 030 031 @Override 032 protected void handleRequest() throws RequestHandlerErrorException { 033 try { 034 if (suitableDownloadTasks.isEmpty()) { 035 // It should maybe be better to reject the request in that case ? 036 // For compatibility reasons with older instances of JOSM, arbitrary choice of DownloadOsmTask 037 // As of 2015-04, Overpass Turbo requires this branch of code ... 038 Main.debug("Remote control, /import: defaulting to DownloadOsmTask"); 039 new DownloadOsmTask().loadUrl(isLoadInNewLayer(), url.toExternalForm(), null); 040 } else if (Main.pref.getBoolean("remotecontrol.import.interactive", true)) { 041 // OpenLocationAction queries the user if more than one task is suitable 042 Main.main.menu.openLocation.openUrl(isLoadInNewLayer(), url.toExternalForm()); 043 } else { 044 // Otherwise perform all tasks 045 for (DownloadTask task : suitableDownloadTasks) { 046 task.loadUrl(isLoadInNewLayer(), url.toExternalForm(), null); 047 } 048 } 049 } catch (Exception ex) { 050 Main.warn("RemoteControl: Error parsing import remote control request:"); 051 Main.error(ex); 052 throw new RequestHandlerErrorException(ex); 053 } 054 } 055 056 @Override 057 public String[] getMandatoryParams() { 058 return new String[]{"url"}; 059 } 060 061 @Override 062 public String[] getOptionalParams() { 063 return new String[] {"new_layer"}; 064 } 065 066 @Override 067 public String getUsage() { 068 return "downloads the specified OSM file and adds it to the current data set"; 069 } 070 071 @Override 072 public String[] getUsageExamples() { 073 return new String[] {"/import?url="+Main.getJOSMWebsite()+"/browser/josm/trunk/data_nodist/direction-arrows.osm"}; 074 } 075 076 @Override 077 public String getPermissionMessage() { 078 // URL can be any suitable URL giving back OSM data, including OSM API calls, even if calls to the main API 079 // should rather be passed to LoadAndZoomHandler or LoadObjectHandler. 080 // Other API instances will however use the import handler to force JOSM to make requests to this API instance. 081 // (Example with OSM-FR website that makes calls to the OSM-FR API) 082 // For user-friendliness, let's try to decode these OSM API calls to give a better confirmation message. 083 Set<String> taskMessages = new LinkedHashSet<>(); 084 if (suitableDownloadTasks != null && !suitableDownloadTasks.isEmpty()) { 085 for (DownloadTask task : suitableDownloadTasks) { 086 taskMessages.add(Utils.firstNonNull(task.getConfirmationMessage(url), url.toString())); 087 } 088 } 089 return tr("Remote Control has been asked to import data from the following URL:") 090 + Utils.joinAsHtmlUnorderedList(taskMessages); 091 } 092 093 @Override 094 public PermissionPrefWithDefault getPermissionPref() { 095 return PermissionPrefWithDefault.IMPORT_DATA; 096 } 097 098 @Override 099 protected void validateRequest() throws RequestHandlerBadRequestException { 100 String urlString = args.get("url"); 101 if (Main.pref.getBoolean("remotecontrol.importhandler.fix_url_query", true)) { 102 urlString = Utils.fixURLQuery(urlString); 103 } 104 try { 105 // Ensure the URL is valid 106 url = new URL(urlString); 107 } catch (MalformedURLException e) { 108 throw new RequestHandlerBadRequestException("MalformedURLException: "+e.getMessage(), e); 109 } 110 // Find download tasks for the given URL 111 suitableDownloadTasks = Main.main.menu.openLocation.findDownloadTasks(urlString, true); 112 } 113}