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}