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

Last change on this file since 8338 was 8338, checked in by Don-vip, 11 years ago

fix squid:S1319 - Declarations should use Java collection interfaces rather than specific implementation classes

  • Property svn:eol-style set to native
File size: 8.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.command;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.Collection;
11import java.util.Collections;
12import java.util.HashMap;
13import java.util.LinkedList;
14import java.util.List;
15import java.util.Map;
16
17import javax.swing.Icon;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.data.osm.OsmPrimitive;
21import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
22import org.openstreetmap.josm.gui.DefaultNameFormatter;
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.
28 *
29 * @author imi
30 */
31public class ChangePropertyCommand extends Command {
32 /**
33 * All primitives that are affected with this command.
34 */
35 private final List<OsmPrimitive> objects;
36 /**
37 * Key and value pairs. If value is <code>null</code>, delete all key references with the given
38 * key. Otherwise, change the tags of all objects to the given value or create keys of
39 * those objects that do not have the key yet.
40 */
41 private final Map<String, String> tags;
42
43 /**
44 * Creates a command to change multiple tags of multiple objects
45 *
46 * @param objects the objects to modify
47 * @param tags the tags to set
48 */
49 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, Map<String, String> tags) {
50 this.objects = new LinkedList<>();
51 this.tags = tags;
52 init(objects);
53 }
54
55 /**
56 * Creates a command to change one tag of multiple objects
57 *
58 * @param objects the objects to modify
59 * @param key the key of the tag to set
60 * @param value the value of the key to set
61 */
62 public ChangePropertyCommand(Collection<? extends OsmPrimitive> objects, String key, String value) {
63 this.objects = new LinkedList<>();
64 this.tags = new HashMap<>(1);
65 this.tags.put(key, value);
66 init(objects);
67 }
68
69 /**
70 * Creates a command to change one tag of one object
71 *
72 * @param object the object to modify
73 * @param key the key of the tag to set
74 * @param value the value of the key to set
75 */
76 public ChangePropertyCommand(OsmPrimitive object, String key, String value) {
77 this(Arrays.asList(object), key, value);
78 }
79
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;
99 }
100 else if (oldVal == null || !newVal.equals(oldVal))
101 // new value is not null and is different from current value
102 modified = true;
103 }
104 if (modified)
105 this.objects.add(osm);
106 }
107 }
108
109 @Override public boolean executeCommand() {
110 Main.main.getCurrentDataSet().beginUpdate();
111 try {
112 super.executeCommand(); // save old
113
114 for (OsmPrimitive osm : objects) {
115 // loop over all tags
116 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
117 String oldVal = osm.get(tag.getKey());
118 String newVal = tag.getValue();
119
120 if (newVal == null || newVal.isEmpty()) {
121 if (oldVal != null)
122 osm.remove(tag.getKey());
123 }
124 else if (oldVal == null || !newVal.equals(oldVal))
125 osm.put(tag.getKey(), newVal);
126 }
127 // init() only keeps modified primitives. Therefore the modified
128 // bit can be set without further checks.
129 osm.setModified(true);
130 }
131 return true;
132 }
133 finally {
134 Main.main.getCurrentDataSet().endUpdate();
135 }
136 }
137
138 @Override public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
139 modified.addAll(objects);
140 }
141
142 @Override
143 public String getDescriptionText() {
144 String text;
145 if (objects.size() == 1 && tags.size() == 1) {
146 OsmPrimitive primitive = objects.iterator().next();
147 String msg = "";
148 Map.Entry<String, String> entry = tags.entrySet().iterator().next();
149 if (entry.getValue() == null) {
150 switch(OsmPrimitiveType.from(primitive)) {
151 case NODE: msg = marktr("Remove \"{0}\" for node ''{1}''"); break;
152 case WAY: msg = marktr("Remove \"{0}\" for way ''{1}''"); break;
153 case RELATION: msg = marktr("Remove \"{0}\" for relation ''{1}''"); break;
154 }
155 text = tr(msg, entry.getKey(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
156 } else {
157 switch(OsmPrimitiveType.from(primitive)) {
158 case NODE: msg = marktr("Set {0}={1} for node ''{2}''"); break;
159 case WAY: msg = marktr("Set {0}={1} for way ''{2}''"); break;
160 case RELATION: msg = marktr("Set {0}={1} for relation ''{2}''"); break;
161 }
162 text = tr(msg, entry.getKey(), entry.getValue(), primitive.getDisplayName(DefaultNameFormatter.getInstance()));
163 }
164 } else if (objects.size() > 1 && tags.size() == 1) {
165 Map.Entry<String, String> entry = tags.entrySet().iterator().next();
166 if (entry.getValue() == null) {
167 /* I18n: plural form for objects, but value < 2 not possible! */
168 text = trn("Remove \"{0}\" for {1} object", "Remove \"{0}\" for {1} objects", objects.size(), entry.getKey(), objects.size());
169 } else {
170 /* I18n: plural form for objects, but value < 2 not possible! */
171 text = trn("Set {0}={1} for {2} object", "Set {0}={1} for {2} objects", objects.size(), entry.getKey(), entry.getValue(), objects.size());
172 }
173 }
174 else {
175 boolean allnull = true;
176 for (Map.Entry<String, String> tag : this.tags.entrySet()) {
177 if (tag.getValue() != null) {
178 allnull = false;
179 break;
180 }
181 }
182
183 if (allnull) {
184 /* I18n: plural form detected for objects only (but value < 2 not possible!), try to do your best for tags */
185 text = trn("Deleted {0} tags for {1} object", "Deleted {0} tags for {1} objects", objects.size(), tags.size(), objects.size());
186 } else {
187 /* I18n: plural form detected for objects only (but value < 2 not possible!), try to do your best for tags */
188 text = trn("Set {0} tags for {1} object", "Set {0} tags for {1} objects", objects.size(), tags.size(), objects.size());
189 }
190 }
191 return text;
192 }
193
194 @Override
195 public Icon getDescriptionIcon() {
196 return ImageProvider.get("data", "key");
197 }
198
199 @Override public Collection<PseudoCommand> getChildren() {
200 if (objects.size() == 1)
201 return null;
202 List<PseudoCommand> children = new ArrayList<>();
203 for (final OsmPrimitive osm : objects) {
204 children.add(new PseudoCommand() {
205 @Override public String getDescriptionText() {
206 return osm.getDisplayName(DefaultNameFormatter.getInstance());
207 }
208
209 @Override public Icon getDescriptionIcon() {
210 return ImageProvider.get(osm.getDisplayType());
211 }
212
213 @Override public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
214 return Collections.singleton(osm);
215 }
216
217 });
218 }
219 return children;
220 }
221
222 /**
223 * Returns the tags to set (key/value pairs).
224 * @return the tags to set (key/value pairs)
225 */
226 public Map<String, String> getTags() {
227 return Collections.unmodifiableMap(tags);
228 }
229}
Note: See TracBrowser for help on using the repository browser.