Ticket #21423: 21423.2.patch

File 21423.2.patch, 10.8 KB (added by taylor.smock, 3 years ago)

Prepend hashcode of tester class name to error code. Contains compatibility code (not well tested), new errors are saved with the new code, old errors will be migrated starting 2024 (to allow users to move between tested/latest versions)

  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/validation/OsmValidator.java b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
    a b  
    246246
    247247    private static void removeLegacyEntries(boolean force) {
    248248        // see #19053:
     249        boolean wasChanged = removeLegacyEntry(force, true, "3000");
     250        // see #18230 (pt_assistant, RightAngleBuildingTest)
     251        wasChanged |= removeLegacyEntry(force, false, "3701");
     252
     253        if (wasChanged) {
     254            saveIgnoredErrors();
     255        }
     256    }
     257
     258    private static boolean removeLegacyEntry(boolean force, boolean keep, String prefix) {
    249259        boolean wasChanged = false;
    250260        if (force) {
    251261            Iterator<Entry<String, String>> iter = ignoredErrors.entrySet().iterator();
    252262            while (iter.hasNext()) {
    253263                Entry<String, String> entry = iter.next();
    254                 if (entry.getKey().startsWith("3000_")) {
     264                if (entry.getKey().startsWith(prefix + "_")) {
    255265                    Logging.warn(tr("Cannot handle ignore list entry {0}", entry));
    256266                    iter.remove();
    257267                    wasChanged = true;
    258268                }
    259269            }
    260270        }
    261         String legacyEntry = ignoredErrors.remove("3000");
    262         if (legacyEntry != null) {
     271        String legacyEntry = ignoredErrors.remove(prefix);
     272        if (keep && legacyEntry != null) {
    263273            if (!legacyEntry.isEmpty()) {
    264                 addIgnoredError("3000_" + legacyEntry, legacyEntry);
     274                addIgnoredError(prefix + "_" + legacyEntry, legacyEntry);
    265275            }
    266276            wasChanged = true;
    267277        }
    268         if (wasChanged) {
    269             saveIgnoredErrors();
    270         }
     278        return wasChanged;
    271279    }
    272280
    273281    /**
     
    502510        List<Map<String, String>> list = new ArrayList<>();
    503511        cleanupIgnoredErrors();
    504512        ignoredErrors.remove("3000"); // see #19053
     513        ignoredErrors.remove("3701"); // see #18230
    505514        list.add(ignoredErrors);
    506515        int i = 0;
    507516        while (i < list.size()) {
  • src/org/openstreetmap/josm/data/validation/TestError.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/validation/TestError.java b/src/org/openstreetmap/josm/data/validation/TestError.java
    a b  
    44import java.awt.geom.Area;
    55import java.awt.geom.PathIterator;
    66import java.text.MessageFormat;
     7import java.time.Instant;
    78import java.util.ArrayList;
    89import java.util.Arrays;
    910import java.util.Collection;
    1011import java.util.Collections;
    1112import java.util.List;
    1213import java.util.Locale;
     14import java.util.Map;
    1315import java.util.TreeSet;
    1416import java.util.function.Supplier;
    1517import java.util.stream.Collectors;
     
    3335 * @since 3669
    3436 */
    3537public class TestError implements Comparable<TestError> {
     38    /**
     39     * Used to switch users over to new ignore system, UNIQUE_CODE_MESSAGE_STATE
     40     * 1_704_067_200L -> 2024-01-01
     41     * We can probably remove this and the supporting code in 2025.
     42     */
     43    private static final boolean SWITCH_OVER = Instant.now().isAfter(Instant.ofEpochMilli(1_704_067_200L));
    3644    /** is this error on the ignore list */
    3745    private boolean ignored;
    3846    /** Severity */
     
    5058    private final Test tester;
    5159    /** Internal code used by testers to classify errors */
    5260    private final int code;
     61    /** Internal code used by testers to classify errors. Used for moving between JOSM versions. */
     62    private final int uniqueCode;
    5363    /** If this error is selected */
    5464    private boolean selected;
    5565    /** Supplying a command to fix the error */
     
    6373        private final Test tester;
    6474        private final Severity severity;
    6575        private final int code;
     76        private final int uniqueCode;
    6677        private String message;
    6778        private String description;
    6879        private String descriptionEn;
     
    7485            this.tester = tester;
    7586            this.severity = severity;
    7687            this.code = code;
     88            this.uniqueCode = this.tester.getClass().getName().hashCode();
    7789        }
    7890
    7991        /**
     
    254266        this.primitives = builder.primitives;
    255267        this.highlighted = builder.highlighted;
    256268        this.code = builder.code;
     269        this.uniqueCode = builder.uniqueCode;
    257270        this.fixingCommand = builder.fixingCommand;
    258271    }
    259272
     
    306319     * @return the ignore state for this error or null if any primitive is new
    307320     */
    308321    public String getIgnoreState() {
     322        return getIgnoreState(false);
     323    }
     324    private String getIgnoreState(boolean useOriginal) {
    309325        Collection<String> strings = new TreeSet<>();
    310326        for (OsmPrimitive o : primitives) {
    311327            // ignore data not yet uploaded
     
    321337            }
    322338            strings.add(type + '_' + o.getId());
    323339        }
    324         return strings.stream().map(o -> ':' + o).collect(Collectors.joining("", getIgnoreSubGroup(), ""));
     340        return strings.stream().map(o -> ':' + o).collect(Collectors.joining("", getIgnoreSubGroup(useOriginal), ""));
    325341    }
    326342
    327343    /**
     
    335351    }
    336352
    337353    private boolean calcIgnored() {
     354        // Begin code removal section (backwards compatibility)
     355        if (OsmValidator.hasIgnoredError(getIgnoreGroup(true))) {
     356            updateIgnoreList(getIgnoreGroup(true), getIgnoreGroup(false));
     357            return true;
     358        }
     359        if (OsmValidator.hasIgnoredError(getIgnoreSubGroup(true))) {
     360            updateIgnoreList(getIgnoreSubGroup(true), getIgnoreSubGroup(false));
     361            return true;
     362        }
     363        String oldState = getIgnoreState(true);
     364        String state = getIgnoreState(false);
     365        if (oldState != null && OsmValidator.hasIgnoredError(oldState)) {
     366            updateIgnoreList(oldState, state);
     367            return true;
     368        }
     369        // End code removal section
    338370        if (OsmValidator.hasIgnoredError(getIgnoreGroup()))
    339371            return true;
    340372        if (OsmValidator.hasIgnoredError(getIgnoreSubGroup()))
    341373            return true;
    342         String state = getIgnoreState();
    343374        return state != null && OsmValidator.hasIgnoredError(state);
    344375    }
    345376
     377    /**
     378     * Convert old keys to new keys. Only takes effect when {@link #SWITCH_OVER} is true
     379     * @param oldKey The key to replace
     380     * @param newKey The new key
     381     */
     382    private static void updateIgnoreList(String oldKey, String newKey) {
     383        if (SWITCH_OVER) {
     384            Map<String, String> errors = OsmValidator.getIgnoredErrors();
     385            if (errors.containsKey(oldKey)) {
     386                String value = errors.remove(oldKey);
     387                errors.put(newKey, value);
     388            }
     389        }
     390    }
     391
    346392    /**
    347393     * Gets the ignores subgroup that is more specialized than {@link #getIgnoreGroup()}
    348394     * @return The ignore sub group
    349395     */
    350396    public String getIgnoreSubGroup() {
     397        return getIgnoreSubGroup(false);
     398    }
     399
     400    private String getIgnoreSubGroup(boolean useOriginal) {
    351401        if (code == 3000) {
    352402            // see #19053
    353403            return "3000_" + (description == null ? message : description);
    354404        }
    355         String ignorestring = getIgnoreGroup();
     405        String ignorestring = getIgnoreGroup(useOriginal);
    356406        if (descriptionEn != null) {
    357407            ignorestring += '_' + descriptionEn;
    358408        }
     
    365415     * @see TestError#getIgnoreSubGroup()
    366416     */
    367417    public String getIgnoreGroup() {
     418        return getIgnoreGroup(false);
     419    }
     420
     421    private String getIgnoreGroup(boolean useOriginal) {
    368422        if (code == 3000) {
    369423            // see #19053
    370424            return "3000_" + getMessage();
    371425        }
    372         return Integer.toString(code);
     426        if (useOriginal) {
     427            return Integer.toString(this.code);
     428        }
     429        return this.uniqueCode + "_" + this.code;
    373430    }
    374431
    375432    /**
     
    404461        return code;
    405462    }
    406463
     464    /**
     465     * Get the unique code for this test. Used for ignore lists.
     466     * @return The unique code (generated with {@code tester.getClass().getName().hashCode() + code}).
     467     * @since xxx
     468     */
     469    public int getUniqueCode() {
     470        return this.uniqueCode;
     471    }
     472
    407473    /**
    408474     * Returns true if the error can be fixed automatically
    409475     *
     
    546612     * @return true if two errors are similar
    547613     */
    548614    public boolean isSimilar(TestError other) {
    549         return getCode() == other.getCode()
     615        return getUniqueCode() == other.getUniqueCode()
     616                && getCode() == other.getCode()
    550617                && getMessage().equals(other.getMessage())
    551618                && getPrimitives().size() == other.getPrimitives().size()
    552619                && getPrimitives().containsAll(other.getPrimitives())
     
    570637
    571638    @Override
    572639    public String toString() {
    573         return "TestError [tester=" + tester + ", code=" + code + ", message=" + message + ']';
     640        return "TestError [tester=" + tester + ", unique code=" + this.uniqueCode +
     641                ", code=" + code + ", message=" + message + ']';
    574642    }
    575643
    576644}
  • src/org/openstreetmap/josm/io/GeoJSONMapRouletteWriter.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/io/GeoJSONMapRouletteWriter.java b/src/org/openstreetmap/josm/io/GeoJSONMapRouletteWriter.java
    a b  
    4545        final JsonObjectBuilder propertiesBuilder = Json.createObjectBuilder();
    4646        propertiesBuilder.add("message", testError.getMessage());
    4747        Optional.ofNullable(testError.getDescription()).ifPresent(description -> propertiesBuilder.add("description", description));
    48         propertiesBuilder.add("code", testError.getCode());
     48        propertiesBuilder.add("code", testError.getUniqueCode());
    4949        propertiesBuilder.add("fixable", testError.isFixable());
    5050        propertiesBuilder.add("severity", testError.getSeverity().toString());
    5151        propertiesBuilder.add("severityInteger", testError.getSeverity().getLevel());