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