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.stream.Collectors; 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 return new Data(members.stream() 054 .map(m -> new RelationMemberData(m.getRole(), m.getType(), m.getUniqueId())) 055 .collect(Collectors.toList())); 056 } 057 } 058 059 /** 060 * Data flavor for {@link RelationMemberData} which is wrapped in {@link Data}. 061 */ 062 public static final DataFlavor RELATION_MEMBER_DATA = new DataFlavor(Data.class, "Relation member"); 063 private final Collection<RelationMember> members; 064 065 /** 066 * Constructs a new {@code RelationMemberTransferable}. 067 * @param members list of relation members 068 */ 069 public RelationMemberTransferable(Collection<RelationMember> members) { 070 this.members = new ArrayList<>(members); 071 } 072 073 @Override 074 public DataFlavor[] getTransferDataFlavors() { 075 return new DataFlavor[]{RELATION_MEMBER_DATA, PrimitiveTransferData.DATA_FLAVOR, DataFlavor.stringFlavor}; 076 } 077 078 @Override 079 public boolean isDataFlavorSupported(DataFlavor flavor) { 080 return Arrays.asList(getTransferDataFlavors()).contains(flavor); 081 } 082 083 @Override 084 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { 085 if (DataFlavor.stringFlavor.equals(flavor)) { 086 return getStringData(); 087 } else if (RELATION_MEMBER_DATA.equals(flavor)) { 088 return getRelationMemberData(); 089 } else if (PrimitiveTransferData.DATA_FLAVOR.equals(flavor)) { 090 return getPrimitiveData(); 091 } 092 throw new UnsupportedFlavorException(flavor); 093 } 094 095 private PrimitiveTransferData getPrimitiveData() { 096 Collection<OsmPrimitive> primitives = members.stream().map(RelationMember::getMember).collect(Collectors.toSet()); 097 return PrimitiveTransferData.getData(primitives); 098 } 099 100 protected String getStringData() { 101 final StringBuilder sb = new StringBuilder(); 102 for (RelationMember member : members) { 103 sb.append(member.getType()) 104 .append(' ').append(member.getUniqueId()) 105 .append(' ').append(member.getRole()) 106 .append(" # ").append(member.getMember().getDisplayName(DefaultNameFormatter.getInstance())) 107 .append('\n'); 108 } 109 return DefaultNameFormatter.removeBiDiCharacters(sb.toString()); 110 } 111 112 protected Data getRelationMemberData() { 113 return Data.getData(members); 114 } 115}