001 package org.openstreetmap.josm.data.validation.tests; 002 003 import static org.openstreetmap.josm.tools.I18n.tr; 004 005 import java.util.Collection; 006 import java.util.LinkedList; 007 import java.util.List; 008 009 import org.openstreetmap.josm.command.ChangePropertyCommand; 010 import org.openstreetmap.josm.command.Command; 011 import org.openstreetmap.josm.command.SequenceCommand; 012 import org.openstreetmap.josm.data.osm.Node; 013 import org.openstreetmap.josm.data.osm.OsmPrimitive; 014 import org.openstreetmap.josm.data.osm.Relation; 015 import org.openstreetmap.josm.data.osm.Tag; 016 import org.openstreetmap.josm.data.osm.Way; 017 import org.openstreetmap.josm.data.validation.Severity; 018 import org.openstreetmap.josm.data.validation.Test; 019 import org.openstreetmap.josm.data.validation.TestError; 020 import org.openstreetmap.josm.tools.Utils; 021 022 public class DeprecatedTags extends Test { 023 024 private List<DeprecationCheck> checks = new LinkedList<DeprecationCheck>(); 025 026 public DeprecatedTags() { 027 super(tr("Deprecated Tags"), tr("Checks and corrects deprecated tags.")); 028 checks.add(new DeprecationCheck(2101). 029 testAndRemove("barrier", "wire_fence"). 030 add("barrier", "fence"). 031 add("fence_type", "chain")); 032 checks.add(new DeprecationCheck(2102). 033 testAndRemove("barrier", "wood_fence"). 034 add("barrier", "fence"). 035 add("fence_type", "wood")); 036 checks.add(new DeprecationCheck(2103). 037 testAndRemove("highway", "ford"). 038 add("ford", "yes")); 039 // from http://wiki.openstreetmap.org/wiki/Deprecated_features 040 checks.add(new DeprecationCheck(2104). 041 test("class"). 042 alternative("highway")); 043 checks.add(new DeprecationCheck(2105). 044 testAndRemove("highway", "stile"). 045 add("barrier", "stile")); 046 checks.add(new DeprecationCheck(2106). 047 testAndRemove("highway", "incline"). 048 add("highway", "road"). 049 add("incline", "up")); 050 checks.add(new DeprecationCheck(2107). 051 testAndRemove("highway", "incline_steep"). 052 add("highway", "road"). 053 add("incline", "up")); 054 checks.add(new DeprecationCheck(2108). 055 testAndRemove("highway", "unsurfaced"). 056 add("highway", "road"). 057 add("incline", "unpaved")); 058 checks.add(new DeprecationCheck(2109). 059 test("landuse", "wood"). 060 alternative("landuse", "forest"). 061 alternative("natural", "wood")); 062 checks.add(new DeprecationCheck(2110). 063 testAndRemove("natural", "marsh"). 064 add("natural", "wetland"). 065 add("wetland", "marsh")); 066 checks.add(new DeprecationCheck(2111). 067 test("highway", "byway")); 068 checks.add(new DeprecationCheck(2112). 069 test("power_source"). 070 alternative("generator:source")); 071 checks.add(new DeprecationCheck(2113). 072 test("power_rating"). 073 alternative("generator:output")); 074 // from http://wiki.openstreetmap.org/wiki/Tag:shop%3Dorganic 075 checks.add(new DeprecationCheck(2114). 076 testAndRemove("shop", "organic"). 077 add("shop", "supermarket"). 078 add("organic", "only")); 079 // from http://wiki.openstreetmap.org/wiki/Key:bicycle_parking 080 checks.add(new DeprecationCheck(2115). 081 testAndRemove("bicycle_parking", "sheffield"). 082 add("bicycle_parking", "stands")); 083 } 084 085 public void visit(OsmPrimitive p) { 086 for (DeprecationCheck check : checks) { 087 if (check.matchesPrimitive(p)) { 088 errors.add(new DeprecationError(p, check)); 089 } 090 } 091 } 092 093 @Override 094 public void visit(Node n) { 095 visit((OsmPrimitive) n); 096 } 097 098 @Override 099 public void visit(Way w) { 100 visit((OsmPrimitive) w); 101 } 102 103 @Override 104 public void visit(Relation r) { 105 visit((OsmPrimitive) r); 106 } 107 108 private static class DeprecationCheck { 109 110 int code; 111 List<Tag> test = new LinkedList<Tag>(); 112 List<Tag> change = new LinkedList<Tag>(); 113 List<Tag> alternatives = new LinkedList<Tag>(); 114 115 public DeprecationCheck(int code) { 116 this.code = code; 117 } 118 119 DeprecationCheck test(String key, String value) { 120 test.add(new Tag(key, value)); 121 return this; 122 } 123 124 DeprecationCheck test(String key) { 125 return test(key, null); 126 } 127 128 DeprecationCheck add(String key, String value) { 129 change.add(new Tag(key, value)); 130 return this; 131 } 132 133 DeprecationCheck remove(String key) { 134 change.add(new Tag(key)); 135 return this; 136 } 137 138 DeprecationCheck testAndRemove(String key, String value) { 139 return test(key, value).remove(key); 140 } 141 142 DeprecationCheck testAndRemove(String key) { 143 return test(key).remove(key); 144 } 145 146 DeprecationCheck alternative(String key, String value) { 147 alternatives.add(new Tag(key, value)); 148 return this; 149 } 150 151 DeprecationCheck alternative(String key) { 152 return alternative(key, null); 153 } 154 155 boolean matchesPrimitive(OsmPrimitive p) { 156 for (Tag tag : test) { 157 String key = tag.getKey(); 158 String value = tag.getValue(); 159 if (value.isEmpty() && !p.hasKey(key)) 160 return false; 161 if (!value.isEmpty() && !value.equals(p.get(key))) 162 return false; 163 } 164 return true; 165 } 166 167 Command fixPrimitive(OsmPrimitive p) { 168 Collection<Command> cmds = new LinkedList<Command>(); 169 for (Tag tag : change) { 170 cmds.add(new ChangePropertyCommand(p, tag.getKey(), tag.getValue())); 171 } 172 return new SequenceCommand(tr("Deprecation fix of {0}", Utils.join(", ", test)), cmds); 173 } 174 175 String getDescription() { 176 if (alternatives.isEmpty()) 177 return tr("{0} is deprecated", Utils.join(", ", test)); 178 else 179 return tr("{0} is deprecated, use {1} instead", Utils.join(", ", test), Utils.join(tr(" or "), alternatives)); 180 } 181 } 182 183 private class DeprecationError extends TestError { 184 185 OsmPrimitive p; 186 DeprecationCheck check; 187 188 DeprecationError(OsmPrimitive p, DeprecationCheck check) { 189 super(DeprecatedTags.this, Severity.WARNING, check.getDescription(), check.code, p); 190 this.p = p; 191 this.check = check; 192 } 193 194 @Override 195 public boolean isFixable() { 196 return !check.change.isEmpty(); 197 } 198 199 @Override 200 public Command getFix() { 201 return check.fixPrimitive(p); 202 } 203 } 204 }