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.util.ArrayList;
008import java.util.Arrays;
009import java.util.List;
010
011import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
012import org.openstreetmap.josm.data.osm.PrimitiveData;
013import org.openstreetmap.josm.gui.datatransfer.data.OsmLayerTransferData;
014import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTagTransferData;
015import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
016import org.openstreetmap.josm.gui.datatransfer.data.TagTransferData;
017import org.openstreetmap.josm.gui.layer.OsmDataLayer;
018
019/**
020 * Transferable objects for {@link PrimitiveTransferData} objects
021 * @since 9369
022 * @since 10604 Complete rework
023 */
024public class PrimitiveTransferable implements Transferable {
025
026    /**
027     * The flavors that are available for normal primitives.
028     */
029    private static final List<DataFlavor> PRIMITIVE_FLAVORS = Arrays.asList(PrimitiveTransferData.DATA_FLAVOR,
030            TagTransferData.FLAVOR, DataFlavor.stringFlavor);
031    private final PrimitiveTransferData primitives;
032    private final OsmDataLayer sourceLayer;
033
034    /**
035     * Constructs a new {@code PrimitiveTransferable}.
036     * @param primitives collection of OSM primitives
037     */
038    public PrimitiveTransferable(PrimitiveTransferData primitives) {
039        this(primitives, null);
040    }
041
042    /**
043     * Constructs a new {@code PrimitiveTransferable}.
044     * @param primitives collection of OSM primitives
045     * @param sourceLayer The layer the primitives are copied from
046     */
047    public PrimitiveTransferable(PrimitiveTransferData primitives, OsmDataLayer sourceLayer) {
048        this.primitives = primitives;
049        this.sourceLayer = sourceLayer;
050    }
051
052    @Override
053    public DataFlavor[] getTransferDataFlavors() {
054        ArrayList<DataFlavor> flavors = new ArrayList<>(PRIMITIVE_FLAVORS);
055        if (sourceLayer != null) {
056            flavors.addAll(OsmLayerTransferData.FLAVORS);
057        }
058        return flavors.toArray(new DataFlavor[0]);
059    }
060
061    @Override
062    public boolean isDataFlavorSupported(DataFlavor flavor) {
063        DataFlavor[] flavors = getTransferDataFlavors();
064        for (DataFlavor f : flavors) {
065            if (flavor.equals(f)) {
066                return true;
067            }
068        }
069        return false;
070    }
071
072    @Override
073    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
074        if (DataFlavor.stringFlavor.equals(flavor)) {
075            return getStringData();
076        } else if (PrimitiveTransferData.DATA_FLAVOR.equals(flavor)) {
077            return primitives;
078        } else if (PrimitiveTagTransferData.FLAVOR.equals(flavor)) {
079            return new PrimitiveTagTransferData(primitives);
080        } else if (TagTransferData.FLAVOR.equals(flavor)) {
081            return new TagTransferData(primitives.getDirectlyAdded());
082        } else if (sourceLayer != null && OsmLayerTransferData.FLAVORS.contains(flavor)) {
083            return new OsmLayerTransferData(null, sourceLayer);
084        } else {
085            throw new UnsupportedFlavorException(flavor);
086        }
087    }
088
089    protected String getStringData() {
090        final StringBuilder sb = new StringBuilder();
091        for (PrimitiveData primitive : primitives.getDirectlyAdded()) {
092            if (sb.length() > 0) {
093                sb.append('\n');
094            }
095            sb.append(OsmPrimitiveType.from(primitive).getAPIName()).append(' ').append(primitive.getId());
096        }
097        return sb.toString().replace("\u200E", "").replace("\u200F", "");
098    }
099}