Changeset 8435 in josm for trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
- Timestamp:
- 2015-05-31T17:06:27+02:00 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
r8404 r8435 39 39 import org.openstreetmap.josm.data.osm.OsmUtils; 40 40 import org.openstreetmap.josm.data.osm.Tag; 41 import org.openstreetmap.josm.data.validation.FixableTestError; 41 42 import org.openstreetmap.josm.data.validation.Severity; 42 import org.openstreetmap.josm.data.validation.Test ;43 import org.openstreetmap.josm.data.validation.Test.TagTest; 43 44 import org.openstreetmap.josm.data.validation.TestError; 44 45 import org.openstreetmap.josm.data.validation.util.Entities; … … 56 57 import org.openstreetmap.josm.tools.GBC; 57 58 import org.openstreetmap.josm.tools.MultiMap; 59 import org.openstreetmap.josm.tools.Utils; 58 60 59 61 /** … … 61 63 * 62 64 * @author frsantos 65 * @since 3669 63 66 */ 64 public class TagChecker extends Test.TagTest { 65 66 /** The default data file of tagchecker rules */ 67 //public static final String DATA_FILE = "resource://data/validator/tagchecker.cfg"; 67 public class TagChecker extends TagTest { 68 68 69 /** The config file of ignored tags */ 69 70 public static final String IGNORE_FILE = "resource://data/validator/ignoretags.cfg"; … … 125 126 protected static final int LOW_CHAR_VALUE = 1210; 126 127 protected static final int LOW_CHAR_KEY = 1211; 128 protected static final int MISSPELLED_VALUE = 1212; 127 129 /** 1250 and up is used by tagcheck */ 128 130 … … 324 326 for (CheckerData d : checkerData) { 325 327 if (d.match(p, keys)) { 326 errors.add( 327 d.getDescription(), d.getDescriptionOrig(), d.getCode(), p) 328 errors.add(new TestError(this, d.getSeverity(), tr("Suspicious tag/value combinations"), 329 d.getDescription(), d.getDescriptionOrig(), d.getCode(), p)); 328 330 withErrors.put(p, "TC"); 329 331 } … … 336 338 String value = prop.getValue(); 337 339 if (checkValues && (containsLow(value)) && !withErrors.contains(p, "ICV")) { 338 errors.add( 339 tr(s, key), MessageFormat.format(s, key), LOW_CHAR_VALUE, p) 340 errors.add(new TestError(this, Severity.WARNING, tr("Tag value contains character with code less than 0x20"), 341 tr(s, key), MessageFormat.format(s, key), LOW_CHAR_VALUE, p)); 340 342 withErrors.put(p, "ICV"); 341 343 } 342 344 if (checkKeys && (containsLow(key)) && !withErrors.contains(p, "ICK")) { 343 errors.add( 344 tr(s, key), MessageFormat.format(s, key), LOW_CHAR_KEY, p) 345 errors.add(new TestError(this, Severity.WARNING, tr("Tag key contains character with code less than 0x20"), 346 tr(s, key), MessageFormat.format(s, key), LOW_CHAR_KEY, p)); 345 347 withErrors.put(p, "ICK"); 346 348 } 347 349 if (checkValues && (value!=null && value.length() > 255) && !withErrors.contains(p, "LV")) { 348 errors.add( 349 tr(s, key), MessageFormat.format(s, key), LONG_VALUE, p) 350 errors.add(new TestError(this, Severity.ERROR, tr("Tag value longer than allowed"), 351 tr(s, key), MessageFormat.format(s, key), LONG_VALUE, p)); 350 352 withErrors.put(p, "LV"); 351 353 } 352 354 if (checkKeys && (key!=null && key.length() > 255) && !withErrors.contains(p, "LK")) { 353 errors.add( 354 tr(s, key), MessageFormat.format(s, key), LONG_KEY, p) 355 errors.add(new TestError(this, Severity.ERROR, tr("Tag key longer than allowed"), 356 tr(s, key), MessageFormat.format(s, key), LONG_KEY, p)); 355 357 withErrors.put(p, "LK"); 356 358 } 357 359 if (checkValues && (value==null || value.trim().isEmpty()) && !withErrors.contains(p, "EV")) { 358 errors.add( 359 tr(s, key), MessageFormat.format(s, key), EMPTY_VALUES, p) 360 errors.add(new TestError(this, Severity.WARNING, tr("Tags with empty values"), 361 tr(s, key), MessageFormat.format(s, key), EMPTY_VALUES, p)); 360 362 withErrors.put(p, "EV"); 361 363 } 362 364 if (checkKeys && spellCheckKeyData.containsKey(key) && !withErrors.contains(p, "IPK")) { 363 errors.add( 364 tr(s, key), MessageFormat.format(s, key), INVALID_KEY, p) 365 errors.add(new TestError(this, Severity.WARNING, tr("Invalid property key"), 366 tr(s, key), MessageFormat.format(s, key), INVALID_KEY, p)); 365 367 withErrors.put(p, "IPK"); 366 368 } 367 369 if (checkKeys && key != null && key.indexOf(' ') >= 0 && !withErrors.contains(p, "IPK")) { 368 errors.add( 369 tr(s, key), MessageFormat.format(s, key), INVALID_KEY_SPACE, p) 370 errors.add(new TestError(this, Severity.WARNING, tr("Invalid white space in property key"), 371 tr(s, key), MessageFormat.format(s, key), INVALID_KEY_SPACE, p)); 370 372 withErrors.put(p, "IPK"); 371 373 } 372 374 if (checkValues && value != null && (value.startsWith(" ") || value.endsWith(" ")) && !withErrors.contains(p, "SPACE")) { 373 errors.add( 374 tr(s, key), MessageFormat.format(s, key), INVALID_SPACE, p) 375 errors.add(new TestError(this, Severity.WARNING, tr("Property values start or end with white space"), 376 tr(s, key), MessageFormat.format(s, key), INVALID_SPACE, p)); 375 377 withErrors.put(p, "SPACE"); 376 378 } 377 379 if (checkValues && value != null && !value.equals(entities.unescape(value)) && !withErrors.contains(p, "HTML")) { 378 errors.add( 379 tr(s, key), MessageFormat.format(s, key), INVALID_HTML, p) 380 errors.add(new TestError(this, Severity.OTHER, tr("Property values contain HTML entity"), 381 tr(s, key), MessageFormat.format(s, key), INVALID_HTML, p)); 380 382 withErrors.put(p, "HTML"); 381 383 } … … 413 415 if (!keyInPresets) { 414 416 String i = marktr("Key ''{0}'' not in presets."); 415 errors.add( 416 tr(i, key), MessageFormat.format(i, key), INVALID_VALUE, p) 417 errors.add(new TestError(this, Severity.OTHER, tr("Presets do not contain property key"), 418 tr(i, key), MessageFormat.format(i, key), INVALID_VALUE, p)); 417 419 withErrors.put(p, "UPK"); 418 420 } else if (!tagInPresets) { 419 String i = marktr("Value ''{0}'' for key ''{1}'' not in presets."); 420 errors.add( new TestError(this, Severity.OTHER, tr("Presets do not contain property value"), 421 tr(i, prop.getValue(), key), MessageFormat.format(i, prop.getValue(), key), INVALID_VALUE, p) ); 422 withErrors.put(p, "UPV"); 421 // try to fix common typos and check again if value is still unknown 422 String fixedValue = prettifyValue(prop.getValue()); 423 if (values != null && values.contains(fixedValue)) { 424 // misspelled preset value 425 String i = marktr("Value ''{0}'' for key ''{1}'' looks like ''{2}}."); 426 errors.add(new FixableTestError(this, Severity.WARNING, tr("Misspelled property value"), 427 tr(i, prop.getValue(), key, fixedValue), MessageFormat.format(i, prop.getValue(), fixedValue), 428 MISSPELLED_VALUE, p, new ChangePropertyCommand(p, key, fixedValue))); 429 withErrors.put(p, "WPV"); 430 } else { 431 // unknown preset value 432 String i = marktr("Value ''{0}'' for key ''{1}'' not in presets."); 433 errors.add(new TestError(this, Severity.OTHER, tr("Presets do not contain property value"), 434 tr(i, prop.getValue(), key), MessageFormat.format(i, prop.getValue(), key), INVALID_VALUE, p)); 435 withErrors.put(p, "UPV"); 436 } 423 437 } 424 438 } … … 435 449 } 436 450 } 451 } 452 453 private static String prettifyValue(String value) { 454 // convert to lower case, replace ' ' or '-' with '_' 455 value = value.toLowerCase(Locale.ENGLISH).replace('-', '_').replace(' ', '_'); 456 // remove trailing or leading special chars 457 return Utils.strip(value, "-_;:,"); 437 458 } 438 459 … … 554 575 List<Command> commands = new ArrayList<>(50); 555 576 556 Collection<? extends OsmPrimitive> primitives = testError.getPrimitives(); 557 for (OsmPrimitive p : primitives) { 558 Map<String, String> tags = p.getKeys(); 559 if (tags == null || tags.isEmpty()) { 560 continue; 561 } 562 563 for (Entry<String, String> prop: tags.entrySet()) { 564 String key = prop.getKey(); 565 String value = prop.getValue(); 566 if (value == null || value.trim().isEmpty()) { 567 commands.add(new ChangePropertyCommand(p, key, null)); 568 } else if (value.startsWith(" ") || value.endsWith(" ")) { 569 commands.add(new ChangePropertyCommand(p, key, Tag.removeWhiteSpaces(value))); 570 } else if (key.startsWith(" ") || key.endsWith(" ")) { 571 commands.add(new ChangePropertyKeyCommand(p, key, Tag.removeWhiteSpaces(key))); 572 } else { 573 String evalue = entities.unescape(value); 574 if (!evalue.equals(value)) { 575 commands.add(new ChangePropertyCommand(p, key, evalue)); 577 if (testError instanceof FixableTestError) { 578 commands.add(testError.getFix()); 579 } else { 580 Collection<? extends OsmPrimitive> primitives = testError.getPrimitives(); 581 for (OsmPrimitive p : primitives) { 582 Map<String, String> tags = p.getKeys(); 583 if (tags == null || tags.isEmpty()) { 584 continue; 585 } 586 587 for (Entry<String, String> prop: tags.entrySet()) { 588 String key = prop.getKey(); 589 String value = prop.getValue(); 590 if (value == null || value.trim().isEmpty()) { 591 commands.add(new ChangePropertyCommand(p, key, null)); 592 } else if (value.startsWith(" ") || value.endsWith(" ")) { 593 commands.add(new ChangePropertyCommand(p, key, Tag.removeWhiteSpaces(value))); 594 } else if (key.startsWith(" ") || key.endsWith(" ")) { 595 commands.add(new ChangePropertyKeyCommand(p, key, Tag.removeWhiteSpaces(key))); 576 596 } else { 577 String replacementKey = spellCheckKeyData.get(key); 578 if (replacementKey != null) { 579 commands.add(new ChangePropertyKeyCommand(p, key, replacementKey)); 597 String evalue = entities.unescape(value); 598 if (!evalue.equals(value)) { 599 commands.add(new ChangePropertyCommand(p, key, evalue)); 600 } else { 601 String replacementKey = spellCheckKeyData.get(key); 602 if (replacementKey != null) { 603 commands.add(new ChangePropertyKeyCommand(p, key, replacementKey)); 604 } 580 605 } 581 606 } … … 596 621 if (testError.getTester() instanceof TagChecker) { 597 622 int code = testError.getCode(); 598 return code == INVALID_KEY || code == EMPTY_VALUES || code == INVALID_SPACE || code == INVALID_KEY_SPACE || code == INVALID_HTML; 623 return code == INVALID_KEY || code == EMPTY_VALUES || code == INVALID_SPACE || 624 code == INVALID_KEY_SPACE || code == INVALID_HTML || code == MISSPELLED_VALUE; 599 625 } 600 626
Note:
See TracChangeset
for help on using the changeset viewer.