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