001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.command;
003
004import java.util.Collection;
005import java.util.Objects;
006
007import javax.swing.Icon;
008
009import org.openstreetmap.josm.data.osm.DataSet;
010import org.openstreetmap.josm.data.osm.Node;
011import org.openstreetmap.josm.data.osm.OsmPrimitive;
012import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
013import org.openstreetmap.josm.data.osm.Way;
014import org.openstreetmap.josm.tools.ImageProvider;
015
016/**
017 * Abstracts superclass of {@link ChangeNodesCommand} / {@link RemoveNodesCommand}.
018 * @param <C> type of nodes collection used for this command
019 * @since 15013
020 */
021public abstract class AbstractNodesCommand<C extends Collection<Node>> extends Command {
022
023    protected final Way way;
024    protected final C cmdNodes;
025
026    /**
027     * Constructs a new {@code AbstractNodesCommand}.
028     * @param way The way to modify
029     * @param cmdNodes The collection of nodes for this command
030     */
031    protected AbstractNodesCommand(Way way, C cmdNodes) {
032        this(way.getDataSet(), way, cmdNodes);
033    }
034
035    /**
036     * Constructs a new {@code AbstractNodesCommand}.
037     * @param ds The target data set. Must not be {@code null}
038     * @param way The way to modify
039     * @param cmdNodes The collection of nodes for this command
040     */
041    protected AbstractNodesCommand(DataSet ds, Way way, C cmdNodes) {
042        super(ds);
043        this.way = Objects.requireNonNull(way, "way");
044        this.cmdNodes = Objects.requireNonNull(cmdNodes, "cmdNodes");
045        if (cmdNodes.isEmpty()) {
046            throw new IllegalArgumentException("Nodes collection is empty");
047        }
048    }
049
050    protected abstract void modifyWay();
051
052    @Override
053    public boolean executeCommand() {
054        super.executeCommand();
055        modifyWay();
056        way.setModified(true);
057        return true;
058    }
059
060    @Override
061    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
062        modified.add(way);
063    }
064
065    @Override
066    public Icon getDescriptionIcon() {
067        return ImageProvider.get(OsmPrimitiveType.WAY);
068    }
069
070    @Override
071    public int hashCode() {
072        return Objects.hash(super.hashCode(), way, cmdNodes);
073    }
074
075    @Override
076    public boolean equals(Object obj) {
077        if (this == obj) return true;
078        if (obj == null || getClass() != obj.getClass()) return false;
079        if (!super.equals(obj)) return false;
080        AbstractNodesCommand<?> that = (AbstractNodesCommand<?>) obj;
081        return Objects.equals(way, that.way) &&
082               Objects.equals(cmdNodes, that.cmdNodes);
083    }
084}