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}