001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.command;
003
004import static org.openstreetmap.josm.tools.I18n.marktr;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.util.Collection;
008
009import javax.swing.Icon;
010
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.gui.DefaultNameFormatter;
015import org.openstreetmap.josm.gui.layer.OsmDataLayer;
016import org.openstreetmap.josm.tools.CheckParameterUtil;
017import org.openstreetmap.josm.tools.ImageProvider;
018
019/**
020 * Command that basically replaces one OSM primitive by another of the same type.
021 *
022 * @since 93
023 */
024public class ChangeCommand extends Command {
025
026    private final OsmPrimitive osm;
027    private final OsmPrimitive newOsm;
028
029    public ChangeCommand(OsmPrimitive osm, OsmPrimitive newOsm) {
030        super();
031        this.osm = osm;
032        this.newOsm = newOsm;
033        sanityChecks();
034    }
035
036    public ChangeCommand(OsmDataLayer layer, OsmPrimitive osm, OsmPrimitive newOsm) {
037        super(layer);
038        this.osm = osm;
039        this.newOsm = newOsm;
040        sanityChecks();
041    }
042    
043    private void sanityChecks() {
044        CheckParameterUtil.ensureParameterNotNull(osm, "osm");
045        CheckParameterUtil.ensureParameterNotNull(newOsm, "newOsm");
046        if (newOsm instanceof Way && ((Way)newOsm).getNodesCount() == 0) {
047            // Do not allow to create empty ways (see #7465)
048            throw new IllegalArgumentException(tr("New way {0} has 0 nodes", newOsm));
049        }
050    }
051
052    @Override
053    public boolean executeCommand() {
054        super.executeCommand();
055        osm.cloneFrom(newOsm);
056        osm.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(osm);
063    }
064
065    @Override
066    public String getDescriptionText() {
067        String msg = "";
068        switch(OsmPrimitiveType.from(osm)) {
069        case NODE: msg = marktr("Change node {0}"); break;
070        case WAY: msg = marktr("Change way {0}"); break;
071        case RELATION: msg = marktr("Change relation {0}"); break;
072        }
073        return tr(msg, osm.getDisplayName(DefaultNameFormatter.getInstance()));
074    }
075
076    @Override
077    public Icon getDescriptionIcon() {
078        return ImageProvider.get(osm.getDisplayType());
079    }
080}