source: josm/trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueResolutionDecision.java@ 7801

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

fix some Sonar issues

  • Property svn:eol-style set to native
File size: 10.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.conflict.tags;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.text.MessageFormat;
7import java.util.ArrayList;
8import java.util.Collection;
9import java.util.Collections;
10import java.util.List;
11
12import org.openstreetmap.josm.command.ChangePropertyCommand;
13import org.openstreetmap.josm.command.Command;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.data.osm.Tag;
16import org.openstreetmap.josm.data.osm.TagCollection;
17import org.openstreetmap.josm.tools.CheckParameterUtil;
18
19/**
20 * Represents a decision for a conflict due to multiple possible value for a tag.
21 * @since 2008
22 */
23public class MultiValueResolutionDecision {
24
25 /** the type of decision */
26 private MultiValueDecisionType type;
27 /** the collection of tags for which a decision is needed */
28 private TagCollection tags;
29 /** the selected value if {@link #type} is {@link MultiValueDecisionType#KEEP_ONE} */
30 private String value;
31
32 private static final String[] SUMMABLE_KEYS = new String[] {
33 "capacity(:.+)?", "step_count"
34 };
35
36 /**
37 * constructor
38 */
39 public MultiValueResolutionDecision() {
40 type = MultiValueDecisionType.UNDECIDED;
41 tags = new TagCollection();
42 autoDecide();
43 }
44
45 /**
46 * Creates a new decision for the tag collection <code>tags</code>.
47 * All tags must have the same key.
48 *
49 * @param tags the tags. Must not be null.
50 * @exception IllegalArgumentException thrown if tags is null
51 * @exception IllegalArgumentException thrown if there are more than one keys
52 * @exception IllegalArgumentException thrown if tags is empty
53 */
54 public MultiValueResolutionDecision(TagCollection tags) throws IllegalArgumentException {
55 CheckParameterUtil.ensureParameterNotNull(tags, "tags");
56 if (tags.isEmpty())
57 throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' must not be empty.", "tags"));
58 if (tags.getKeys().size() != 1)
59 throw new IllegalArgumentException(MessageFormat.format("Parameter ''{0}'' with tags for exactly one key expected. Got {1}.", "tags", tags.getKeys().size()));
60 this.tags = tags;
61 autoDecide();
62 }
63
64 /**
65 * Tries to find the best decision based on the current values.
66 */
67 protected final void autoDecide() {
68 this.type = MultiValueDecisionType.UNDECIDED;
69 // exactly one empty value ? -> delete the tag
70 if (tags.size() == 1 && tags.getValues().contains("")) {
71 this.type = MultiValueDecisionType.KEEP_NONE;
72
73 // exactly one non empty value? -> keep this value
74 } else if (tags.size() == 1) {
75 this.type = MultiValueDecisionType.KEEP_ONE;
76 this.value = tags.getValues().iterator().next();
77 }
78 }
79
80 /**
81 * Apply the decision to keep no value
82 */
83 public void keepNone() {
84 this.type = MultiValueDecisionType.KEEP_NONE;
85 }
86
87 /**
88 * Apply the decision to keep all values
89 */
90 public void keepAll() {
91 this.type = MultiValueDecisionType.KEEP_ALL;
92 }
93
94 /**
95 * Apply the decision to sum all numeric values
96 * @since 7743
97 */
98 public void sumAllNumeric() {
99 this.type = MultiValueDecisionType.SUM_ALL_NUMERIC;
100 }
101
102 /**
103 * Apply the decision to keep exactly one value
104 *
105 * @param value the value to keep
106 * @throws IllegalArgumentException thrown if value is null
107 * @throws IllegalStateException thrown if value is not in the list of known values for this tag
108 */
109 public void keepOne(String value) throws IllegalArgumentException, IllegalStateException {
110 CheckParameterUtil.ensureParameterNotNull(value, "value");
111 if (!tags.getValues().contains(value))
112 throw new IllegalStateException(tr("Tag collection does not include the selected value ''{0}''.", value));
113 this.value = value;
114 this.type = MultiValueDecisionType.KEEP_ONE;
115 }
116
117 /**
118 * sets a new value for this
119 *
120 * @param value the new vlaue
121 */
122 public void setNew(String value) {
123 if (value == null) {
124 value = "";
125 }
126 this.value = value;
127 this.type = MultiValueDecisionType.KEEP_ONE;
128
129 }
130
131 /**
132 * marks this as undecided
133 *
134 */
135 public void undecide() {
136 this.type = MultiValueDecisionType.UNDECIDED;
137 }
138
139 /**
140 * Replies the chosen value
141 *
142 * @return the chosen value
143 * @throws IllegalStateException thrown if this resolution is not yet decided
144 */
145 public String getChosenValue() throws IllegalStateException {
146 switch(type) {
147 case UNDECIDED: throw new IllegalStateException(tr("Not decided yet."));
148 case KEEP_ONE: return value;
149 case SUM_ALL_NUMERIC: return tags.getSummedValues(getKey());
150 case KEEP_ALL: return tags.getJoinedValues(getKey());
151 case KEEP_NONE:
152 default: return null;
153 }
154 }
155
156 /**
157 * Replies the list of possible, non empty values
158 *
159 * @return the list of possible, non empty values
160 */
161 public List<String> getValues() {
162 List<String> ret = new ArrayList<>(tags.getValues());
163 ret.remove("");
164 ret.remove(null);
165 Collections.sort(ret);
166 return ret;
167 }
168
169 /**
170 * Replies the key of the tag to be resolved by this resolution
171 *
172 * @return the key of the tag to be resolved by this resolution
173 */
174 public String getKey() {
175 return tags.getKeys().iterator().next();
176 }
177
178 /**
179 * Replies true if the empty value is a possible value in this resolution
180 *
181 * @return true if the empty value is a possible value in this resolution
182 */
183 public boolean canKeepNone() {
184 return tags.getValues().contains("");
185 }
186
187 /**
188 * Replies true, if this resolution has more than 1 possible non-empty values
189 *
190 * @return true, if this resolution has more than 1 possible non-empty values
191 */
192 public boolean canKeepAll() {
193 return getValues().size() > 1;
194 }
195
196 /**
197 * Replies true, if summing all numeric values is a possible value in this resolution
198 *
199 * @return true, if summing all numeric values is a possible value in this resolution
200 * @since 7743
201 */
202 public boolean canSumAllNumeric() {
203 if (!canKeepAll()) {
204 return false;
205 }
206 for (String key : SUMMABLE_KEYS) {
207 if (getKey().matches(key)) {
208 return true;
209 }
210 }
211 return false;
212 }
213
214 /**
215 * Replies true if this resolution is decided
216 *
217 * @return true if this resolution is decided
218 */
219 public boolean isDecided() {
220 return !type.equals(MultiValueDecisionType.UNDECIDED);
221 }
222
223 /**
224 * Replies the type of the resolution
225 *
226 * @return the type of the resolution
227 */
228 public MultiValueDecisionType getDecisionType() {
229 return type;
230 }
231
232 /**
233 * Applies the resolution to an {@link OsmPrimitive}
234 *
235 * @param primitive the primitive
236 * @throws IllegalStateException thrown if this resolution is not resolved yet
237 *
238 */
239 public void applyTo(OsmPrimitive primitive) {
240 if (primitive == null) return;
241 if (!isDecided())
242 throw new IllegalStateException(tr("Not decided yet."));
243 String key = tags.getKeys().iterator().next();
244 if (type.equals(MultiValueDecisionType.KEEP_NONE)) {
245 primitive.remove(key);
246 } else {
247 primitive.put(key, getChosenValue());
248 }
249 }
250
251 /**
252 * Applies this resolution to a collection of primitives
253 *
254 * @param primitives the collection of primitives
255 * @throws IllegalStateException thrown if this resolution is not resolved yet
256 */
257 public void applyTo(Collection<? extends OsmPrimitive> primitives) {
258 if (primitives == null) return;
259 for (OsmPrimitive primitive: primitives) {
260 if (primitive == null) {
261 continue;
262 }
263 applyTo(primitive);
264 }
265 }
266
267 /**
268 * Builds a change command for applying this resolution to a primitive
269 *
270 * @param primitive the primitive
271 * @return the change command
272 * @throws IllegalArgumentException thrown if primitive is null
273 * @throws IllegalStateException thrown if this resolution is not resolved yet
274 */
275 public Command buildChangeCommand(OsmPrimitive primitive) {
276 CheckParameterUtil.ensureParameterNotNull(primitive, "primitive");
277 if (!isDecided())
278 throw new IllegalStateException(tr("Not decided yet."));
279 String key = tags.getKeys().iterator().next();
280 return new ChangePropertyCommand(primitive, key, getChosenValue());
281 }
282
283 /**
284 * Builds a change command for applying this resolution to a collection of primitives
285 *
286 * @param primitives the collection of primitives
287 * @return the change command
288 * @throws IllegalArgumentException thrown if primitives is null
289 * @throws IllegalStateException thrown if this resolution is not resolved yet
290 */
291 public Command buildChangeCommand(Collection<? extends OsmPrimitive> primitives) {
292 CheckParameterUtil.ensureParameterNotNull(primitives, "primitives");
293 if (!isDecided())
294 throw new IllegalStateException(tr("Not decided yet."));
295 String key = tags.getKeys().iterator().next();
296 return new ChangePropertyCommand(primitives, key, getChosenValue());
297 }
298
299 /**
300 * Replies a tag representing the current resolution. Null, if this resolution is not resolved yet.
301 *
302 * @return a tag representing the current resolution. Null, if this resolution is not resolved yet
303 */
304 public Tag getResolution() {
305 switch(type) {
306 case SUM_ALL_NUMERIC: return new Tag(getKey(), tags.getSummedValues(getKey()));
307 case KEEP_ALL: return new Tag(getKey(), tags.getJoinedValues(getKey()));
308 case KEEP_ONE: return new Tag(getKey(),value);
309 case KEEP_NONE: return new Tag(getKey(), "");
310 case UNDECIDED:
311 default: return null;
312 }
313 }
314}
Note: See TracBrowser for help on using the repository browser.