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

Last change on this file was 10378, checked in by Don-vip, 13 days ago

Checkstyle 6.19: enable SingleSpaceSeparator and fix violations

  • 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    /**
30     * List of checks to run on data
31     */
32    private final List<FixData> deprecated = new LinkedList<>();
33
34    /**
35     * Constructor for data initialization
36     */
37    public FixDataHook() {
38        // CHECKSTYLE.OFF: SingleSpaceSeparator
39        deprecated.add(new FixDataSpace());
40        deprecated.add(new FixDataKey("color",            "colour"));
41        deprecated.add(new FixDataTag("highway", "ford",  "ford",    "yes"));
42        deprecated.add(new FixDataTag("oneway",  "false", "oneway",  "no"));
43        deprecated.add(new FixDataTag("oneway",  "0",     "oneway",  "no"));
44        deprecated.add(new FixDataTag("oneway",  "true",  "oneway",  "yes"));
45        deprecated.add(new FixDataTag("oneway",  "1",     "oneway",  "yes"));
46        deprecated.add(new FixDataTag("highway", "stile", "barrier", "stile"));
47        // CHECKSTYLE.ON: SingleSpaceSeparator
48        deprecated.add(new FixData() {
49            @Override
50            public boolean fixKeys(Map<String, String> keys, OsmPrimitive 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    /**
61     * Common set of commands for data fixing
62     */
63    public interface FixData {
64        /**
65         * Checks if data needs to be fixed and change keys
66         *
67         * @param keys list of keys to be modified
68         * @param osm the object for type validation, don't use keys of it!
69         * @return <code>true</code> if keys have been modified
70         */
71        boolean fixKeys(Map<String, String> keys, OsmPrimitive osm);
72    }
73
74    /**
75     * Data fix to remove spaces at begin or end of tags
76     */
77    public static class FixDataSpace implements FixData {
78        @Override
79        public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
80            Map<String, String> newKeys = new HashMap<>(keys);
81            for (Entry<String, String> e : keys.entrySet()) {
82                String v = Tag.removeWhiteSpaces(e.getValue());
83                String k = Tag.removeWhiteSpaces(e.getKey());
84                boolean drop = k.isEmpty() || v.isEmpty();
85                if (!e.getKey().equals(k)) {
86                    if (drop || !keys.containsKey(k)) {
87                        newKeys.put(e.getKey(), null);
88                        if (!drop)
89                            newKeys.put(k, v);
90                    }
91                } else if (!e.getValue().equals(v)) {
92                    newKeys.put(k, v.isEmpty() ? null : v);
93                } else if (drop) {
94                    newKeys.put(e.getKey(), null);
95                }
96            }
97            boolean changed = !keys.equals(newKeys);
98            if (changed) {
99                keys.clear();
100                keys.putAll(newKeys);
101            }
102            return changed;
103        }
104    }
105
106    /**
107     * Data fix to cleanup wrong spelled keys
108     */
109    public static class FixDataKey implements FixData {
110        /** key of wrong data */
111        private final String oldKey;
112        /** key of correct data */
113        private final String newKey;
114
115        /**
116         * Setup key check for wrong spelled keys
117         *
118         * @param oldKey wrong spelled key
119         * @param newKey correct replacement
120         */
121        public FixDataKey(String oldKey, String newKey) {
122            this.oldKey = oldKey;
123            this.newKey = newKey;
124        }
125
126        @Override
127        public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
128            if (keys.containsKey(oldKey) && !keys.containsKey(newKey)) {
129                keys.put(newKey, keys.get(oldKey));
130                keys.put(oldKey, null);
131                return true;
132            } else if (keys.containsKey(oldKey) && keys.containsKey(newKey) && keys.get(oldKey).equals(keys.get(newKey))) {
133                keys.put(oldKey, null);
134                return true;
135            }
136            return false;
137        }
138    }
139
140    /**
141     * Data fix to cleanup wrong spelled tags
142     */
143    public static class FixDataTag implements FixData {
144        /** key of wrong data */
145        private final String oldKey;
146        /** value of wrong data */
147        private final String oldValue;
148        /** key of correct data */
149        private final String newKey;
150        /** value of correct data */
151        private final String newValue;
152
153        /**
154         * Setup key check for wrong spelled keys
155         *
156         * @param oldKey wrong or old key
157         * @param oldValue wrong or old value
158         * @param newKey correct key replacement
159         * @param newValue correct value replacement
160         */
161        public FixDataTag(String oldKey, String oldValue, String newKey, String newValue) {
162            this.oldKey = oldKey;
163            this.oldValue = oldValue;
164            this.newKey = newKey;
165            this.newValue = newValue;
166        }
167
168        @Override
169        public boolean fixKeys(Map<String, String> keys, OsmPrimitive osm) {
170            if (oldValue.equals(keys.get(oldKey)) && (newKey.equals(oldKey)
171            || !keys.containsKey(newKey) || keys.get(newKey).equals(newValue))) {
172                keys.put(newKey, newValue);
173                if (!newKey.equals(oldKey))
174                    keys.put(oldKey, null);
175                return true;
176            }
177            return false;
178        }
179    }
180
181    /**
182     * Checks the upload for deprecated or wrong tags.
183     * @param apiDataSet the data to upload
184     */
185    @Override
186    public boolean checkUpload(APIDataSet apiDataSet) {
187        if (!Main.pref.getBoolean("fix.data.on.upload", true))
188            return true;
189
190        List<OsmPrimitive> objectsToUpload = apiDataSet.getPrimitives();
191        Collection<Command> cmds = new LinkedList<>();
192
193        for (OsmPrimitive osm : objectsToUpload) {
194            Map<String, String> keys = new HashMap<>(osm.getKeys());
195            if (!keys.isEmpty()) {
196                boolean modified = false;
197                for (FixData fix : deprecated) {
198                    if (fix.fixKeys(keys, osm))
199                        modified = true;
200                }
201                if (modified)
202                    cmds.add(new ChangePropertyCommand(Collections.singleton(osm), keys));
203            }
204        }
205
206        if (!cmds.isEmpty())
207            Main.main.undoRedo.add(new SequenceCommand(tr("Fix deprecated tags"), cmds));
208        return true;
209    }
210}
Note: See TracBrowser for help on using the repository browser.