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