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.DefaultNameFormatter; 015import org.openstreetmap.josm.data.osm.OsmPrimitive; 016import org.openstreetmap.josm.data.osm.RelationMember; 017import org.openstreetmap.josm.data.osm.RelationMemberData; 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}