source: josm/trunk/src/org/openstreetmap/josm/actions/upload/FixDataHook.java@ 12346

Last change on this file since 12346 was 12288, checked in by Don-vip, 7 years ago

sonar - squid:S3516 - Methods returns should not be invariant

  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.upload;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Collection;
7import java.util.Collections;
8import java.util.HashMap;
9import java.util.LinkedList;
10import java.util.List;
11import java.util.Map;
12import java.util.Map.Entry;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.command.ChangePropertyCommand;
16import org.openstreetmap.josm.command.Command;
17import org.openstreetmap.josm.command.SequenceCommand;
18import org.openstreetmap.josm.data.APIDataSet;
19import org.openstreetmap.josm.data.osm.OsmPrimitive;
20import org.openstreetmap.josm.data.osm.Relation;
21import org.openstreetmap.josm.data.osm.Tag;
22
23/**
24 * Fixes defective data entries for all modified objects before upload
25 * @since 5621
26 */
27public class FixDataHook implements UploadHook {
28
29 private static final String ONEWAY = "oneway";
30
31 /**
32 * List of checks to run on data
33 */
34 private final List<FixData> deprecated = new LinkedList<>();
35
36 /**
37 * Constructor for data initialization
38 */
39 public FixDataHook() {
40 // CHECKSTYLE.OFF: SingleSpaceSeparator
41 deprecated.add(new FixDataSpace());
42 deprecated.add(new FixDataKey("color", "colour"));
43 deprecated.add(new FixDataTag("highway", "ford", "ford", "yes"));
44 deprecated.add(new FixDataTag(ONEWAY, "false", ONEWAY, "no"));
45 deprecated.add(new FixDataTag(ONEWAY, "0", ONEWAY, "no"));
46 deprecated.add(new FixDataTag(ONEWAY, "true", ONEWAY, "yes"));
47 deprecated.add(new FixDataTag(ONEWAY, "1", ONEWAY, "yes"));
48 deprecated.add(new FixDataTag("highway", "stile", "barrier", "stile"));
49 // CHECKSTYLE.ON: SingleSpaceSeparator
50 deprecated.add((keys, osm) -> {
51 if (osm instanceof Relation && "multipolygon".equals(keys.get("type")) && "administrative".equals(keys.get("boundary"))) {
52 keys.put("type", "boundary");
53 return true;
54 }
55 return false;
56 });
57 }
58
59 /**
60 * Common set of commands for data fixing
61 * @since 10600 (functional interface)
62 */
63 @FunctionalInterface
64 public interface FixData {
65 /**
66 * Checks if data needs to be fixed and change keys
67 *
68 * @param keys list of keys to be modified
69 * @param osm the object for type validation, don't use keys of it!
70 * @return <code>true</code> if keys have been modified
71 */
72 boolean fixKeys(Map<String, String> keys, OsmPrimitive osm);
73 }
74
75 /**
76 * Data fix to remove spaces at begin or end of tags
77 */
78 public static class FixDataSpace implements FixData {
79 @Override
80 public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
81 Map<String, String> newKeys = new HashMap<>(keys);
82 for (Entry<String, String> e : keys.entrySet()) {
83 String v = Tag.removeWhiteSpaces(e.getValue());
84 String k = Tag.removeWhiteSpaces(e.getKey());
85 boolean drop = k.isEmpty() || v.isEmpty();
86 if (!e.getKey().equals(k)) {
87 if (drop || !keys.containsKey(k)) {
88 newKeys.put(e.getKey(), null);
89 if (!drop)
90 newKeys.put(k, v);
91 }
92 } else if (!e.getValue().equals(v)) {
93 newKeys.put(k, v.isEmpty() ? null : v);
94 } else if (drop) {
95 newKeys.put(e.getKey(), null);
96 }
97 }
98 boolean changed = !keys.equals(newKeys);
99 if (changed) {
100 keys.clear();
101 keys.putAll(newKeys);
102 }
103 return changed;
104 }
105 }
106
107 /**
108 * Data fix to cleanup wrong spelled keys
109 */
110 public static class FixDataKey implements FixData {
111 /** key of wrong data */
112 private final String oldKey;
113 /** key of correct data */
114 private final String newKey;
115
116 /**
117 * Setup key check for wrong spelled keys
118 *
119 * @param oldKey wrong spelled key
120 * @param newKey correct replacement
121 */
122 public FixDataKey(String oldKey, String newKey) {
123 this.oldKey = oldKey;
124 this.newKey = newKey;
125 }
126
127 @Override
128 public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
129 if (keys.containsKey(oldKey) && !keys.containsKey(newKey)) {
130 keys.put(newKey, keys.get(oldKey));
131 keys.put(oldKey, null);
132 return true;
133 } else if (keys.containsKey(oldKey) && keys.containsKey(newKey) && keys.get(oldKey).equals(keys.get(newKey))) {
134 keys.put(oldKey, null);
135 return true;
136 }
137 return false;
138 }
139 }
140
141 /**
142 * Data fix to cleanup wrong spelled tags
143 */
144 public static class FixDataTag implements FixData {
145 /** key of wrong data */
146 private final String oldKey;
147 /** value of wrong data */
148 private final String oldValue;
149 /** key of correct data */
150 private final String newKey;
151 /** value of correct data */
152 private final String newValue;
153
154 /**
155 * Setup key check for wrong spelled keys
156 *
157 * @param oldKey wrong or old key
158 * @param oldValue wrong or old value
159 * @param newKey correct key replacement
160 * @param newValue correct value replacement
161 */
162 public FixDataTag(String oldKey, String oldValue, String newKey, String newValue) {
163 this.oldKey = oldKey;
164 this.oldValue = oldValue;
165 this.newKey = newKey;
166 this.newValue = newValue;
167 }
168
169 @Override
170 public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
171 if (oldValue.equals(keys.get(oldKey)) && (newKey.equals(oldKey)
172 || !keys.containsKey(newKey) || keys.get(newKey).equals(newValue))) {
173 keys.put(newKey, newValue);
174 if (!newKey.equals(oldKey))
175 keys.put(oldKey, null);
176 return true;
177 }
178 return false;
179 }
180 }
181
182 /**
183 * Checks the upload for deprecated or wrong tags.
184 * @param apiDataSet the data to upload
185 */
186 @Override
187 public boolean checkUpload(APIDataSet apiDataSet) {
188 if (Main.pref.getBoolean("fix.data.on.upload", true)) {
189 Collection<Command> cmds = new LinkedList<>();
190
191 for (OsmPrimitive osm : apiDataSet.getPrimitives()) {
192 Map<String, String> keys = new HashMap<>(osm.getKeys());
193 if (!keys.isEmpty()) {
194 boolean modified = false;
195 for (FixData fix : deprecated) {
196 if (fix.fixKeys(keys, osm))
197 modified = true;
198 }
199 if (modified) {
200 cmds.add(new ChangePropertyCommand(Collections.singleton(osm), keys));
201 }
202 }
203 }
204
205 if (!cmds.isEmpty()) {
206 Main.main.undoRedo.add(new SequenceCommand(tr("Fix deprecated tags"), cmds));
207 }
208 }
209 return true;
210 }
211}
Note: See TracBrowser for help on using the repository browser.