001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.conflict.tags;
003
004import static org.openstreetmap.josm.gui.conflict.tags.RelationMemberConflictDecisionType.UNDECIDED;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.util.Objects;
008import java.util.Optional;
009
010import org.openstreetmap.josm.data.osm.OsmPrimitive;
011import org.openstreetmap.josm.data.osm.Relation;
012import org.openstreetmap.josm.data.osm.RelationMember;
013import org.openstreetmap.josm.tools.CheckParameterUtil;
014
015/**
016 * This class stores the decision the user made regarding a relation member conflict
017 */
018public class RelationMemberConflictDecision {
019
020    private final Relation relation;
021    private final int pos;
022    private final OsmPrimitive originalPrimitive;
023    private String role;
024    private RelationMemberConflictDecisionType decision;
025
026    public RelationMemberConflictDecision(Relation relation, int pos) {
027        CheckParameterUtil.ensureParameterNotNull(relation, "relation");
028        RelationMember member = relation.getMember(pos);
029        if (member == null)
030            throw new IndexOutOfBoundsException(
031                    tr("Position {0} is out of range. Current number of members is {1}.", pos, relation.getMembersCount()));
032        this.relation = relation;
033        this.pos = pos;
034        this.originalPrimitive = member.getMember();
035        this.role = member.hasRole() ? member.getRole() : "";
036        this.decision = UNDECIDED;
037    }
038
039    public Relation getRelation() {
040        return relation;
041    }
042
043    public int getPos() {
044        return pos;
045    }
046
047    public OsmPrimitive getOriginalPrimitive() {
048        return originalPrimitive;
049    }
050
051    public String getRole() {
052        return role;
053    }
054
055    public RelationMemberConflictDecisionType getDecision() {
056        return decision;
057    }
058
059    public void setRole(String role) {
060        this.role = role == null ? "" : role;
061    }
062
063    public void decide(RelationMemberConflictDecisionType decision) {
064        this.decision = Optional.ofNullable(decision).orElse(UNDECIDED);
065    }
066
067    public boolean isDecided() {
068        return !UNDECIDED.equals(decision);
069    }
070
071    public boolean matches(Relation relation, int pos) {
072        return this.relation == relation && this.pos == pos;
073    }
074
075    @Override
076    public int hashCode() {
077        return Objects.hash(relation, pos, originalPrimitive, role, decision);
078    }
079
080    @Override
081    public boolean equals(Object obj) {
082        if (this == obj) return true;
083        if (obj == null || getClass() != obj.getClass()) return false;
084        RelationMemberConflictDecision that = (RelationMemberConflictDecision) obj;
085        return pos == that.pos &&
086               decision == that.decision &&
087               Objects.equals(relation, that.relation) &&
088               Objects.equals(originalPrimitive, that.originalPrimitive) &&
089               Objects.equals(role, that.role);
090    }
091
092    @Override
093    public String toString() {
094        return originalPrimitive.getPrimitiveId() + " at index " + pos + " with role " + role + " in " + relation.getUniqueId()
095            + " => " + decision;
096    }
097}