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