001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.data.osm.history;
003    
004    import java.text.MessageFormat;
005    import java.util.ArrayList;
006    import java.util.Collections;
007    import java.util.Date;
008    import java.util.List;
009    
010    import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
011    import org.openstreetmap.josm.data.osm.Relation;
012    import org.openstreetmap.josm.data.osm.RelationMemberData;
013    import org.openstreetmap.josm.data.osm.User;
014    import 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     */
021    public class HistoryRelation extends HistoryOsmPrimitive{
022    
023        private ArrayList<RelationMemberData> members = new ArrayList<RelationMemberData>();
024    
025        /**
026         * constructor
027         *
028         * @param id the id (>0 required)
029         * @param version the version (> 0 required)
030         * @param visible whether the primitive is still visible
031         * @param user  the user (! null required)
032         * @param changesetId the changeset id (> 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) throws IllegalArgumentException {
038            super(id, version, visible, user, changesetId, timestamp);
039        }
040    
041        /**
042         * constructor
043         *
044         * @param id the id (>0 required)
045         * @param version the version (> 0 required)
046         * @param visible whether the primitive is still visible
047         * @param user  the user (! null required)
048         * @param changesetId the changeset id (> 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) throws IllegalArgumentException {
056            super(id, version, visible, user, changesetId, timestamp, checkHistoricParams);
057        }
058    
059        /**
060         * constructor
061         *
062         * @param id the id (>0 required)
063         * @param version the version (> 0 required)
064         * @param visible whether the primitive is still visible
065         * @param user  the user (! null required)
066         * @param changesetId the changeset id (> 0 required)
067         * @param timestamp the timestamp (! null required)
068         * @param members list of members for this relation
069         *
070         * @throws IllegalArgumentException thrown if preconditions are violated
071         */
072        public HistoryRelation(long id, long version, boolean visible, User user, long changesetId,
073                Date timestamp, ArrayList<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 thrown, 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(MessageFormat.format("Parameter {0} not in range 0..{1}. Got ''{2}''.", "idx", members.size(),idx));
116            return members.get(idx);
117        }
118    
119        /**
120         * replies the type, i.e. {@link OsmPrimitiveType#RELATION}
121         *
122         */
123        @Override
124        public OsmPrimitiveType getType() {
125            return OsmPrimitiveType.RELATION;
126        }
127    
128        /**
129         * adds a member to the list of members
130         *
131         * @param member the member (must not be null)
132         * @exception IllegalArgumentException thrown, if member is null
133         */
134        public void addMember(RelationMemberData member) throws IllegalArgumentException {
135            CheckParameterUtil.ensureParameterNotNull(member, "member");
136            members.add(member);
137        }
138    
139        @Override
140        public String getDisplayName(HistoryNameFormatter formatter) {
141            return formatter.format(this);
142        }
143    }