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 LoadAndZoomHandler.parseChangesetTags(args); 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", "changeset_tags"}; 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 Config.getUrls().getJOSMWebsite()+"/browser/josm/trunk/nodist/data/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 (!Utils.isEmpty(suitableDownloadTasks)) { 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}