001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm.history;
003
004import java.text.MessageFormat;
005import java.util.ArrayList;
006import java.util.Collections;
007import java.util.Date;
008import java.util.List;
009
010import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
011import org.openstreetmap.josm.data.osm.Relation;
012import org.openstreetmap.josm.data.osm.RelationMemberData;
013import org.openstreetmap.josm.data.osm.User;
014import org.openstreetmap.josm.tools.CheckParameterUtil;
015
016/**
017 * Represents an immutable OSM relation in the context of a historical view on
018 * OSM data.
019 *
020 */
021public class HistoryRelation extends HistoryOsmPrimitive {
022
023    private final List<RelationMemberData> members = new ArrayList<>();
024
025    /**
026     * constructor
027     *
028     * @param id the id (&gt; 0 required)
029     * @param version the version (&gt; 0 required)
030     * @param visible whether the primitive is still visible
031     * @param user  the user (!= null required)
032     * @param changesetId the changeset id (&gt; 0 required)
033     * @param timestamp the timestamp (!= null required)
034     *
035     * @throws IllegalArgumentException if preconditions are violated
036     */
037    public HistoryRelation(long id, long version, boolean visible, User user, long changesetId, Date timestamp) {
038        super(id, version, visible, user, changesetId, timestamp);
039    }
040
041    /**
042     * constructor
043     *
044     * @param id the id (&gt; 0 required)
045     * @param version the version (&gt; 0 required)
046     * @param visible whether the primitive is still visible
047     * @param user  the user (!= null required)
048     * @param changesetId the changeset id (&gt; 0 required if {@code checkHistoricParams} is true)
049     * @param timestamp the timestamp (!= null required if {@code checkHistoricParams} is true)
050     * @param checkHistoricParams If true, checks values of {@code changesetId} and {@code timestamp}
051     *
052     * @throws IllegalArgumentException if preconditions are violated
053     * @since 5440
054     */
055    public HistoryRelation(long id, long version, boolean visible, User user, long changesetId, Date timestamp, boolean checkHistoricParams) {
056        super(id, version, visible, user, changesetId, timestamp, checkHistoricParams);
057    }
058
059    /**
060     * constructor
061     *
062     * @param id the id (&gt; 0 required)
063     * @param version the version (&gt; 0 required)
064     * @param visible whether the primitive is still visible
065     * @param user  the user (!= null required)
066     * @param changesetId the changeset id (&gt; 0 required)
067     * @param timestamp the timestamp (!= null required)
068     * @param members list of members for this relation
069     *
070     * @throws IllegalArgumentException if preconditions are violated
071     */
072    public HistoryRelation(long id, long version, boolean visible, User user, long changesetId, Date timestamp,
073            List<RelationMemberData> members) {
074        this(id, version, visible, user, changesetId, timestamp);
075        if (members != null) {
076            this.members.addAll(members);
077        }
078    }
079
080    /**
081     * Constructs a new {@code HistoryRelation} from an existing {@link Relation}.
082     * @param r the relation
083     */
084    public HistoryRelation(Relation r) {
085        super(r);
086    }
087
088    /**
089     * replies an immutable list of members of this relation
090     *
091     * @return an immutable list of members of this relation
092     */
093    public List<RelationMemberData> getMembers() {
094        return Collections.unmodifiableList(members);
095    }
096
097    /**
098     * replies the number of members
099     *
100     * @return the number of members
101     *
102     */
103    public int getNumMembers() {
104        return members.size();
105    }
106
107    /**
108     * replies the idx-th member
109     * @param idx the index
110     * @return the idx-th member
111     * @throws IndexOutOfBoundsException if idx is out of bounds
112     */
113    public RelationMemberData getRelationMember(int idx) throws IndexOutOfBoundsException  {
114        if (idx < 0 || idx >= members.size())
115            throw new IndexOutOfBoundsException(
116                    MessageFormat.format("Parameter {0} not in range 0..{1}. Got ''{2}''.", "idx", members.size(), idx));
117        return members.get(idx);
118    }
119
120    /**
121     * replies the type, i.e. {@link OsmPrimitiveType#RELATION}
122     *
123     */
124    @Override
125    public OsmPrimitiveType getType() {
126        return OsmPrimitiveType.RELATION;
127    }
128
129    /**
130     * adds a member to the list of members
131     *
132     * @param member the member (must not be null)
133     * @throws IllegalArgumentException if member is null
134     */
135    public void addMember(RelationMemberData member) {
136        CheckParameterUtil.ensureParameterNotNull(member, "member");
137        members.add(member);
138    }
139
140    @Override
141    public String getDisplayName(HistoryNameFormatter formatter) {
142        return formatter.format(this);
143    }
144}