001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.command;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.util.Collection;
007import java.util.Objects;
008
009import javax.swing.Icon;
010
011import org.openstreetmap.josm.data.osm.DataSet;
012import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
013import org.openstreetmap.josm.data.osm.OsmPrimitive;
014import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
015import org.openstreetmap.josm.data.osm.Relation;
016import org.openstreetmap.josm.data.osm.RelationMember;
017import org.openstreetmap.josm.tools.ImageProvider;
018
019/**
020 * Command that changes the role of a relation member
021 *
022 * @author Teemu Koskinen <teemu.koskinen@mbnet.fi>
023 */
024public class ChangeRelationMemberRoleCommand extends Command {
025
026    // The relation to be changed
027    private final Relation relation;
028    // Position of the member
029    private final int position;
030    // The new role
031    private final String newRole;
032    // The old role
033    private String oldRole;
034    // Old value of modified
035    private Boolean oldModified;
036
037    /**
038     * Constructs a new {@code ChangeRelationMemberRoleCommand}.
039     * @param relation The relation to be changed. Must not be null, and belong to a data set
040     * @param position Member position
041     * @param newRole New role
042     */
043    public ChangeRelationMemberRoleCommand(Relation relation, int position, String newRole) {
044        this(relation.getDataSet(), relation, position, newRole);
045    }
046
047    /**
048     * Constructs a new {@code ChangeRelationMemberRoleCommand}.
049     * @param dataSet The data set the role is in. Must not be {@code null}
050     * @param relation The relation to be changed
051     * @param position Member position
052     * @param newRole New role
053     * @since 12355
054     */
055    public ChangeRelationMemberRoleCommand(DataSet dataSet, Relation relation, int position, String newRole) {
056        super(dataSet);
057        this.relation = relation;
058        this.position = position;
059        this.newRole = newRole;
060    }
061
062    @Override
063    public boolean executeCommand() {
064        if (position >= 0 && position < relation.getMembersCount()) {
065            oldRole = relation.getMember(position).getRole();
066            if (!newRole.equals(oldRole)) {
067                relation.setMember(position, new RelationMember(newRole, relation.getMember(position).getMember()));
068                oldModified = relation.isModified();
069                relation.setModified(true);
070            }
071        }
072        return true;
073    }
074
075    @Override
076    public void undoCommand() {
077        if (position >= 0 && position < relation.getMembersCount()) {
078            relation.setMember(position, new RelationMember(oldRole, relation.getMember(position).getMember()));
079            if (oldModified != null) {
080                relation.setModified(oldModified);
081            }
082        }
083    }
084
085    @Override
086    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
087        modified.add(relation);
088    }
089
090    @Override
091    public String getDescriptionText() {
092        return tr("Change relation member role for {0} {1}",
093                OsmPrimitiveType.from(relation),
094                relation.getDisplayName(DefaultNameFormatter.getInstance()));
095    }
096
097    @Override
098    public Icon getDescriptionIcon() {
099        return ImageProvider.get(relation.getDisplayType());
100    }
101
102    @Override
103    public int hashCode() {
104        return Objects.hash(super.hashCode(), relation, position, newRole, oldRole, oldModified);
105    }
106
107    @Override
108    public boolean equals(Object obj) {
109        if (this == obj) return true;
110        if (obj == null || getClass() != obj.getClass()) return false;
111        if (!super.equals(obj)) return false;
112        ChangeRelationMemberRoleCommand that = (ChangeRelationMemberRoleCommand) obj;
113        return position == that.position &&
114                Objects.equals(relation, that.relation) &&
115                Objects.equals(newRole, that.newRole) &&
116                Objects.equals(oldRole, that.oldRole) &&
117                Objects.equals(oldModified, that.oldModified);
118    }
119}