Ticket #17055: 17055-enh-v1.patch
File 17055-enh-v1.patch, 12.9 KB (added by , 6 years ago) |
---|
-
src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
13 13 import java.util.Collection; 14 14 import java.util.Collections; 15 15 import java.util.HashMap; 16 import java.util.HashSet; 16 17 import java.util.List; 17 18 import java.util.Locale; 18 19 import java.util.Map; … … 76 77 /** The TagChecker data */ 77 78 private static final List<CheckerData> checkerData = new ArrayList<>(); 78 79 private static final List<String> ignoreDataStartsWith = new ArrayList<>(); 79 private static final List<String> ignoreDataEquals = new ArrayList<>();80 private static final Set<String> ignoreDataEquals = new HashSet<>(); 80 81 private static final List<String> ignoreDataEndsWith = new ArrayList<>(); 81 82 private static final List<Tag> ignoreDataTag = new ArrayList<>(); 82 83 … … 141 142 protected JCheckBox prefCheckPaintBeforeUpload; 142 143 143 144 // CHECKSTYLE.OFF: SingleSpaceSeparator 144 protected static final int EMPTY_VALUES = 1200; 145 protected static final int INVALID_KEY = 1201; 146 protected static final int INVALID_VALUE = 1202; 147 protected static final int FIXME = 1203; 148 protected static final int INVALID_SPACE = 1204; 149 protected static final int INVALID_KEY_SPACE = 1205; 150 protected static final int INVALID_HTML = 1206; /* 1207 was PAINT */ 151 protected static final int LONG_VALUE = 1208; 152 protected static final int LONG_KEY = 1209; 153 protected static final int LOW_CHAR_VALUE = 1210; 154 protected static final int LOW_CHAR_KEY = 1211; 155 protected static final int MISSPELLED_VALUE = 1212; 156 protected static final int MISSPELLED_KEY = 1213; 157 protected static final int MULTIPLE_SPACES = 1214; 145 protected static final int EMPTY_VALUES = 1200; 146 protected static final int INVALID_KEY = 1201; 147 protected static final int INVALID_VALUE = 1202; 148 protected static final int FIXME = 1203; 149 protected static final int INVALID_SPACE = 1204; 150 protected static final int INVALID_KEY_SPACE = 1205; 151 protected static final int INVALID_HTML = 1206; /* 1207 was PAINT */ 152 protected static final int LONG_VALUE = 1208; 153 protected static final int LONG_KEY = 1209; 154 protected static final int LOW_CHAR_VALUE = 1210; 155 protected static final int LOW_CHAR_KEY = 1211; 156 protected static final int MISSPELLED_VALUE = 1212; 157 protected static final int MISSPELLED_KEY = 1213; 158 protected static final int MULTIPLE_SPACES = 1214; 159 protected static final int TRUNCATED_VALUE = 1215; 160 protected static final int MISSPELLED_VALUE_NO_FIX = 1216; 161 protected static final int TRUNCATED_VALUE_NO_FIX = 1217; 158 162 // CHECKSTYLE.ON: SingleSpaceSeparator 159 163 // 1250 and up is used by tagcheck 160 164 … … 387 391 * @since 9023 388 392 */ 389 393 public static boolean isTagIgnored(String key, String value) { 390 boolean tagInPresets = isTagInPresets(key, value);391 boolean ignore = false;392 394 if (ignoreDataEquals.contains(key)) { 395 return true; 396 } 393 397 for (String a : ignoreDataStartsWith) { 394 398 if (key.startsWith(a)) { 395 ignore =true;399 return true; 396 400 } 397 401 } 398 for (String a : ignoreDataEquals) {399 if (key.equals(a)) {400 ignore = true;401 }402 }403 402 for (String a : ignoreDataEndsWith) { 404 403 if (key.endsWith(a)) { 405 ignore =true;404 return true; 406 405 } 407 406 } 408 407 409 if (! tagInPresets) {408 if (!isTagInPresets(key, value)) { 410 409 for (Tag a : ignoreDataTag) { 411 410 if (key.equals(a.getKey()) && value.equals(a.getValue())) { 412 ignore =true;411 return true; 413 412 } 414 413 } 415 414 } 416 return ignore;415 return false; 417 416 } 418 417 419 418 /** … … 534 533 } else if (!isTagInPresets(key, value)) { 535 534 // try to fix common typos and check again if value is still unknown 536 535 String fixedValue = harmonizeValue(prop.getValue()); 537 Map<String, String> possibleValues = getPossibleValues(getPresetValues(key));536 Set<String> possibleValues = getPresetValues(key); 538 537 List<String> fixVals = new ArrayList<>(); 539 if (!possibleValues.containsKey(fixedValue)) { 540 int minDist = 2; 538 List<String> sameStartVals = new ArrayList<>(); 539 if (!possibleValues.contains(fixedValue)) { 540 int minDist = 10; 541 541 String closest = null; 542 for (String possibleVal : possibleValues.keySet()) { 542 for (String possibleVal : possibleValues) { 543 if (possibleVal.isEmpty()) 544 continue; 545 if (possibleVal.startsWith(fixedValue)) 546 sameStartVals.add(possibleVal); 543 547 int dist = Utils.getLevenshteinDistance(possibleVal, fixedValue); 544 548 if (dist < minDist) { 545 549 closest = possibleVal; … … 550 554 fixVals.add(possibleVal); 551 555 } 552 556 } 553 if (minDist <= 1) { 557 fixedValue = null; 558 if (minDist <= 2) { 554 559 if (fixVals.size() < 2) { 555 560 fixedValue = closest; 556 561 } else { 557 562 Collections.sort(fixVals); 558 563 // misspelled preset value with multiple good alternatives 559 errors.add(TestError.builder(this, Severity.WARNING, MISSPELLED_VALUE )564 errors.add(TestError.builder(this, Severity.WARNING, MISSPELLED_VALUE_NO_FIX) 560 565 .message(tr("Misspelled property value"), 561 566 marktr("Value ''{0}'' for key ''{1}'' looks like one of {2}."), prop.getValue(), key, fixVals) 562 567 .primitives(p) … … 565 570 continue; 566 571 } 567 572 } 573 if (!sameStartVals.isEmpty()) { 574 if (sameStartVals.size() == 1) { 575 // only one preset value starts with the same characters 576 fixedValue = sameStartVals.get(0); 577 } else { 578 errors.add(TestError.builder(this, Severity.WARNING, TRUNCATED_VALUE_NO_FIX) 579 .message(tr("Probably truncated property value"), 580 marktr("Value ''{0}'' for key ''{1}'' not in presets."), 581 prop.getValue(), key) 582 .primitives(p).build()); 583 withErrors.put(p, "WPV"); 584 } 585 continue; 586 } 568 587 } 569 if ( possibleValues.containsKey(fixedValue)) {570 final String newValue = possibleValues.get(fixedValue);588 if (fixedValue != null && possibleValues.contains(fixedValue)) { 589 final String newValue = fixedValue; 571 590 // misspelled preset value 572 591 errors.add(TestError.builder(this, Severity.WARNING, MISSPELLED_VALUE) 573 592 .message(tr("Misspelled property value"), … … 602 621 || value.toLowerCase(Locale.ENGLISH).contains("fixme") || value.contains("check and delete"); 603 622 } 604 623 605 private static Map<String, String> getPossibleValues(Set<String> values) {606 // generate a map with common typos607 Map<String, String> map = new HashMap<>();608 if (values != null) {609 for (String value : values) {610 map.put(value, value);611 if (value.contains("_")) {612 map.put(value.replace("_", ""), value);613 }614 }615 }616 return map;617 }618 619 624 private static String harmonizeKey(String key) { 620 625 return Utils.strip(key.toLowerCase(Locale.ENGLISH).replace('-', '_').replace(':', '_').replace(' ', '_'), "-_;:,"); 621 626 } … … 778 783 int code = testError.getCode(); 779 784 return code == INVALID_KEY || code == EMPTY_VALUES || code == INVALID_SPACE || 780 785 code == INVALID_KEY_SPACE || code == INVALID_HTML || code == MISSPELLED_VALUE || 781 code == MULTIPLE_SPACES ;786 code == MULTIPLE_SPACES || code == TRUNCATED_VALUE; 782 787 } 783 788 784 789 return false; -
test/unit/org/openstreetmap/josm/data/validation/tests/TagCheckerTest.java
15 15 import org.openstreetmap.josm.data.osm.OsmPrimitive; 16 16 import org.openstreetmap.josm.data.osm.OsmUtils; 17 17 import org.openstreetmap.josm.data.osm.Tag; 18 import org.openstreetmap.josm.data.validation.Severity; 18 19 import org.openstreetmap.josm.data.validation.TestError; 19 20 import org.openstreetmap.josm.testutils.JOSMTestRules; 20 21 … … 77 78 assertEquals(1, errors.size()); 78 79 assertEquals("Misspelled property key", errors.get(0).getMessage()); 79 80 assertEquals("Key 'Brand' looks like 'brand'.", errors.get(0).getDescription()); 81 assertEquals(Severity.WARNING, errors.get(0).getSeverity()); 80 82 assertFalse(errors.get(0).isFixable()); 81 83 } 82 84 … … 90 92 assertEquals(1, errors.size()); 91 93 assertEquals("Presets do not contain property key", errors.get(0).getMessage()); 92 94 assertEquals("Key 'namez' not in presets.", errors.get(0).getDescription()); 95 assertEquals(Severity.OTHER, errors.get(0).getSeverity()); 96 assertFalse(errors.get(0).isFixable()); 93 97 } 94 98 95 99 /** … … 102 106 assertEquals(1, errors.size()); 103 107 assertEquals("Misspelled property value", errors.get(0).getMessage()); 104 108 assertEquals("Value 'forrest' for key 'landuse' looks like 'forest'.", errors.get(0).getDescription()); 109 assertEquals(Severity.WARNING, errors.get(0).getSeverity()); 110 assertTrue(errors.get(0).isFixable()); 105 111 } 106 112 107 113 /** … … 114 120 assertEquals(1, errors.size()); 115 121 assertEquals("Misspelled property value", errors.get(0).getMessage()); 116 122 assertEquals("Value 'servics' for key 'highway' looks like one of [service, services].", errors.get(0).getDescription()); 123 assertEquals(Severity.WARNING, errors.get(0).getSeverity()); 124 assertFalse(errors.get(0).isFixable()); 117 125 } 118 126 119 127 /** 128 * Check for misspelled value. 129 * @throws IOException if any I/O error occurs 130 */ 131 @Test 132 public void testMisspelledTag3() throws IOException { 133 final List<TestError> errors = test(OsmUtils.createPrimitive("node highway=residentail")); 134 assertEquals(1, errors.size()); 135 assertEquals("Misspelled property value", errors.get(0).getMessage()); 136 assertEquals("Value 'residentail' for key 'highway' looks like 'residential'.", errors.get(0).getDescription()); 137 assertEquals(Severity.WARNING, errors.get(0).getSeverity()); 138 assertTrue(errors.get(0).isFixable()); 139 } 140 141 /** 142 * Check for misspelled value. 143 * @throws IOException if any I/O error occurs 144 */ 145 @Test 146 public void testMisspelledTag4() throws IOException { 147 final List<TestError> errors = test(OsmUtils.createPrimitive("node highway=res")); 148 assertEquals(1, errors.size()); 149 assertEquals("Probably truncated property value", errors.get(0).getMessage()); 150 assertEquals("Value 'res' for key 'highway' not in presets.", errors.get(0).getDescription()); 151 assertEquals(Severity.WARNING, errors.get(0).getSeverity()); 152 assertFalse(errors.get(0).isFixable()); 153 } 154 155 /** 120 156 * Checks that tags specifically ignored are effectively not in internal presets. 121 157 * @throws IOException if any I/O error occurs 122 158 */