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.Objects;
007
008import org.openstreetmap.josm.command.Command;
009import org.openstreetmap.josm.data.conflict.Conflict;
010import org.openstreetmap.josm.data.conflict.ConflictCollection;
011import org.openstreetmap.josm.data.osm.DataSet;
012import org.openstreetmap.josm.data.osm.OsmDataManager;
013import org.openstreetmap.josm.tools.Logging;
014
015/**
016 * This is the common base class for {@link Command}s which manipulate {@link Conflict}s in
017 * addition to {@link org.openstreetmap.josm.data.osm.OsmPrimitive}s.
018 *
019 * A ConflictResolverCommand can remember a collection of conflicts it resolves. Upon undoing
020 * it reconstitutes them.
021 *
022 */
023public abstract class ConflictResolveCommand extends Command {
024    /** the list of resolved conflicts */
025    private final ConflictCollection resolvedConflicts = new ConflictCollection();
026
027    /**
028     * Constructs a new {@code ConflictResolveCommand} in the context of a given data set.
029     * @param ds the data set. Must not be null.
030     */
031    public ConflictResolveCommand(DataSet ds) {
032        super(ds);
033    }
034
035    /**
036     * remembers a conflict in the internal list of remembered conflicts
037     *
038     * @param c the remembered conflict
039     */
040    protected void rememberConflict(Conflict<?> c) {
041        if (!resolvedConflicts.hasConflictForMy(c.getMy())) {
042            resolvedConflicts.add(c);
043        }
044    }
045
046    /**
047     * reconstitutes all remembered conflicts. Add the remembered conflicts to the
048     * set of conflicts of the {@link DataSet} this command was applied to.
049     *
050     */
051    protected void reconstituteConflicts() {
052        DataSet ds = getAffectedDataSet();
053        for (Conflict<?> c : resolvedConflicts) {
054            if (!ds.getConflicts().hasConflictForMy(c.getMy())) {
055                ds.getConflicts().add(c);
056            }
057        }
058    }
059
060    @Override
061    public void undoCommand() {
062        super.undoCommand();
063
064        DataSet ds = getAffectedDataSet();
065        if (!OsmDataManager.getInstance().containsDataSet(ds)) {
066            Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
067                    this.toString(),
068                    ds.getName()
069            ));
070            return;
071        }
072
073        OsmDataManager.getInstance().setActiveDataSet(ds);
074        reconstituteConflicts();
075    }
076
077    @Override
078    public int hashCode() {
079        return Objects.hash(super.hashCode(), resolvedConflicts);
080    }
081
082    @Override
083    public boolean equals(Object obj) {
084        if (this == obj) return true;
085        if (obj == null || getClass() != obj.getClass()) return false;
086        if (!super.equals(obj)) return false;
087        ConflictResolveCommand that = (ConflictResolveCommand) obj;
088        return Objects.equals(resolvedConflicts, that.resolvedConflicts);
089    }
090}