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.Serializable;
008import java.util.ArrayList;
009import java.util.Collection;
010
011import org.openstreetmap.josm.data.osm.OsmPrimitive;
012import org.openstreetmap.josm.data.osm.PrimitiveData;
013import org.openstreetmap.josm.gui.DefaultNameFormatter;
014import org.openstreetmap.josm.tools.CheckParameterUtil;
015
016/**
017 * Transferable objects for {@link PrimitiveData}.
018 * @since 9369
019 */
020public class PrimitiveTransferable implements Transferable {
021
022    /**
023     * A wrapper for a collection of {@link PrimitiveData}.
024     */
025    public static final class Data implements Serializable {
026        private static final long serialVersionUID = -1485089993600213704L;
027        private final Collection<PrimitiveData> primitiveData;
028
029        private Data(Collection<PrimitiveData> primitiveData) {
030            CheckParameterUtil.ensureThat(primitiveData instanceof Serializable, "primitiveData must be instanceof Serializable");
031            this.primitiveData = primitiveData;
032        }
033
034        /**
035         * Returns the contained {@link PrimitiveData}
036         * @return the contained {@link PrimitiveData}
037         */
038        public Collection<PrimitiveData> getPrimitiveData() {
039            return primitiveData;
040        }
041    }
042
043    /**
044     * Data flavor for {@link PrimitiveData} which is wrapped in {@link Data}.
045     */
046    public static final DataFlavor PRIMITIVE_DATA = new DataFlavor(Data.class, Data.class.getName());
047    private final Collection<? extends OsmPrimitive> primitives;
048
049    /**
050     * Constructs a new {@code PrimitiveTransferable}.
051     * @param primitives collection of OSM primitives
052     */
053    public PrimitiveTransferable(Collection<? extends OsmPrimitive> primitives) {
054        this.primitives = primitives;
055    }
056
057    @Override
058    public DataFlavor[] getTransferDataFlavors() {
059        return new DataFlavor[]{PRIMITIVE_DATA, DataFlavor.stringFlavor};
060    }
061
062    @Override
063    public boolean isDataFlavorSupported(DataFlavor flavor) {
064        return flavor == PRIMITIVE_DATA;
065    }
066
067    @Override
068    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
069        if (DataFlavor.stringFlavor.equals(flavor)) {
070            return getStringData();
071        } else if (PRIMITIVE_DATA.equals(flavor)) {
072            return getPrimitiveData();
073        }
074        throw new UnsupportedFlavorException(flavor);
075    }
076
077    protected String getStringData() {
078        final StringBuilder sb = new StringBuilder();
079        for (OsmPrimitive primitive : primitives) {
080            sb.append(primitive.getType())
081              .append(' ').append(primitive.getUniqueId())
082              .append(" # ").append(primitive.getDisplayName(DefaultNameFormatter.getInstance()))
083              .append('\n');
084        }
085        return sb.toString().replace("\u200E", "").replace("\u200F", "");
086    }
087
088    protected Data getPrimitiveData() {
089        final Collection<PrimitiveData> r = new ArrayList<>(primitives.size());
090        for (OsmPrimitive primitive : primitives) {
091            r.add(primitive.save());
092        }
093        return new Data(r);
094    }
095}