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