001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.datatransfer;
003
004import java.awt.datatransfer.DataFlavor;
005import java.awt.datatransfer.Transferable;
006import java.awt.datatransfer.UnsupportedFlavorException;
007import java.io.IOException;
008import java.util.Arrays;
009import java.util.Collection;
010import java.util.Collections;
011
012import org.openstreetmap.josm.Main;
013import org.openstreetmap.josm.data.coor.EastNorth;
014import org.openstreetmap.josm.data.osm.OsmPrimitive;
015import org.openstreetmap.josm.gui.datatransfer.importers.AbstractOsmDataPaster;
016import org.openstreetmap.josm.gui.datatransfer.importers.FilePaster;
017import org.openstreetmap.josm.gui.datatransfer.importers.OsmLinkPaster;
018import org.openstreetmap.josm.gui.datatransfer.importers.PrimitiveDataPaster;
019import org.openstreetmap.josm.gui.datatransfer.importers.PrimitiveTagTransferPaster;
020import org.openstreetmap.josm.gui.datatransfer.importers.TagTransferPaster;
021import org.openstreetmap.josm.gui.datatransfer.importers.TextTagPaster;
022import org.openstreetmap.josm.gui.layer.OsmDataLayer;
023
024/**
025 * This transfer hanlder provides the ability to transfer OSM data. It allows you to receive files, primitives or tags.
026 * @author Michael Zangl
027 * @since 10604
028 */
029public class OsmTransferHandler extends AbstractStackTransferHandler {
030
031    private static final Collection<AbstractOsmDataPaster> SUPPORTED = Arrays.asList(
032            new FilePaster(), new PrimitiveDataPaster(),
033            new PrimitiveTagTransferPaster(),
034            new TagTransferPaster(), new OsmLinkPaster(), new TextTagPaster());
035
036    @Override
037    protected Collection<AbstractOsmDataPaster> getSupportedPasters() {
038        return Collections.unmodifiableCollection(SUPPORTED);
039    }
040
041    private boolean importTags(TransferSupport support, Collection<? extends OsmPrimitive> primitives) {
042        for (AbstractOsmDataPaster df : SUPPORTED) {
043            if (df.supports(support)) {
044                try {
045                    if (df.importTagsOn(support, primitives)) {
046                        return true;
047                    }
048                } catch (UnsupportedFlavorException | IOException e) {
049                    Main.warn(e);
050                }
051            }
052        }
053        return super.importData(support);
054    }
055
056    /**
057     * Paste the current clipboard current at the given position
058     * @param editLayer The layer to paste on.
059     * @param mPosition The position to paste at. If it is <code>null</code>, the original position will be used.
060     */
061    public void pasteOn(OsmDataLayer editLayer, EastNorth mPosition) {
062        Transferable transferable = ClipboardUtils.getClipboard().getContents(null);
063        pasteOn(editLayer, mPosition, transferable);
064    }
065
066    /**
067     * Paste the given clipboard current at the given position
068     * @param editLayer The layer to paste on.
069     * @param mPosition The position to paste at. If it is <code>null</code>, the original position will be used.
070     * @param transferable The transferable to use.
071     */
072    public void pasteOn(OsmDataLayer editLayer, EastNorth mPosition, Transferable transferable) {
073        importData(new TransferSupport(Main.panel, transferable), editLayer, mPosition);
074    }
075
076    /**
077     * Paste the given tags on the primitives.
078     * @param primitives The primitives to paste on.
079     */
080    public void pasteTags(Collection<? extends OsmPrimitive> primitives) {
081        Transferable transferable = ClipboardUtils.getClipboard().getContents(null);
082        importTags(new TransferSupport(Main.panel, transferable), primitives);
083    }
084
085    /**
086     * Check if any primitive data or any other supported data is available in the clipboard.
087     * @return <code>true</code> if any flavor is supported.
088     */
089    public boolean isDataAvailable() {
090        try {
091            Collection<DataFlavor> available = Arrays.asList(ClipboardUtils.getClipboard().getAvailableDataFlavors());
092            for (AbstractOsmDataPaster s : SUPPORTED) {
093                if (s.supports(available)) {
094                    return true;
095                }
096            }
097        } catch (IllegalStateException e) {
098            Main.debug(e);
099        } catch (NullPointerException e) {
100            // JDK-6322854: On Linux/X11, NPE can happen for unknown reasons, on all versions of Java
101            Main.error(e);
102        }
103        return false;
104    }
105}