001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.command.conflict;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.util.Collection;
007import java.util.List;
008import java.util.Objects;
009
010import javax.swing.Icon;
011
012import org.openstreetmap.josm.data.conflict.Conflict;
013import org.openstreetmap.josm.data.osm.DataSet;
014import org.openstreetmap.josm.data.osm.OsmDataManager;
015import org.openstreetmap.josm.data.osm.OsmPrimitive;
016import org.openstreetmap.josm.data.osm.Relation;
017import org.openstreetmap.josm.data.osm.RelationMember;
018import org.openstreetmap.josm.tools.ImageProvider;
019import org.openstreetmap.josm.tools.Logging;
020
021/**
022 * Represents the resolution of conflicts in the member list of two {@link Relation}s.
023 * @since 1631
024 */
025public class RelationMemberConflictResolverCommand extends ConflictResolveCommand {
026    /** the conflict to resolve */
027    private final Conflict<Relation> conflict;
028    /** the list of merged nodes. This becomes the list of news of my way after the command is executed */
029    private final List<RelationMember> mergedMembers;
030
031    /**
032     * Constructs a new {@code RelationMemberConflictResolverCommand}.
033     * @param conflict the conflict to resolve
034     * @param mergedMembers the list of merged relation members
035     */
036    @SuppressWarnings("unchecked")
037    public RelationMemberConflictResolverCommand(Conflict<? extends OsmPrimitive> conflict, List<RelationMember> mergedMembers) {
038        super(conflict.getMy().getDataSet());
039        this.conflict = (Conflict<Relation>) conflict;
040        this.mergedMembers = mergedMembers;
041    }
042
043    @Override
044    public String getDescriptionText() {
045        return tr("Resolve conflicts in member list of relation {0}", conflict.getMy().getId());
046    }
047
048    @Override
049    public Icon getDescriptionIcon() {
050        return ImageProvider.get("data", "object");
051    }
052
053    @Override
054    public boolean executeCommand() {
055        // remember the current state of 'my' way
056        //
057        super.executeCommand();
058
059        // replace the list of members of 'my' relation by the list of merged members
060        //
061        conflict.getMy().setMembers(mergedMembers);
062
063        return true;
064    }
065
066    @Override
067    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
068            Collection<OsmPrimitive> added) {
069        modified.add(conflict.getMy());
070    }
071
072    @Override
073    public void undoCommand() {
074        DataSet ds = getAffectedDataSet();
075        if (!OsmDataManager.getInstance().containsDataSet(ds)) {
076            Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
077                    this.toString(),
078                    ds.getName()
079            ));
080            return;
081        }
082
083        OsmDataManager.getInstance().setActiveDataSet(ds);
084
085        // restore the former state
086        //
087        super.undoCommand();
088
089        // restore a conflict if necessary
090        //
091        if (!ds.getConflicts().hasConflictForMy(conflict.getMy())) {
092            ds.getConflicts().add(conflict);
093        }
094    }
095
096    @Override
097    public int hashCode() {
098        return Objects.hash(super.hashCode(), conflict, mergedMembers);
099    }
100
101    @Override
102    public boolean equals(Object obj) {
103        if (this == obj) return true;
104        if (obj == null || getClass() != obj.getClass()) return false;
105        if (!super.equals(obj)) return false;
106        RelationMemberConflictResolverCommand that = (RelationMemberConflictResolverCommand) obj;
107        return Objects.equals(conflict, that.conflict) &&
108               Objects.equals(mergedMembers, that.mergedMembers);
109    }
110}