001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.command;
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.osm.Node;
013import org.openstreetmap.josm.data.osm.OsmPrimitive;
014import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
015import org.openstreetmap.josm.data.osm.Way;
016import org.openstreetmap.josm.gui.DefaultNameFormatter;
017import org.openstreetmap.josm.tools.ImageProvider;
018
019/**
020 * Command that changes the nodes list of a way.
021 * The same can be done with ChangeCommand, but this is more
022 * efficient. (Needed for the duplicate node fixing
023 * tool of the validator plugin, when processing large data sets.)
024 *
025 * @author Imi
026 */
027public class ChangeNodesCommand extends Command {
028
029    private final Way way;
030    private final List<Node> newNodes;
031
032    /**
033     * Constructs a new {@code ChangeNodesCommand}.
034     * @param way The way to modify
035     * @param newNodes The new list of nodes for the given way
036     */
037    public ChangeNodesCommand(Way way, List<Node> newNodes) {
038        this.way = way;
039        this.newNodes = newNodes;
040        if (newNodes.isEmpty()) {
041            throw new IllegalArgumentException("Cannot set nodes to be an empty list.");
042        }
043    }
044
045    @Override
046    public boolean executeCommand() {
047        super.executeCommand();
048        way.setNodes(newNodes);
049        way.setModified(true);
050        return true;
051    }
052
053    @Override
054    public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
055        modified.add(way);
056    }
057
058    @Override
059    public String getDescriptionText() {
060        return tr("Change nodes of {0}", way.getDisplayName(DefaultNameFormatter.getInstance()));
061    }
062
063    @Override
064    public Icon getDescriptionIcon() {
065        return ImageProvider.get(OsmPrimitiveType.WAY);
066    }
067
068    @Override
069    public int hashCode() {
070        return Objects.hash(super.hashCode(), way, newNodes);
071    }
072
073    @Override
074    public boolean equals(Object obj) {
075        if (this == obj) return true;
076        if (obj == null || getClass() != obj.getClass()) return false;
077        if (!super.equals(obj)) return false;
078        ChangeNodesCommand that = (ChangeNodesCommand) obj;
079        return Objects.equals(way, that.way) &&
080                Objects.equals(newNodes, that.newNodes);
081    }
082}