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.gui.MapView;
017import org.openstreetmap.josm.gui.layer.OsmDataLayer;
018
019/**
020 * Handles the paste / drop of an OSM address.
021 * <p>
022 * e.g. http://www.openstreetmap.org/node/123 downloads node 123
023 *
024 * @author Michael Zangl
025 * @since 10881
026 */
027public class OsmLinkPaster extends AbstractOsmDataPaster {
028
029    static final class NoWarnOpenLocationAction extends OpenLocationAction {
030        @Override
031        protected void warnNoSuitableTasks(String url) {
032            // ignore this.
033        }
034    }
035
036    private static final String OSM_SERVER = "^https?\\://(\\w+\\.)?(osm|openstreetmap)\\.org/";
037
038    /**
039     * Create a new Osm address paster
040     */
041    public OsmLinkPaster() {
042        super(DataFlavor.stringFlavor);
043    }
044
045    @Override
046    public boolean importData(TransferSupport support, OsmDataLayer layer, EastNorth pasteAt)
047            throws UnsupportedFlavorException, IOException {
048        if (!supports(support)) {
049            throw new UnsupportedFlavorException(df);
050        }
051
052        String transferData = (String) support.getTransferable().getTransferData(df);
053        if (!new NoWarnOpenLocationAction().openUrl(transferData).isEmpty()) {
054            return true;
055        }
056
057        LatLon ll = parseLatLon(transferData);
058        if (ll != null) {
059            Component comp = support.getComponent();
060            if (comp instanceof MapView) {
061                ((MapView) comp).zoomTo(ll);
062            }
063        }
064
065        return false;
066    }
067
068    static LatLon parseLatLon(String transferData) {
069        Matcher matcher = Pattern
070                .compile(OSM_SERVER + "#map=(?<zoom>\\d+)/(?<lat>-?\\d+\\.\\d+)/(?<lon>-?\\d+\\.\\d+)$")
071                .matcher(transferData);
072
073        if (!matcher.matches()) {
074            return null;
075        } else {
076            return new LatLon(Double.parseDouble(matcher.group("lat")), Double.parseDouble(matcher.group("lon")));
077        }
078    }
079}