Changeset 14727 in josm


Ignore:
Timestamp:
2019-01-24T17:49:13+01:00 (5 years ago)
Author:
GerdP
Message:

fix #17233: Remove support for TagChecker configuration files starting with "# JOSM TagChecker"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java

    r14721 r14727  
    2020import java.util.Map.Entry;
    2121import java.util.Set;
    22 import java.util.regex.Matcher;
    23 import java.util.regex.Pattern;
    24 import java.util.regex.PatternSyntaxException;
    2522
    2623import javax.swing.JCheckBox;
     
    3431import org.openstreetmap.josm.data.osm.AbstractPrimitive;
    3532import org.openstreetmap.josm.data.osm.OsmPrimitive;
    36 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    37 import org.openstreetmap.josm.data.osm.OsmUtils;
    3833import org.openstreetmap.josm.data.osm.Tag;
    3934import org.openstreetmap.josm.data.osm.Tagged;
     
    7974
    8075    /** The TagChecker data */
    81     private static final List<CheckerData> checkerData = new ArrayList<>();
    8276    private static final List<String> ignoreDataStartsWith = new ArrayList<>();
    8377    private static final Set<String> ignoreDataEquals = new HashSet<>();
     
    135129    protected boolean checkKeys;
    136130    protected boolean checkValues;
     131    /** Was used for special configuration file, might be used to disable value spell checker. */
    137132    protected boolean checkComplex;
    138133    protected boolean checkFixmes;
     
    167162    protected static final int MISSPELLED_VALUE_NO_FIX  = 1215;
    168163    // CHECKSTYLE.ON: SingleSpaceSeparator
    169     // 1250 and up is used by TagCheckLevel in class CheckerData
    170164
    171165    protected EditableList sourcesList;
    172166
    173     private static final List<String> DEFAULT_SOURCES = Arrays.asList(/*DATA_FILE, */IGNORE_FILE, SPELL_FILE);
     167    private static final List<String> DEFAULT_SOURCES = Arrays.asList(IGNORE_FILE, SPELL_FILE);
    174168
    175169    /**
     
    219213     */
    220214    private static void initializeData() throws IOException {
    221         checkerData.clear();
    222215        ignoreDataStartsWith.clear();
    223216        ignoreDataEquals.clear();
     
    243236                        if (line.startsWith("# JOSM TagChecker")) {
    244237                            tagcheckerfile = true;
    245                             if (!DEFAULT_SOURCES.contains(source)) {
    246                                 Logging.info(tr("Adding {0} to tag checker", source));
    247                             }
     238                            Logging.error(tr("Ignoring {0}. Support was dropped", source));
    248239                        } else
    249240                        if (line.startsWith("# JOSM IgnoreTags")) {
     
    256247                        parseIgnoreFileLine(source, line);
    257248                    } else if (tagcheckerfile) {
    258                         if (!line.isEmpty()) {
    259                             CheckerData d = new CheckerData();
    260                             String err = d.getData(line);
    261 
    262                             if (err == null) {
    263                                 checkerData.add(d);
    264                             } else {
    265                                 Logging.error(tr("Invalid tagchecker line - {0}: {1}", err, line));
    266                             }
    267                         }
     249                        // ignore
    268250                    } else if (line.charAt(0) == '+') {
    269251                        okValue = line.substring(1);
     
    394376    }
    395377
     378    /**
     379     * Get set of preset values for the given key.
     380     * @param key the key
     381     * @return null if key is not in presets or in additionalPresetsValueData,
     382     *  else a set which might be empty.
     383     */
    396384    private static Set<String> getPresetValues(String key) {
    397385        Set<String> res = TaggingPresets.getPresetValues(key);
     
    400388        if (additionalPresetsValueData.contains(key))
    401389            return Collections.emptySet();
     390        // null means key is not known
    402391        return null;
    403392    }
     
    490479        // Just a collection to know if a primitive has been already marked with error
    491480        MultiMap<OsmPrimitive, String> withErrors = new MultiMap<>();
    492 
    493         if (checkComplex) {
    494             Map<String, String> keys = p.getKeys();
    495             for (CheckerData d : checkerData) {
    496                 if (d.match(p, keys)) {
    497                     errors.add(TestError.builder(this, d.getSeverity(), d.getCode())
    498                             .message(tr("Suspicious tag/value combinations"), d.getDescription())
    499                             .primitives(p)
    500                             .build());
    501                     withErrors.put(p, "TC");
    502                 }
    503             }
    504         }
    505481
    506482        for (Entry<String, String> prop : p.getKeys().entrySet()) {
     
    651627            return;
    652628        String fixedValue = null;
     629        List<Set<String>> sets = new ArrayList<>();
    653630        Set<String> presetValues = getPresetValues(key);
    654         Set<String> oftenUsedValues = oftenUsedTags.get(key);
    655         for (Set<String> possibleValues: Arrays.asList(presetValues, oftenUsedValues)) {
    656             if (possibleValues != null && possibleValues.contains(harmonizedValue)) {
     631        if (presetValues != null)
     632            sets.add(presetValues);
     633        sets.add(oftenUsedTags.get(key));
     634        for (Set<String> possibleValues: sets) {
     635            if (possibleValues.contains(harmonizedValue)) {
    657636                fixedValue = harmonizedValue;
    658637                break;
     
    665644            int minDist = MAX_LEVENSHTEIN_DISTANCE + 1;
    666645            String closest = null;
    667             for (Set<String> possibleValues: Arrays.asList(presetValues, oftenUsedValues)) {
    668                 if (possibleValues == null)
    669                     continue;
     646            for (Set<String> possibleValues: sets) {
    670647                for (String possibleVal : possibleValues) {
    671648                    if (possibleVal.isEmpty())
     
    765742        }
    766743
    767         checkComplex = Config.getPref().getBoolean(PREF_CHECK_COMPLEX, true) && !checkerData.isEmpty();
     744        checkComplex = Config.getPref().getBoolean(PREF_CHECK_COMPLEX, true);
    768745        if (isBeforeUpload) {
    769746            checkComplex = checkComplex && Config.getPref().getBoolean(PREF_CHECK_COMPLEX_BEFORE_UPLOAD, true);
     
    911888        return false;
    912889    }
    913 
    914     protected static class CheckerData {
    915         private String description;
    916         protected List<CheckerElement> data = new ArrayList<>();
    917         private OsmPrimitiveType type;
    918         private TagCheckLevel level;
    919         protected Severity severity;
    920 
    921         private enum TagCheckLevel {
    922             TAG_CHECK_ERROR(1250),
    923             TAG_CHECK_WARN(1260),
    924             TAG_CHECK_INFO(1270);
    925 
    926             final int code;
    927 
    928             TagCheckLevel(int code) {
    929                 this.code = code;
    930             }
    931         }
    932 
    933         protected static class CheckerElement {
    934             Object tag;
    935             Object value;
    936             boolean noMatch;
    937             boolean tagAll;
    938             boolean valueAll;
    939             boolean valueBool;
    940 
    941             private static Pattern getPattern(String str) {
    942                 if (str.endsWith("/i"))
    943                     return Pattern.compile(str.substring(1, str.length()-2), Pattern.CASE_INSENSITIVE);
    944                 if (str.endsWith("/"))
    945                     return Pattern.compile(str.substring(1, str.length()-1));
    946 
    947                 throw new IllegalStateException();
    948             }
    949 
    950             CheckerElement(String exp) {
    951                 Matcher m = Pattern.compile("(.+)([!=]=)(.+)").matcher(exp);
    952                 m.matches();
    953 
    954                 String n = m.group(1).trim();
    955 
    956                 if ("*".equals(n)) {
    957                     tagAll = true;
    958                 } else {
    959                     tag = n.startsWith("/") ? getPattern(n) : n;
    960                     noMatch = "!=".equals(m.group(2));
    961                     n = m.group(3).trim();
    962                     switch (n) {
    963                     case "*": valueAll = true; break;
    964                     case "BOOLEAN_TRUE":
    965                         valueBool = true;
    966                         value = OsmUtils.TRUE_VALUE;
    967                         break;
    968                     case "BOOLEAN_FALSE":
    969                         valueBool = true;
    970                         value = OsmUtils.FALSE_VALUE;
    971                         break;
    972                     default:
    973                         value = n.startsWith("/") ? getPattern(n) : n;
    974                     }
    975                 }
    976             }
    977 
    978             boolean match(Map<String, String> keys) {
    979                 for (Entry<String, String> prop: keys.entrySet()) {
    980                     String key = prop.getKey();
    981                     String val = valueBool ? OsmUtils.getNamedOsmBoolean(prop.getValue()) : prop.getValue();
    982                     if ((tagAll || (tag instanceof Pattern ? ((Pattern) tag).matcher(key).matches() : key.equals(tag)))
    983                             && (valueAll || (value instanceof Pattern ? ((Pattern) value).matcher(val).matches() : val.equals(value))))
    984                         return !noMatch;
    985                 }
    986                 return noMatch;
    987             }
    988         }
    989 
    990         private static final Pattern CLEAN_STR_PATTERN = Pattern.compile(" *# *([^#]+) *$");
    991         private static final Pattern SPLIT_TRIMMED_PATTERN = Pattern.compile(" *: *");
    992         private static final Pattern SPLIT_ELEMENTS_PATTERN = Pattern.compile(" *&& *");
    993 
    994         public String getData(final String str) {
    995             Matcher m = CLEAN_STR_PATTERN.matcher(str);
    996             String trimmed = m.replaceFirst("").trim();
    997             try {
    998                 description = m.group(1);
    999                 if (description != null && description.isEmpty()) {
    1000                     description = null;
    1001                 }
    1002             } catch (IllegalStateException e) {
    1003                 Logging.error(e);
    1004                 description = null;
    1005             }
    1006             String[] n = SPLIT_TRIMMED_PATTERN.split(trimmed, 3);
    1007             switch (n[0]) {
    1008             case "way":
    1009                 type = OsmPrimitiveType.WAY;
    1010                 break;
    1011             case "node":
    1012                 type = OsmPrimitiveType.NODE;
    1013                 break;
    1014             case "relation":
    1015                 type = OsmPrimitiveType.RELATION;
    1016                 break;
    1017             case "*":
    1018                 type = null;
    1019                 break;
    1020             default:
    1021                 return tr("Could not find element type");
    1022             }
    1023             if (n.length != 3)
    1024                 return tr("Incorrect number of parameters");
    1025 
    1026             switch (n[1]) {
    1027             case "W":
    1028                 severity = Severity.WARNING;
    1029                 level = TagCheckLevel.TAG_CHECK_WARN;
    1030                 break;
    1031             case "E":
    1032                 severity = Severity.ERROR;
    1033                 level = TagCheckLevel.TAG_CHECK_ERROR;
    1034                 break;
    1035             case "I":
    1036                 severity = Severity.OTHER;
    1037                 level = TagCheckLevel.TAG_CHECK_INFO;
    1038                 break;
    1039             default:
    1040                 return tr("Could not find warning level");
    1041             }
    1042             for (String exp: SPLIT_ELEMENTS_PATTERN.split(n[2])) {
    1043                 try {
    1044                     data.add(new CheckerElement(exp));
    1045                 } catch (IllegalStateException e) {
    1046                     Logging.trace(e);
    1047                     return tr("Illegal expression ''{0}''", exp);
    1048                 } catch (PatternSyntaxException e) {
    1049                     Logging.trace(e);
    1050                     return tr("Illegal regular expression ''{0}''", exp);
    1051                 }
    1052             }
    1053             return null;
    1054         }
    1055 
    1056         public boolean match(OsmPrimitive osm, Map<String, String> keys) {
    1057             if (type != null && OsmPrimitiveType.from(osm) != type)
    1058                 return false;
    1059 
    1060             for (CheckerElement ce : data) {
    1061                 if (!ce.match(keys))
    1062                     return false;
    1063             }
    1064             return true;
    1065         }
    1066 
    1067         /**
    1068          * Returns the error description.
    1069          * @return the error description
    1070          */
    1071         public String getDescription() {
    1072             return description;
    1073         }
    1074 
    1075         /**
    1076          * Returns the error severity.
    1077          * @return the error severity
    1078          */
    1079         public Severity getSeverity() {
    1080             return severity;
    1081         }
    1082 
    1083         /**
    1084          * Returns the error code.
    1085          * @return the error code
    1086          */
    1087         public int getCode() {
    1088             if (type == null)
    1089                 return level.code;
    1090 
    1091             return level.code + type.ordinal() + 1;
    1092         }
    1093     }
    1094890}
Note: See TracChangeset for help on using the changeset viewer.