Changeset 5691 in josm for trunk


Ignore:
Timestamp:
2013-01-29T21:40:59+01:00 (12 years ago)
Author:
Don-vip
Message:

see #8148 - Remote control: URL validation in import handler + find suitable download tasks + dynamic width of confirmation dialog box

Location:
trunk/src/org/openstreetmap/josm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java

    r5361 r5691  
    1010import java.awt.event.KeyEvent;
    1111import java.util.ArrayList;
     12import java.util.Collection;
    1213import java.util.Collections;
    1314import java.util.LinkedList;
     
    120121        openUrl(layer.isSelected(), uploadAddresses.getText());
    121122    }
    122 
     123   
    123124    /**
    124      * Open the given URL.
     125     * Replies the list of download tasks accepting the given url.
     126     * @param url The URL to open
     127     * @return The list of download tasks accepting the given url.
     128     * @since 5691
    125129     */
    126     public void openUrl(boolean new_layer, final String url) {
    127         PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download Data"));
    128         DownloadTask task = null;
    129         Future<?> future = null;
    130         for (int i = 0; future == null && i < downloadTasks.size(); i++) {
     130    public Collection<DownloadTask> findDownloadTasks(final String url) {
     131        List<DownloadTask> result = new ArrayList<DownloadTask>();
     132        for (int i = 0; i < downloadTasks.size(); i++) {
    131133            Class<? extends DownloadTask> taskClass = downloadTasks.get(i);
    132134            if (taskClass != null) {
    133135                try {
    134                     task = taskClass.getConstructor().newInstance();
     136                    DownloadTask task = taskClass.getConstructor().newInstance();
    135137                    if (task.acceptsUrl(url)) {
    136                         future = task.loadUrl(new_layer, url, monitor);
     138                        result.add(task);
    137139                    }
    138140                } catch (Exception e) {
     
    140142                }
    141143            }
     144        }
     145        return result;
     146    }
     147
     148    /**
     149     * Open the given URL.
     150     * @param new_layer true if the URL needs to be opened in a new layer, false otherwise
     151     * @param url The URL to open
     152     */
     153    public void openUrl(boolean new_layer, final String url) {
     154        PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download Data"));
     155        Collection<DownloadTask> tasks = findDownloadTasks(url);
     156        DownloadTask task = null;
     157        Future<?> future = null;
     158        if (!tasks.isEmpty()) {
     159            // TODO: handle multiple suitable tasks ?
     160            future = tasks.iterator().next().loadUrl(new_layer, url, monitor);
    142161        }
    143162        if (future != null) {
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java

    r5501 r5691  
    55
    66import java.io.IOException;
     7import java.net.URL;
    78import java.util.concurrent.Future;
    89import java.util.regex.Matcher;
     
    178179        }
    179180    }
     181
     182    @Override
     183    public String getConfirmationMessage(URL url) {
     184        // TODO
     185        return null;
     186    }
    180187}
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java

    r5663 r5691  
    66import java.awt.geom.Area;
    77import java.io.IOException;
     8import java.net.URL;
    89import java.util.ArrayList;
    910import java.util.Collection;
     
    1718
    1819import javax.swing.JOptionPane;
     20
    1921import org.openstreetmap.josm.Main;
    2022import org.openstreetmap.josm.data.Bounds;
     
    4547 */
    4648public class DownloadOsmTask extends AbstractDownloadTask {
     49   
     50    private static final String PATTERN_OSM_API_URL           = "http://.*/api/0.6/(map|nodes?|ways?|relations?|\\*).*";
     51    private static final String PATTERN_OVERPASS_API_URL      = "http://.*/interpreter\\?data=.*";
     52    private static final String PATTERN_OVERPASS_API_XAPI_URL = "http://.*/xapi\\?.*\\[@meta\\].*";
     53    private static final String PATTERN_EXTERNAL_OSM_FILE     = "https?://.*/.*\\.osm";
     54   
    4755    protected Bounds currentBounds;
    4856    protected DataSet downloadedData;
     
    145153    public boolean acceptsUrl(String url) {
    146154        return url != null && (
    147                 url.matches("http://.*/api/0.6/(map|nodes?|ways?|relations?|\\*).*")// OSM API 0.6 and XAPI
    148              || url.matches("http://.*/interpreter\\?data=.*")                      // Overpass API
    149              || url.matches("http://.*/xapi\\?.*\\[@meta\\].*")                    // Overpass API XAPI compatibility layer
    150              || url.matches("https?://.*/.*\\.osm")                                 // Remote .osm files
     155                url.matches(PATTERN_OSM_API_URL)           // OSM API 0.6 and XAPI
     156             || url.matches(PATTERN_OVERPASS_API_URL)      // Overpass API
     157             || url.matches(PATTERN_OVERPASS_API_XAPI_URL) // Overpass API XAPI compatibility layer
     158             || url.matches(PATTERN_EXTERNAL_OSM_FILE)     // Remote .osm files
    151159                );
    152160    }
     
    352360        }
    353361    }
     362
     363    @Override
     364    public String getConfirmationMessage(URL url) {
     365        if (url != null) {
     366            String urlString = url.toExternalForm();
     367            if (urlString.matches(PATTERN_OSM_API_URL)) {
     368                // TODO: proper i18n after stabilization
     369                String message = "<ul><li>"+tr("OSM Server URL:") + " " + url.getHost() + "</li><li>" +
     370                        tr("Command")+": "+url.getPath()+"</li>";
     371                if (url.getQuery() != null) {
     372                    message += "<li>" + tr("Request details: {0}", url.getQuery().replaceAll(",\\s*", ", ")) + "</li>";
     373                }
     374                message += "</ul>";
     375                return message;
     376            }
     377            // TODO: other APIs
     378        }
     379        return null;
     380    }
    354381}
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java

    r5402 r5691  
    22package org.openstreetmap.josm.actions.downloadtasks;
    33
     4import java.net.URL;
    45import java.util.List;
    56import java.util.concurrent.Future;
     
    9293     */
    9394    public void cancel();
     95   
     96    /**
     97     * Replies the HTML-formatted confirmation message to be shown to user when the given URL needs to be confirmed before loading.
     98     * @param url The URL to be confirmed
     99     * @return The HTML-formatted confirmation message to be shown to user
     100     * @since
     101     */
     102    public String getConfirmationMessage(URL url);
    94103}
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java

    r5680 r5691  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.net.MalformedURLException;
     7import java.net.URL;
     8import java.util.Collection;
    69import java.util.HashMap;
    710
     11import org.openstreetmap.josm.Main;
    812import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
    913import org.openstreetmap.josm.actions.downloadtasks.DownloadTask;
     
    1923     */
    2024    public static final String command = "import";
     25   
     26    private URL url;
     27    private Collection<DownloadTask> suitableDownloadTasks;
    2128
    2229    @Override
    2330    protected void handleRequest() throws RequestHandlerErrorException {
    2431        try {
    25             DownloadTask osmTask = new DownloadOsmTask();
    26             osmTask.loadUrl(false, args.get("url"), null);
     32            if (suitableDownloadTasks != null && !suitableDownloadTasks.isEmpty()) {
     33                // TODO: add new_layer parameter
     34                // TODO: handle multiple suitable download tasks ?
     35                suitableDownloadTasks.iterator().next().loadUrl(false, url.toExternalForm(), null);
     36            }
    2737        } catch (Exception ex) {
    2838            System.out.println("RemoteControl: Error parsing import remote control request:");
     
    3949    @Override
    4050    public String getPermissionMessage() {
     51        // URL can be any suitable URL giving back OSM data, including OSM API calls, even if calls to the main API
     52        // should rather be passed to LoadAndZoomHandler or LoadObjectHandler.
     53        // Other API instances will however use the import handler to force JOSM to make requests to this API instance.
     54        // (Example with OSM-FR website that makes calls to the OSM-FR API)
     55        // For user-friendliness, let's try to decode these OSM API calls to give a better confirmation message.
     56        String taskMessage = null;
     57        if (suitableDownloadTasks != null && !suitableDownloadTasks.isEmpty()) {
     58            // TODO: handle multiple suitable download tasks ?
     59            taskMessage = suitableDownloadTasks.iterator().next().getConfirmationMessage(url);
     60        }
    4161        return tr("Remote Control has been asked to import data from the following URL:")
    42                 + "<br>" + args.get("url");
     62                + "<br>" + (taskMessage == null ? url.toString() : taskMessage);
    4363    }
    4464
     
    80100    @Override
    81101    protected void validateRequest() throws RequestHandlerBadRequestException {
    82         // Nothing to do
     102        final String urlString = args.get("url");
     103        try {
     104            // Ensure the URL is valid
     105            url = new URL(urlString);
     106        } catch (MalformedURLException e) {
     107            throw new RequestHandlerBadRequestException("MalformedURLException: "+e.getMessage());
     108        }
     109        // Find download tasks for the given URL
     110        suitableDownloadTasks = Main.main.menu.openLocation.findDownloadTasks(urlString);
     111        if (suitableDownloadTasks.isEmpty()) {
     112            // It should maybe be better to reject the request in that case ?
     113            // For compatibility reasons with older instances of JOSM, arbitrary choice of DownloadOsmTask
     114            suitableDownloadTasks.add(new DownloadOsmTask());
     115        }
    83116    }
    84117}
  • trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java

    r5680 r5691  
    1111import java.util.List;
    1212
     13import javax.swing.JLabel;
    1314import javax.swing.JOptionPane;
    1415
     
    129130         */
    130131        if (Main.pref.getBoolean(globalConfirmationKey, globalConfirmationDefault)) {
    131             if (JOptionPane.showConfirmDialog(Main.parent,
    132                 "<html>" + getPermissionMessage() +
    133                 "<br>" + tr("Do you want to allow this?"),
     132            // Ensure dialog box does not exceed main window size
     133            Integer maxWidth = (int) Math.max(200, Main.parent.getWidth()*0.6);
     134            String message = "<html><div>" + getPermissionMessage() +
     135                    "<br/>" + tr("Do you want to allow this?") + "</div></html>";
     136            JLabel label = new JLabel(message);
     137            if (label.getPreferredSize().width > maxWidth) {
     138                label.setText(message.replaceFirst("<div>", "<div style=\"width:" + maxWidth + "px;\">"));
     139            }
     140            if (JOptionPane.showConfirmDialog(Main.parent, label,
    134141                tr("Confirm Remote Control action"),
    135142                JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) {
Note: See TracChangeset for help on using the changeset viewer.