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