Changeset 6538 in josm
- Timestamp:
- 2013-12-26T15:19:31+01:00 (11 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/data/validator/relation.mapcss
r6537 r6538 8 8 9 9 /* from http://wiki.openstreetmap.org/wiki/Types_of_relation */ 10 relation[type=route][!route] { 11 throwWarning: tr("{0} relation without {0} tag", "route"); 10 /* see also #9071 */ 11 relation[type=route][!route], 12 relation[type=route_master][!route_master], 13 relation[type=restriction][!restriction], 14 relation[type=boundary][!boundary], 15 relation[type=site][!site], 16 relation[type=public_transport][!public_transport], 17 relation[type=waterway][!waterway], 18 relation[type=enforcement][!enforcement] { 19 throwWarning: tr("{0} relation without {0} tag", "{1.key}"); 12 20 assertMatch: "relation type=route"; 13 21 assertNoMatch: "relation type=route route=train"; 14 }15 16 relation[type=route_master][!route_master] {17 /* see #9071 */18 throwWarning: tr("{0} relation without {0} tag", "route_master");19 22 assertMatch: "relation type=route_master"; 20 23 assertNoMatch: "relation type=route_master route_master=train"; 21 }22 23 relation[type=restriction][!restriction] {24 throwWarning: tr("{0} relation without {0} tag", "restriction");25 24 assertMatch: "relation type=restriction"; 26 25 assertNoMatch: "relation type=restriction restriction=no_left_turn"; 27 }28 29 relation[type=boundary][!boundary] {30 throwWarning: tr("{0} relation without {0} tag", "boundary");31 26 assertMatch: "relation type=boundary"; 32 27 assertNoMatch: "relation type=boundary boundary=administrative"; 33 }34 35 relation[type=site][!site] {36 throwWarning: tr("{0} relation without {0} tag", "site");37 28 assertMatch: "relation type=site"; 38 29 assertNoMatch: "relation type=site site=administrative"; 39 }40 41 relation[type=public_transport][!public_transport] {42 throwWarning: tr("{0} relation without {0} tag", "public_transport");43 30 assertMatch: "relation type=public_transport"; 44 31 assertNoMatch: "relation type=public_transport public_transport=stop_area"; 45 }46 47 relation[type=waterway][!waterway] {48 throwWarning: tr("{0} relation without {0} tag", "waterway");49 32 assertMatch: "relation type=waterway"; 50 33 assertNoMatch: "relation type=waterway waterway=river"; 51 }52 53 relation[type=enforcement][!enforcement] {54 throwWarning: tr("{0} relation without {0} tag", "enforcement");55 34 assertMatch: "relation type=enforcement"; 56 35 assertNoMatch: "relation type=enforcement enforcement=maxspeed"; -
trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java
r6507 r6538 221 221 return children; 222 222 } 223 224 public Map<String, String> getTags() { 225 return Collections.unmodifiableMap(tags); 226 } 223 227 } -
trunk/src/org/openstreetmap/josm/command/Command.java
r6380 r6538 86 86 */ 87 87 public Command() { 88 this.layer = Main.main.getEditLayer(); 88 this.layer = Main.main == null ? null : Main.main.getEditLayer(); 89 89 } 90 90 -
trunk/src/org/openstreetmap/josm/data/validation/TestError.java
r6378 r6538 219 219 } 220 220 221 public void setTester(Test tester) { 222 this.tester = tester; 223 } 224 221 225 /** 222 226 * Gets the code -
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
r6537 r6538 14 14 import java.util.List; 15 15 import java.util.Map; 16 import java.util.regex.Matcher; 17 import java.util.regex.Pattern; 16 18 17 19 import org.openstreetmap.josm.command.ChangePropertyCommand; … … 29 31 import org.openstreetmap.josm.data.validation.TestError; 30 32 import org.openstreetmap.josm.gui.mappaint.Environment; 33 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; 31 34 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression; 32 35 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction; … … 173 176 */ 174 177 boolean matchesPrimitive(OsmPrimitive primitive) { 178 return whichSelectorMatchesPrimitive(primitive) != null; 179 } 180 181 Selector whichSelectorMatchesPrimitive(OsmPrimitive primitive) { 175 182 final Environment env = new Environment().withPrimitive(primitive); 176 183 for (Selector i : selector) { 177 184 if (i.matches(env)) { 178 return true; 179 } 180 } 181 return false; 185 return i; 186 } 187 } 188 return null; 189 } 190 191 /** 192 * Determines the {@code index}-th key/value/tag (depending on {@code type}) of the {@link Selector.GeneralSelector}. 193 */ 194 static String determineArgument(Selector.GeneralSelector matchingSelector, int index, String type) { 195 try { 196 final Condition c = matchingSelector.getConditions().get(index); 197 final Tag tag = c instanceof Condition.KeyCondition 198 ? ((Condition.KeyCondition) c).asTag() 199 : c instanceof Condition.KeyValueCondition 200 ? ((Condition.KeyValueCondition) c).asTag() 201 : null; 202 if (tag == null) { 203 return null; 204 } else if ("key".equals(type)) { 205 return tag.getKey(); 206 } else if ("value".equals(type)) { 207 return tag.getValue(); 208 } else if ("tag".equals(type)) { 209 return tag.toString(); 210 } 211 } catch (IndexOutOfBoundsException ignore) { 212 } 213 return null; 214 } 215 216 /** 217 * Replaces occurrences of {@code {i.key}}, {@code {i.value}}, {@code {i.tag}} in {@code s} by the corresponding 218 * key/value/tag of the {@code index}-th {@link Condition} of {@code matchingSelector}. 219 */ 220 static String insertArguments(Selector matchingSelector, String s) { 221 if (!(matchingSelector instanceof Selector.GeneralSelector) || s == null) { 222 return s; 223 } 224 final Matcher m = Pattern.compile("\\{(\\d+)\\.(key|value|tag)\\}").matcher(s); 225 final StringBuffer sb = new StringBuffer(); 226 while (m.find()) { 227 m.appendReplacement(sb, determineArgument((Selector.GeneralSelector) matchingSelector, Integer.parseInt(m.group(1)), m.group(2))); 228 } 229 m.appendTail(sb); 230 return sb.toString(); 182 231 } 183 232 … … 193 242 return null; 194 243 } 244 final Selector matchingSelector = whichSelectorMatchesPrimitive(p); 195 245 Collection<Command> cmds = new LinkedList<Command>(); 196 246 for (PrimitiveToTag toTag : change) { 197 247 final Tag tag = toTag.apply(p); 198 cmds.add(new ChangePropertyCommand(p, tag.getKey(), tag.getValue())); 248 final String key = insertArguments(matchingSelector, tag.getKey()); 249 final String value = insertArguments(matchingSelector, tag.getValue()); 250 cmds.add(new ChangePropertyCommand(p, key, value)); 199 251 } 200 252 for (Map.Entry<String, String> i : keyChange.entrySet()) { 201 cmds.add(new ChangePropertyKeyCommand(p, i.getKey(), i.getValue())); 253 final String oldKey = insertArguments(matchingSelector, i.getKey()); 254 final String newKey = insertArguments(matchingSelector, i.getValue()); 255 cmds.add(new ChangePropertyKeyCommand(p, oldKey, newKey)); 202 256 } 203 257 return new SequenceCommand(tr("Fix of {0}", getDescription()), cmds); … … 231 285 } 232 286 287 /** 288 * Constructs a {@link TestError} for the given primitive, or returns null if the primitive does not give rise to an error. 289 * 290 * @param p the primitive to construct the error for 291 * @return an instance of {@link TestError}, or returns null if the primitive does not give rise to an error. 292 */ 293 TestError getErrorForPrimitive(OsmPrimitive p) { 294 final Selector matchingSelector = whichSelectorMatchesPrimitive(p); 295 if (matchingSelector != null) { 296 final Command fix = fixPrimitive(p); 297 final String description = TagCheck.insertArguments(matchingSelector, getDescription()); 298 if (fix != null) { 299 return new FixableTestError(null, getSeverity(), description, 3000, p, fix); 300 } else { 301 return new TestError(null, getSeverity(), description, 3000, p); 302 } 303 } else { 304 return null; 305 } 306 } 233 307 } 234 308 … … 240 314 public void visit(OsmPrimitive p) { 241 315 for (TagCheck check : checks) { 242 if (check.matchesPrimitive(p)) { 243 final Command fix = check.fixPrimitive(p); 244 if (fix != null) { 245 errors.add(new FixableTestError(this, check.getSeverity(), check.getDescription(), 3000, p, fix)); 246 } else { 247 errors.add(new TestError(this, check.getSeverity(), check.getDescription(), 3000, p)); 248 } 316 final TestError error = check.getErrorForPrimitive(p); 317 if (error != null) { 318 error.setTester(this); 319 errors.add(error); 249 320 } 250 321 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
r6513 r6538 12 12 import org.openstreetmap.josm.data.osm.OsmUtils; 13 13 import org.openstreetmap.josm.data.osm.Relation; 14 import org.openstreetmap.josm.data.osm.Tag; 14 15 import org.openstreetmap.josm.data.osm.Way; 15 16 import org.openstreetmap.josm.gui.mappaint.Cascade; … … 161 162 public boolean applies(Environment env) { 162 163 return op.eval(env.osm.get(k), v); 164 } 165 166 public Tag asTag() { 167 return new Tag(k, v); 163 168 } 164 169 … … 252 257 } 253 258 259 public Tag asTag() { 260 return new Tag(label); 261 } 262 254 263 @Override 255 264 public String toString() { -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
r6535 r6538 431 431 } 432 432 Matcher m = Pattern.compile(pattern, f).matcher(target); 433 if (m.matches()) { 434 List<String> result = new ArrayList<String>(m.groupCount() + 1); 435 for (int i = 0; i <= m.groupCount(); i++) { 436 result.add(m.group(i)); 437 } 438 return result; 439 } else { 440 return null; 441 } 433 return Utils.getMatches(m); 442 434 } 443 435 … … 450 442 public static List<String> regexp_match(String pattern, String target) { 451 443 Matcher m = Pattern.compile(pattern).matcher(target); 452 if (m.matches()) { 453 List<String> result = new ArrayList<String>(m.groupCount() + 1); 454 for (int i = 0; i <= m.groupCount(); i++) { 455 result.add(m.group(i)); 456 } 457 return result; 458 } else { 459 return null; 460 } 444 return Utils.getMatches(m); 461 445 } 462 446 -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r6248 r6538 2 2 package org.openstreetmap.josm.gui.mappaint.mapcss; 3 3 4 import java.util.Collections; 4 5 import java.util.List; 5 6 import java.util.regex.PatternSyntaxException; … … 231 232 return true; 232 233 } 234 235 public List<Condition> getConditions() { 236 return Collections.unmodifiableList(conds); 237 } 233 238 } 234 239 … … 310 315 @Override 311 316 public boolean matches(Environment e) { 312 if (!matchesBase(e)) return false; 313 return matchesConditions(e); 317 return matchesBase(e) && matchesConditions(e); 314 318 } 315 319 -
trunk/src/org/openstreetmap/josm/tools/Utils.java
r6524 r6538 38 38 import java.util.Iterator; 39 39 import java.util.List; 40 import java.util.regex.Matcher; 40 41 import java.util.zip.GZIPInputStream; 41 42 import java.util.zip.ZipFile; … … 835 836 return String.format("%d %s %d %s", days, trn("day", "days", days), elapsedTime/3600000, tr("h")); 836 837 } 838 839 /** 840 * Returns a list of capture groups if {@link Matcher#matches()}, or {@code null}. 841 * The first element (index 0) is the complete match. 842 * Further elements correspond to the parts in parentheses of the regular expression. 843 * @param m the matcher 844 * @return a list of capture groups if {@link Matcher#matches()}, or {@code null}. 845 */ 846 public static List<String> getMatches(final Matcher m) { 847 if (m.matches()) { 848 List<String> result = new ArrayList<String>(m.groupCount() + 1); 849 for (int i = 0; i <= m.groupCount(); i++) { 850 result.add(m.group(i)); 851 } 852 return result; 853 } else { 854 return null; 855 } 856 } 837 857 } -
trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java
r6534 r6538 4 4 import org.junit.Test; 5 5 import org.openstreetmap.josm.Main; 6 import org.openstreetmap.josm.command.ChangePropertyCommand; 6 7 import org.openstreetmap.josm.data.Preferences; 7 8 import org.openstreetmap.josm.data.osm.Node; … … 10 11 import org.openstreetmap.josm.data.osm.Tag; 11 12 import org.openstreetmap.josm.data.osm.Way; 13 import org.openstreetmap.josm.data.validation.Severity; 12 14 import org.openstreetmap.josm.tools.TextTagParser; 13 15 14 16 import java.io.StringReader; 17 import java.text.MessageFormat; 15 18 import java.util.LinkedHashSet; 16 19 import java.util.List; … … 35 38 final List<MapCSSTagChecker.TagCheck> checks = MapCSSTagChecker.TagCheck.readMapCSS(new StringReader("" + 36 39 "*[natural=marsh] {\n" + 37 " throwWarning: tr(\"{0} is deprecated\", \" natural=marsh\");\n" +38 " fixRemove: \" natural\";\n" +40 " throwWarning: tr(\"{0} is deprecated\", \"{0.tag}\");\n" + 41 " fixRemove: \"{0.key}\";\n" + 39 42 " fixAdd: \"natural=wetland\";\n" + 40 43 " fixAdd: \"wetland=marsh\";\n" + … … 43 46 final MapCSSTagChecker.TagCheck check = checks.get(0); 44 47 assertThat(check, notNullValue()); 45 assertThat(check.change.get(0).apply(null), is(new Tag("natural"))); 48 assertThat(check.getDescription(), is("{0.tag} is deprecated")); 49 assertThat(check.change.get(0).apply(null), is(new Tag("{0.key}"))); 46 50 assertThat(check.change.get(1).apply(null), is(new Tag("natural", "wetland"))); 47 51 assertThat(check.change.get(2).apply(null), is(new Tag("wetland", "marsh"))); 48 assertThat(check.errors.keySet().iterator().next(), is("natural=marsh is deprecated"));49 52 final Node n1 = new Node(); 50 53 n1.put("natural", "marsh"); 51 54 assertTrue(check.matchesPrimitive(n1)); 55 assertThat(check.getErrorForPrimitive(n1).getMessage(), is("natural=marsh is deprecated")); 56 assertThat(check.getErrorForPrimitive(n1).getSeverity(), is(Severity.WARNING)); 57 assertThat(((ChangePropertyCommand) check.fixPrimitive(n1).getChildren().iterator().next()).getTags().toString(), 58 is("{natural=}")); 52 59 final Node n2 = new Node(); 53 60 n2.put("natural", "wood"); 54 61 assertFalse(check.matchesPrimitive(n2)); 62 assertThat(MapCSSTagChecker.TagCheck.insertArguments(check.selector.get(0), "The key is {0.key} and the value is {0.value}"), 63 is("The key is natural and the value is marsh")); 55 64 } 56 65 … … 97 106 final OsmPrimitive p = createPrimitiveForAssertion(i.getKey()); 98 107 if (check.matchesPrimitive(p) != i.getValue()) { 99 final String error = "Expecting test '" + check.getMessage() + "' to " + (i.getValue() ? "" : "not ") + "match " + i.getKey() + ", i.e., " + p.getKeys(); 108 final String error = MessageFormat.format("Expecting test ''{0}'' (i.e., {1}) to {2} {3} (i.e., {4})", 109 check.getMessage(), check.selector, i.getValue() ? "match" : "not match", i.getKey(), p.getKeys()); 100 110 System.err.println(error); 101 111 assertionErrors.add(error);
Note:
See TracChangeset
for help on using the changeset viewer.