001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.osm; 003 004import java.util.Objects; 005import java.util.Optional; 006 007import org.openstreetmap.josm.tools.CheckParameterUtil; 008 009/** 010 * A linkage class that can be used by an relation to keep a list of members. 011 * Since membership may be qualified by a "role", a simple list is not sufficient. 012 * @since 343 013 */ 014public class RelationMember implements IRelationMember<OsmPrimitive> { 015 016 /** 017 * 018 */ 019 private final String role; 020 021 /** 022 * 023 */ 024 private final OsmPrimitive member; 025 026 @Override 027 public String getRole() { 028 return role; 029 } 030 031 @Override 032 public boolean isRelation() { 033 return member instanceof Relation; 034 } 035 036 @Override 037 public boolean isWay() { 038 return member instanceof Way; 039 } 040 041 @Override 042 public boolean isNode() { 043 return member instanceof Node; 044 } 045 046 /** 047 * Returns the relation member as a relation. 048 * @return Member as relation 049 * @since 1937 050 */ 051 public Relation getRelation() { 052 return (Relation) member; 053 } 054 055 /** 056 * Returns the relation member as a way. 057 * @return Member as way 058 * @since 1937 059 */ 060 @Override 061 public Way getWay() { 062 return (Way) member; 063 } 064 065 /** 066 * Returns the relation member as a node. 067 * @return Member as node 068 * @since 1937 069 */ 070 public Node getNode() { 071 return (Node) member; 072 } 073 074 @Override 075 public OsmPrimitive getMember() { 076 return member; 077 } 078 079 /** 080 * Constructs a new {@code RelationMember}. 081 * @param role Can be null, in this case it's save as "" 082 * @param member Cannot be null 083 * @throws IllegalArgumentException if member is <code>null</code> 084 */ 085 public RelationMember(String role, OsmPrimitive member) { 086 CheckParameterUtil.ensureParameterNotNull(member, "member"); 087 this.role = Optional.ofNullable(role).orElse("").intern(); 088 this.member = member; 089 } 090 091 /** 092 * Copy constructor. 093 * This constructor is left only for backwards compatibility. Copying RelationMember doesn't make sense 094 * because it's immutable 095 * @param other relation member to be copied. 096 */ 097 public RelationMember(RelationMember other) { 098 this(other.role, other.member); 099 } 100 101 @Override 102 public String toString() { 103 return '"' + role + "\"=" + member; 104 } 105 106 /** 107 * Replies true, if this relation member refers to the primitive 108 * 109 * @param primitive the primitive to check 110 * @return true, if this relation member refers to the primitive 111 */ 112 public boolean refersTo(OsmPrimitive primitive) { 113 return member == primitive; 114 } 115 116 @Override 117 public int hashCode() { 118 return Objects.hash(role, member); 119 } 120 121 @Override 122 public boolean equals(Object obj) { 123 if (this == obj) return true; 124 if (obj == null || getClass() != obj.getClass()) return false; 125 RelationMember that = (RelationMember) obj; 126 return Objects.equals(role, that.role) && 127 Objects.equals(member, that.member); 128 } 129 130 /** 131 * PrimitiveId implementation. Returns the same value as getMember().getType() 132 */ 133 @Override 134 public OsmPrimitiveType getType() { 135 return member.getType(); 136 } 137 138 /** 139 * PrimitiveId implementation. Returns the same value as getMember().getUniqueId() 140 */ 141 @Override 142 public long getUniqueId() { 143 return member.getUniqueId(); 144 } 145 146 /** 147 * PrimitiveId implementation. Returns the same value as getMember().isNew() 148 */ 149 @Override 150 public boolean isNew() { 151 return member.isNew(); 152 } 153}