001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.datatransfer.importers;
003
004import java.awt.Component;
005import java.awt.datatransfer.DataFlavor;
006import java.awt.datatransfer.UnsupportedFlavorException;
007import java.io.IOException;
008import java.util.regex.Matcher;
009import java.util.regex.Pattern;
010
011import javax.swing.TransferHandler.TransferSupport;
012
013import org.openstreetmap.josm.actions.OpenLocationAction;
014import org.openstreetmap.josm.data.coor.EastNorth;
015import org.openstreetmap.josm.data.coor.LatLon;
016import org.openstreetmap.josm.data.preferences.BooleanProperty;
017import org.openstreetmap.josm.gui.MapView;
018import org.openstreetmap.josm.gui.layer.OsmDataLayer;
019
020/**
021 * Handles the paste / drop of an OSM address.
022 * <p>
023 * e.g. http://www.openstreetmap.org/node/123 downloads node 123
024 *
025 * @author Michael Zangl
026 * @since 10881
027 */
028public class OsmLinkPaster extends AbstractOsmDataPaster {
029
030    static final class NoWarnOpenLocationAction extends OpenLocationAction {
031        @Override
032        protected void warnNoSuitableTasks(String url) {
033            // ignore this.
034        }
035    }
036
037    private static final BooleanProperty PASTE_REFERRERS = new BooleanProperty("paste.url.download-referrers", true);
038    private static final String OSM_SERVER = "^https?\\://(\\w+\\.)?(osm|openstreetmap)\\.org/";
039
040    /**
041     * Create a new Osm address paster
042     */
043    public OsmLinkPaster() {
044        super(DataFlavor.stringFlavor);
045    }
046
047    @Override
048    public boolean importData(TransferSupport support, OsmDataLayer layer, EastNorth pasteAt)
049            throws UnsupportedFlavorException, IOException {
050        if (!supports(support)) {
051            throw new UnsupportedFlavorException(df);
052        }
053
054        String transferData = (String) support.getTransferable().getTransferData(df);
055        if (new NoWarnOpenLocationAction().openUrl(transferData)) {
056            return true;
057        }
058
059        LatLon ll = parseLatLon(transferData);
060        if (ll != null) {
061            Component comp = support.getComponent();
062            if (comp instanceof MapView) {
063                ((MapView) comp).zoomTo(ll);
064            }
065        }
066
067        return false;
068    }
069
070    protected static LatLon parseLatLon(String transferData) {
071        Matcher matcher = Pattern
072                .compile(OSM_SERVER + "#map=(?<zoom>\\d+)/(?<lat>-?\\d+\\.\\d+)/(?<lon>-?\\d+\\.\\d+)$")
073                .matcher(transferData);
074
075        if (!matcher.matches()) {
076            return null;
077        } else {
078            return new LatLon(Double.parseDouble(matcher.group("lat")), Double.parseDouble(matcher.group("lon")));
079        }
080    }
081}