001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.command; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005import static org.openstreetmap.josm.tools.I18n.trn; 006 007import java.util.ArrayList; 008import java.util.Collection; 009import java.util.Collections; 010import java.util.LinkedList; 011import java.util.List; 012import java.util.Objects; 013 014import javax.swing.Icon; 015 016import org.openstreetmap.josm.data.osm.OsmPrimitive; 017import org.openstreetmap.josm.data.validation.util.NameVisitor; 018import org.openstreetmap.josm.tools.ImageProvider; 019 020/** 021 * Command that replaces the key of one or several objects 022 * 023 */ 024public class ChangePropertyKeyCommand extends Command { 025 /** 026 * All primitives, that are affected with this command. 027 */ 028 private final List<? extends OsmPrimitive> objects; 029 /** 030 * The key that is subject to change. 031 */ 032 private final String key; 033 /** 034 * The mew key. 035 */ 036 private final String newKey; 037 038 /** 039 * Constructs a new {@code ChangePropertyKeyCommand}. 040 * 041 * @param object the object subject to change replacement 042 * @param key The key to replace 043 * @param newKey the new value of the key 044 * @since 6329 045 */ 046 public ChangePropertyKeyCommand(OsmPrimitive object, String key, String newKey) { 047 this(Collections.singleton(object), key, newKey); 048 } 049 050 /** 051 * Constructs a new {@code ChangePropertyKeyCommand}. 052 * 053 * @param objects all objects subject to change replacement 054 * @param key The key to replace 055 * @param newKey the new value of the key 056 */ 057 public ChangePropertyKeyCommand(Collection<? extends OsmPrimitive> objects, String key, String newKey) { 058 this.objects = new LinkedList<>(objects); 059 this.key = key; 060 this.newKey = newKey; 061 } 062 063 @Override 064 public boolean executeCommand() { 065 if (!super.executeCommand()) 066 return false; // save old 067 for (OsmPrimitive osm : objects) { 068 if (osm.hasKeys()) { 069 osm.setModified(true); 070 String oldValue = osm.get(key); 071 osm.put(newKey, oldValue); 072 osm.remove(key); 073 } 074 } 075 return true; 076 } 077 078 @Override 079 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 080 modified.addAll(objects); 081 } 082 083 @Override 084 public String getDescriptionText() { 085 String text = tr("Replace \"{0}\" by \"{1}\" for", key, newKey); 086 if (objects.size() == 1) { 087 NameVisitor v = new NameVisitor(); 088 objects.get(0).accept(v); 089 text += ' '+tr(v.className)+' '+v.name; 090 } else { 091 text += ' '+objects.size()+' '+trn("object", "objects", objects.size()); 092 } 093 return text; 094 } 095 096 @Override 097 public Icon getDescriptionIcon() { 098 return ImageProvider.get("data", "key"); 099 } 100 101 @Override 102 public Collection<PseudoCommand> getChildren() { 103 if (objects.size() == 1) 104 return null; 105 List<PseudoCommand> children = new ArrayList<>(); 106 107 final NameVisitor v = new NameVisitor(); 108 for (final OsmPrimitive osm : objects) { 109 osm.accept(v); 110 children.add(new PseudoCommand() { 111 @Override 112 public String getDescriptionText() { 113 return v.name; 114 } 115 116 @Override 117 public Icon getDescriptionIcon() { 118 return v.icon; 119 } 120 121 @Override 122 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() { 123 return Collections.singleton(osm); 124 } 125 }); 126 } 127 return children; 128 } 129 130 @Override 131 public int hashCode() { 132 return Objects.hash(super.hashCode(), objects, key, newKey); 133 } 134 135 @Override 136 public boolean equals(Object obj) { 137 if (this == obj) return true; 138 if (obj == null || getClass() != obj.getClass()) return false; 139 if (!super.equals(obj)) return false; 140 ChangePropertyKeyCommand that = (ChangePropertyKeyCommand) obj; 141 return Objects.equals(objects, that.objects) && 142 Objects.equals(key, that.key) && 143 Objects.equals(newKey, that.newKey); 144 } 145}