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