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