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.Arrays;
010import java.util.Collection;
011import java.util.Collections;
012import java.util.HashSet;
013
014import org.openstreetmap.josm.data.osm.OsmPrimitive;
015import org.openstreetmap.josm.data.osm.RelationMember;
016import org.openstreetmap.josm.data.osm.RelationMemberData;
017import org.openstreetmap.josm.gui.DefaultNameFormatter;
018import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
019import org.openstreetmap.josm.tools.CheckParameterUtil;
020
021/**
022 * Transferable objects for {@link RelationMemberData}.
023 * @since 9368
024 */
025public class RelationMemberTransferable implements Transferable {
026
027    /**
028     * A wrapper for a collection of {@link RelationMemberData}.
029     */
030    public static final class Data implements Serializable {
031        private static final long serialVersionUID = -8432393711635811029L;
032        private final Collection<RelationMemberData> relationMemberDatas;
033
034        private Data(Collection<RelationMemberData> primitiveData) {
035            CheckParameterUtil.ensureThat(primitiveData instanceof Serializable, "primitiveData must be instanceof Serializable");
036            this.relationMemberDatas = primitiveData;
037        }
038
039        /**
040         * Returns the contained {@link RelationMemberData}
041         * @return the contained {@link RelationMemberData}
042         */
043        public Collection<RelationMemberData> getRelationMemberData() {
044            return Collections.unmodifiableCollection(relationMemberDatas);
045        }
046
047        /**
048         * Gets the Data for the given list of members.
049         * @param members The collection. The order is preserved.
050         * @return The data.
051         */
052        public static Data getData(Collection<RelationMember> members) {
053            final Collection<RelationMemberData> r = new ArrayList<>(members.size());
054            for (RelationMember member : members) {
055                r.add(new RelationMemberData(member.getRole(), member.getType(), member.getUniqueId()));
056            }
057            return new Data(r);
058        }
059    }
060
061    /**
062     * Data flavor for {@link RelationMemberData} which is wrapped in {@link Data}.
063     */
064    public static final DataFlavor RELATION_MEMBER_DATA = new DataFlavor(Data.class, "Relation member");
065    private final Collection<RelationMember> members;
066
067    /**
068     * Constructs a new {@code RelationMemberTransferable}.
069     * @param members list of relation members
070     */
071    public RelationMemberTransferable(Collection<RelationMember> members) {
072        this.members = new ArrayList<>(members);
073    }
074
075    @Override
076    public DataFlavor[] getTransferDataFlavors() {
077        return new DataFlavor[]{RELATION_MEMBER_DATA, PrimitiveTransferData.DATA_FLAVOR, DataFlavor.stringFlavor};
078    }
079
080    @Override
081    public boolean isDataFlavorSupported(DataFlavor flavor) {
082        return Arrays.asList(getTransferDataFlavors()).contains(flavor);
083    }
084
085    @Override
086    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
087        if (DataFlavor.stringFlavor.equals(flavor)) {
088            return getStringData();
089        } else if (RELATION_MEMBER_DATA.equals(flavor)) {
090            return getRelationMemberData();
091        } else if (PrimitiveTransferData.DATA_FLAVOR.equals(flavor)) {
092            return getPrimitiveData();
093        }
094        throw new UnsupportedFlavorException(flavor);
095    }
096
097    private PrimitiveTransferData getPrimitiveData() {
098        Collection<OsmPrimitive> primitives = new HashSet<>();
099        for (RelationMember member : members) {
100            primitives.add(member.getMember());
101        }
102        return PrimitiveTransferData.getData(primitives);
103    }
104
105    protected String getStringData() {
106        final StringBuilder sb = new StringBuilder();
107        for (RelationMember member : members) {
108            sb.append(member.getType())
109              .append(' ').append(member.getUniqueId())
110              .append(' ').append(member.getRole())
111              .append(" # ").append(member.getMember().getDisplayName(DefaultNameFormatter.getInstance()))
112              .append('\n');
113        }
114        return sb.toString().replace("\u200E", "").replace("\u200F", "");
115    }
116
117    protected Data getRelationMemberData() {
118        return Data.getData(members);
119    }
120}