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