source: josm/trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java@ 8792

Last change on this file since 8792 was 8509, checked in by Don-vip, 9 years ago

fix many checkstyle violations

  • Property svn:eol-style set to native
File size: 9.6 KB
RevLine 
[6380]1// License: GPL. For details, see LICENSE file.
[626]2package org.openstreetmap.josm.command;
3
[1990]4import static org.openstreetmap.josm.tools.I18n.marktr;
[626]5import static org.openstreetmap.josm.tools.I18n.tr;
[6507]6import static org.openstreetmap.josm.tools.I18n.trn;
[626]7
[3262]8import java.util.ArrayList;
[4302]9import java.util.Arrays;
[626]10import java.util.Collection;
[3262]11import java.util.Collections;
[4773]12import java.util.HashMap;
[626]13import java.util.LinkedList;
14import java.util.List;
[4773]15import java.util.Map;
[5077]16
[4918]17import javax.swing.Icon;
[626]18
[3910]19import org.openstreetmap.josm.Main;
[626]20import org.openstreetmap.josm.data.osm.OsmPrimitive;
[1814]21import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
[1990]22import org.openstreetmap.josm.gui.DefaultNameFormatter;
[626]23import org.openstreetmap.josm.tools.ImageProvider;
24
25/**
26 * Command that manipulate the key/value structure of several objects. Manages deletion,
27 * adding and modify of values and keys.
[1169]28 *
[626]29 * @author imi
30 */
31public class ChangePropertyCommand extends Command {
[1169]32 /**
33 * All primitives that are affected with this command.
34 */
35 private final List<OsmPrimitive> objects;
36 /**
[4773]37 * Key and value pairs. If value is <code>null</code>, delete all key references with the given
[6324]38 * key. Otherwise, change the tags of all objects to the given value or create keys of
[1169]39 * those objects that do not have the key yet.
40 */
[8338]41 private final Map<String, String> tags;
[628]42
[4773]43 /**
[6324]44 * Creates a command to change multiple tags of multiple objects
[4773]45 *
46 * @param objects the objects to modify
[6324]47 * @param tags the tags to set
[4773]48 */
[8338]49 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, Map<String, String> tags) {
[7005]50 this.objects = new LinkedList<>();
[4773]51 this.tags = tags;
52 init(objects);
[1169]53 }
[626]54
[4773]55 /**
[6324]56 * Creates a command to change one tag of multiple objects
[4773]57 *
58 * @param objects the objects to modify
[6324]59 * @param key the key of the tag to set
[4773]60 * @param value the value of the key to set
61 */
62 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) {
[7005]63 this.objects = new LinkedList<>();
64 this.tags = new HashMap<>(1);
[4773]65 this.tags.put(key, value);
66 init(objects);
67 }
68
69 /**
[6324]70 * Creates a command to change one tag of one object
[4773]71 *
72 * @param object the object to modify
[6324]73 * @param key the key of the tag to set
[4773]74 * @param value the value of the key to set
75 */
[1169]76 public ChangePropertyCommand(OsmPrimitive object, String key, String value) {
[4302]77 this(Arrays.asList(object), key, value);
[1169]78 }
[626]79
[4773]80 /**
81 * Initialize the instance by finding what objects will be modified
82 *
83 * @param objects the objects to (possibly) modify
84 */
85 private void init(Collection<? extends OsmPrimitive> objects) {
86 // determine what objects will be modified
87 for (OsmPrimitive osm : objects) {
88 boolean modified = false;
89
90 // loop over all tags
91 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
92 String oldVal = osm.get(tag.getKey());
93 String newVal = tag.getValue();
94
95 if (newVal == null || newVal.isEmpty()) {
96 if (oldVal != null)
97 // new value is null and tag exists (will delete tag)
98 modified = true;
[8342]99 } else if (oldVal == null || !newVal.equals(oldVal))
[4773]100 // new value is not null and is different from current value
101 modified = true;
102 }
103 if (modified)
104 this.objects.add(osm);
105 }
106 }
107
[1169]108 @Override public boolean executeCommand() {
[3910]109 Main.main.getCurrentDataSet().beginUpdate();
110 try {
111 super.executeCommand(); // save old
[4773]112
113 for (OsmPrimitive osm : objects) {
[5143]114 // loop over all tags
[4773]115 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
116 String oldVal = osm.get(tag.getKey());
117 String newVal = tag.getValue();
118
119 if (newVal == null || newVal.isEmpty()) {
[5143]120 if (oldVal != null)
[4773]121 osm.remove(tag.getKey());
[8342]122 } else if (oldVal == null || !newVal.equals(oldVal))
[4773]123 osm.put(tag.getKey(), newVal);
[3910]124 }
[5143]125 // init() only keeps modified primitives. Therefore the modified
126 // bit can be set without further checks.
127 osm.setModified(true);
[1169]128 }
[3910]129 return true;
[8342]130 } finally {
[3910]131 Main.main.getCurrentDataSet().endUpdate();
132 }
[626]133 }
[1169]134
135 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
136 modified.addAll(objects);
137 }
138
[4918]139 @Override
140 public String getDescriptionText() {
[1182]141 String text;
[4773]142 if (objects.size() == 1 && tags.size() == 1) {
[1814]143 OsmPrimitive primitive = objects.iterator().next();
[1989]144 String msg = "";
[4773]145 Map.Entry<String, String> entry = tags.entrySet().iterator().next();
146 if (entry.getValue() == null) {
[1989]147 switch(OsmPrimitiveType.from(primitive)) {
[2990]148 case NODE: msg = marktr("Remove \"{0}\" for node ''{1}''"); break;
149 case WAY: msg = marktr("Remove \"{0}\" for way ''{1}''"); break;
150 case RELATION: msg = marktr("Remove \"{0}\" for relation ''{1}''"); break;
[1989]151 }
[4773]152 text = tr(msg, entry.getKey(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
[1989]153 } else {
154 switch(OsmPrimitiveType.from(primitive)) {
[2990]155 case NODE: msg = marktr("Set {0}={1} for node ''{2}''"); break;
156 case WAY: msg = marktr("Set {0}={1} for way ''{2}''"); break;
157 case RELATION: msg = marktr("Set {0}={1} for relation ''{2}''"); break;
[1989]158 }
[4773]159 text = tr(msg, entry.getKey(), entry.getValue(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
[1989]160 }
[4773]161 } else if (objects.size() > 1 && tags.size() == 1) {
162 Map.Entry<String, String> entry = tags.entrySet().iterator().next();
[6507]163 if (entry.getValue() == null) {
[6679]164 /* I18n: plural form for objects, but value < 2 not possible! */
165 text = trn("Remove \"{0}\" for {1} object", "Remove \"{0}\" for {1} objects", objects.size(), entry.getKey(), objects.size());
[6507]166 } else {
[6679]167 /* I18n: plural form for objects, but value < 2 not possible! */
[8509]168 text = trn("Set {0}={1} for {2} object", "Set {0}={1} for {2} objects",
169 objects.size(), entry.getKey(), entry.getValue(), objects.size());
[6507]170 }
[8342]171 } else {
[4773]172 boolean allnull = true;
173 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
174 if (tag.getValue() != null) {
175 allnull = false;
176 break;
177 }
178 }
[5077]179
[4773]180 if (allnull) {
[6881]181 /* I18n: plural form detected for objects only (but value < 2 not possible!), try to do your best for tags */
[6679]182 text = trn("Deleted {0} tags for {1} object", "Deleted {0} tags for {1} objects", objects.size(), tags.size(), objects.size());
[6507]183 } else {
[6679]184 /* I18n: plural form detected for objects only (but value < 2 not possible!), try to do your best for tags */
185 text = trn("Set {0} tags for {1} object", "Set {0} tags for {1} objects", objects.size(), tags.size(), objects.size());
[6507]186 }
[4773]187 }
[4918]188 return text;
[3262]189 }
190
[4918]191 @Override
192 public Icon getDescriptionIcon() {
193 return ImageProvider.get("data", "key");
194 }
195
[3262]196 @Override public Collection<PseudoCommand> getChildren() {
[1169]197 if (objects.size() == 1)
[3262]198 return null;
[7005]199 List<PseudoCommand> children = new ArrayList<>();
[3262]200 for (final OsmPrimitive osm : objects) {
201 children.add(new PseudoCommand() {
[4918]202 @Override public String getDescriptionText() {
203 return osm.getDisplayName(DefaultNameFormatter.getInstance());
204 }
[3262]205
[4918]206 @Override public Icon getDescriptionIcon() {
[5077]207 return ImageProvider.get(osm.getDisplayType());
[3262]208 }
[4918]209
[3262]210 @Override public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
211 return Collections.singleton(osm);
212 }
213
214 });
[1169]215 }
[3262]216 return children;
[1169]217 }
[6538]218
[6881]219 /**
220 * Returns the tags to set (key/value pairs).
221 * @return the tags to set (key/value pairs)
222 */
[6538]223 public Map<String, String> getTags() {
224 return Collections.unmodifiableMap(tags);
225 }
[8456]226
227 @Override
228 public int hashCode() {
229 final int prime = 31;
230 int result = super.hashCode();
231 result = prime * result + ((objects == null) ? 0 : objects.hashCode());
232 result = prime * result + ((tags == null) ? 0 : tags.hashCode());
233 return result;
234 }
235
236 @Override
237 public boolean equals(Object obj) {
238 if (this == obj)
239 return true;
240 if (!super.equals(obj))
241 return false;
242 if (getClass() != obj.getClass())
243 return false;
244 ChangePropertyCommand other = (ChangePropertyCommand) obj;
245 if (objects == null) {
246 if (other.objects != null)
247 return false;
248 } else if (!objects.equals(other.objects))
249 return false;
250 if (tags == null) {
251 if (other.tags != null)
252 return false;
253 } else if (!tags.equals(other.tags))
254 return false;
255 return true;
256 }
[626]257}
Note: See TracBrowser for help on using the repository browser.