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    public Way getWay() {
061        return (Way) member;
062    }
063
064    /**
065     * Returns the relation member as a node.
066     * @return Member as node
067     * @since 1937
068     */
069    public Node getNode() {
070        return (Node) member;
071    }
072
073    @Override
074    public OsmPrimitive getMember() {
075        return member;
076    }
077
078    /**
079     * Constructs a new {@code RelationMember}.
080     * @param role Can be null, in this case it's save as ""
081     * @param member Cannot be null
082     * @throws IllegalArgumentException if member is <code>null</code>
083     */
084    public RelationMember(String role, OsmPrimitive member) {
085        CheckParameterUtil.ensureParameterNotNull(member, "member");
086        this.role = Optional.ofNullable(role).orElse("");
087        this.member = member;
088    }
089
090    /**
091     * Copy constructor.
092     * This constructor is left only for backwards compatibility. Copying RelationMember doesn't make sense
093     * because it's immutable
094     * @param other relation member to be copied.
095     */
096    public RelationMember(RelationMember other) {
097        this(other.role, other.member);
098    }
099
100    @Override
101    public String toString() {
102        return '"' + role + "\"=" + member;
103    }
104
105    /**
106     * Replies true, if this relation member refers to the primitive
107     *
108     * @param primitive  the primitive to check
109     * @return true, if this relation member refers to the primitive
110     */
111    public boolean refersTo(OsmPrimitive primitive) {
112        return member == primitive;
113    }
114
115    @Override
116    public int hashCode() {
117        return Objects.hash(role, member);
118    }
119
120    @Override
121    public boolean equals(Object obj) {
122        if (this == obj) return true;
123        if (obj == null || getClass() != obj.getClass()) return false;
124        RelationMember that = (RelationMember) obj;
125        return Objects.equals(role, that.role) &&
126               Objects.equals(member, that.member);
127    }
128
129    /**
130     * PrimitiveId implementation. Returns the same value as getMember().getType()
131     */
132    @Override
133    public OsmPrimitiveType getType() {
134        return member.getType();
135    }
136
137    /**
138     * PrimitiveId implementation. Returns the same value as getMember().getUniqueId()
139     */
140    @Override
141    public long getUniqueId() {
142        return member.getUniqueId();
143    }
144
145    /**
146     * PrimitiveId implementation. Returns the same value as getMember().isNew()
147     */
148    @Override
149    public boolean isNew() {
150        return member.isNew();
151    }
152}