001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import java.util.Arrays;
005
006import org.openstreetmap.josm.tools.CheckParameterUtil;
007
008/**
009 * A linkage class that can be used by an relation to keep a list of
010 * members. Since membership may be qualified by a "role", a simple
011 * list is not sufficient.
012 *
013 */
014public class RelationMember implements PrimitiveId {
015
016    /**
017     *
018     */
019    private final String role;
020
021    /**
022     *
023     */
024    private final OsmPrimitive member;
025
026    /**
027     * Returns the role of this relation member.
028     * @return Role name or "". Never returns null
029     * @since 1930
030     */
031    public String getRole() {
032        return role;
033    }
034
035    /**
036     * Determines if this relation member has a role.
037     * @return True if role is set
038     * @since 1930
039     */
040    public boolean hasRole() {
041        return !"".equals(role);
042    }
043
044    /**
045     * Determines if this relation member's role is in the given list.
046     * @param roles The roles to look after
047     * @return True if role is in the given list
048     * @since 6305
049     */
050    public boolean hasRole(String ... roles) {
051        return Arrays.asList(roles).contains(role);
052    }
053
054    /**
055     * Determines if this relation member is a relation.
056     * @return True if member is relation
057     * @since 1937
058     */
059    public boolean isRelation() {
060        return member instanceof Relation;
061    }
062
063    /**
064     * Determines if this relation member is a way.
065     * @return True if member is way
066     * @since 1937
067     */
068    public boolean isWay() {
069        return member instanceof Way;
070    }
071
072    /**
073     *
074     * @return type of member for icon display
075     * @since 3844
076     */
077    public OsmPrimitiveType getDisplayType() {
078        return member.getDisplayType();
079    }
080
081    /**
082     * Determines if this relation member is a node.
083     * @return True if member is node
084     * @since 1937
085     */
086    public boolean isNode() {
087        return member instanceof Node;
088    }
089
090    /**
091     * Returns the relation member as a relation.
092     * @return Member as relation
093     * @since 1937
094     */
095    public Relation getRelation() {
096        return (Relation)member;
097    }
098
099    /**
100     * Returns the relation member as a way.
101     * @return Member as way
102     * @since 1937
103     */
104    public Way getWay() {
105        return (Way)member;
106    }
107
108    /**
109     * Returns the relation member as a node.
110     * @return Member as node
111     * @since 1937
112     */
113    public Node getNode() {
114        return (Node)member;
115    }
116
117    /**
118     * Returns the relation member.
119     * @return Member. Returned value is never null.
120     * @since 1937
121     */
122    public OsmPrimitive getMember() {
123        return member;
124    }
125
126    /**
127     * Constructs a new {@code RelationMember}.
128     * @param role Can be null, in this case it's save as ""
129     * @param member Cannot be null
130     * @throws IllegalArgumentException thrown if member is <code>null</code>
131     */
132    public RelationMember(String role, OsmPrimitive member) {
133        CheckParameterUtil.ensureParameterNotNull(member, "member");
134        if (role == null) {
135            role = "";
136        }
137        this.role = role;
138        this.member = member;
139    }
140
141    /**
142     * Copy constructor.
143     * This constructor is left only for backwards compatibility. Copying RelationMember doesn't make sense
144     * because it's immutable
145     * @param other relation member to be copied.
146     */
147    public RelationMember(RelationMember other) {
148        this(other.role, other.member);
149    }
150
151    @Override public String toString() {
152        return '"' + role + "\"=" + member;
153    }
154
155    /**
156     * Replies true, if this relation member refers to the primitive
157     *
158     * @param primitive  the primitive to check
159     * @return true, if this relation member refers to the primitive
160     */
161    public boolean refersTo(OsmPrimitive primitive) {
162        return member == primitive;
163    }
164
165    @Override
166    public int hashCode() {
167        final int prime = 31;
168        int result = 1;
169        result = prime * result + member.hashCode();
170        result = prime * result + role.hashCode();
171        return result;
172    }
173
174    @Override
175    public boolean equals(Object obj) {
176        if (obj instanceof RelationMember) {
177            RelationMember other = (RelationMember) obj;
178            return member.equals(other.getMember()) && role.equals(other.getRole());
179        } else
180            return false;
181    }
182
183    /**
184     * PrimitiveId implementation. Returns the same value as getMember().getType()
185     */
186    @Override
187    public OsmPrimitiveType getType() {
188        return member.getType();
189    }
190
191    /**
192     * PrimitiveId implementation. Returns the same value as getMemberType().getUniqueId()
193     */
194    @Override
195    public long getUniqueId() {
196        return member.getUniqueId();
197    }
198
199    @Override
200    public boolean isNew() {
201        return member.isNew();
202    }
203}