Ticket #13805: 13805-grouped.2.patch

File 13805-grouped.2.patch, 8.4 KB (added by GerdP, 4 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

     
    1717import java.util.LinkedList;
    1818import java.util.List;
    1919import java.util.Map;
     20import java.util.Map.Entry;
    2021import java.util.Objects;
    2122import java.util.Optional;
    2223import java.util.Set;
     
    6667import org.openstreetmap.josm.tools.I18n;
    6768import org.openstreetmap.josm.tools.Logging;
    6869import org.openstreetmap.josm.tools.MultiMap;
     70import org.openstreetmap.josm.tools.Stopwatch;
    6971import org.openstreetmap.josm.tools.Utils;
    7072
    7173/**
     
    7577public class MapCSSTagChecker extends Test.TagTest {
    7678    private MapCSSStyleIndex indexData;
    7779    final Map<MapCSSRule, MapCSSTagCheckerAndRule> ruleToCheckMap = new HashMap<>();
    78     private final Set<OsmPrimitive> tested = new HashSet<>();
    7980    private static final Map<IPrimitive, Area> mpAreaCache = new HashMap<>();
    8081    static final boolean ALL_TESTS = true;
    8182    static final boolean ONLY_SELECTED_TESTS = false;
     
    203204
    204205    final MultiMap<String, TagCheck> checks = new MultiMap<>();
    205206
     207    /** maps the source URL for a test to the title shown in the dialog where known */
     208    private final Map<String, String> urlTitles = new HashMap<>();
     209
    206210    /**
    207211     * Result of {@link TagCheck#readMapCSS}
    208212     * @since 8936
     
    617621
    618622        @Override
    619623        public String getSource() {
    620             return tr("URL / File: {0}", source);
     624            return source;
    621625        }
    622626    }
    623627
     
    661665                                // rule.selectors might be different due to MapCSSStyleIndex, however, the declarations are the same object
    662666                                .filter(c -> c.rule.declaration == rule.declaration)
    663667                                .findFirst()
    664                                 .map(c -> new MapCSSTagCheckerAndRule(c, e.getKey()))
     668                                .map(c -> new MapCSSTagCheckerAndRule(c, getTitle(e.getKey())))
    665669                                .orElse(null))
    666670                        .filter(Objects::nonNull)
    667671                        .findFirst()
     
    680684        return res;
    681685    }
    682686
     687    private String getTitle(String url) {
     688        return urlTitles.getOrDefault(url, tr("unknown"));
     689    }
     690
    683691    /**
    684692     * See #12627
    685693     * Add error to given list if list doesn't already contain a similar error.
     
    749757        for (TestError e : getErrorsForPrimitive(p, ValidatorPrefHelper.PREF_OTHER.get())) {
    750758            addIfNotSimilar(e, errors);
    751759        }
    752         if (partialSelection) {
    753             tested.add(p);
    754         }
    755760    }
    756761
    757762    /**
     
    787792            result = TagCheck.readMapCSS(reader, assertionConsumer);
    788793            checks.remove(url);
    789794            checks.putAll(url, result.parseChecks);
     795            for (SourceEntry source : new ValidatorPrefHelper().get()) {
     796                if (url.equals(source.url)) {
     797                    urlTitles.put(url, source.title);
     798                    break;
     799                }
     800            }
    790801            indexData = null;
    791802        }
    792803        return result;
     
    795806    @Override
    796807    public synchronized void initialize() throws Exception {
    797808        checks.clear();
     809        urlTitles.clear();
    798810        indexData = null;
    799811        for (SourceEntry source : new ValidatorPrefHelper().get()) {
    800812            if (!source.active) {
     
    842854    public synchronized void startTest(ProgressMonitor progressMonitor) {
    843855        super.startTest(progressMonitor);
    844856        super.setShowElements(true);
    845         if (indexData == null) {
    846             indexData = createMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), ALL_TESTS);
     857    }
     858
     859    @Override
     860    public synchronized void endTest() {
     861        // no need to keep the index, it is quickly build and doubles the memory needs
     862        indexData = null;
     863        // always clear the cache to make sure that we catch changes in geometry
     864        mpAreaCache.clear();
     865        super.endTest();
     866    }
     867
     868    @Override
     869    public void visit(Collection<OsmPrimitive> selection) {
     870        if (progressMonitor != null) {
     871            progressMonitor.setTicksCount(selection.size() * checks.size());
    847872        }
    848         tested.clear();
     873
    849874        mpAreaCache.clear();
     875
     876        Set<OsmPrimitive> surrounding = new HashSet<>();
     877        for (Entry<String, Set<TagCheck>> entry : checks.entrySet()) {
     878            if (isCanceled()) {
     879                break;
     880            }
     881            visit(entry.getKey(), entry.getValue(), selection, surrounding);
     882        }
    850883    }
    851884
    852     @Override
    853     public synchronized void endTest() {
     885    /**
     886     * Perform the checks for one check url
     887     * @param url the url for the checks
     888     * @param checksForUrl the checks to perform
     889     * @param selection collection primitives
     890     * @param surrounding surrounding primitives, evtl. filled by this routine
     891     */
     892    private void visit(String url, Set<TagCheck> checksForUrl, Collection<OsmPrimitive> selection,
     893            Set<OsmPrimitive> surrounding) {
     894        MultiMap<String, TagCheck> currentCheck = new MultiMap<>();
     895        currentCheck.putAll(url, checksForUrl);
     896        indexData = createMapCSSTagCheckerIndex(currentCheck, includeOtherSeverityChecks(), ALL_TESTS);
     897        Set<OsmPrimitive> tested = new HashSet<>();
     898
     899
     900        String title = getTitle(url);
     901        if (progressMonitor != null) {
     902            progressMonitor.setExtraText(tr(" {0}", title));
     903        }
     904        long cnt = 0;
     905        Stopwatch stopwatch = Stopwatch.createStarted();
     906        for (OsmPrimitive p : selection) {
     907            if (isCanceled()) {
     908                break;
     909            }
     910            if (isPrimitiveUsable(p)) {
     911                check(p);
     912                if (partialSelection) {
     913                    tested.add(p);
     914                }
     915            }
     916            if (progressMonitor != null) {
     917                progressMonitor.worked(1);
     918                cnt++;
     919                // add frequently changing info to progress monitor so that it
     920                // doesn't seem to hang when test takes longer than 0.5 seconds
     921                if (cnt % 10000 == 0 && stopwatch.elapsed() >= 500) {
     922                    progressMonitor.setExtraText(tr(" {0}: {1} of {2} elements done", title, cnt, selection.size()));
     923                }
     924            }
     925        }
     926
    854927        if (partialSelection && !tested.isEmpty()) {
    855928            // #14287: see https://josm.openstreetmap.de/ticket/14287#comment:15
    856929            // execute tests for objects which might contain or cross previously tested elements
     
    857930
    858931            // rebuild index with a reduced set of rules (those that use ChildOrParentSelector) and thus may have left selectors
    859932            // matching the previously tested elements
    860             indexData = createMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), ONLY_SELECTED_TESTS);
     933            indexData = createMapCSSTagCheckerIndex(currentCheck, includeOtherSeverityChecks(), ONLY_SELECTED_TESTS);
    861934
    862             Set<OsmPrimitive> surrounding = new HashSet<>();
    863             for (OsmPrimitive p : tested) {
    864                 if (p.getDataSet() != null) {
    865                     surrounding.addAll(p.getDataSet().searchWays(p.getBBox()));
    866                     surrounding.addAll(p.getDataSet().searchRelations(p.getBBox()));
     935            if (surrounding.isEmpty()) {
     936                for (OsmPrimitive p : tested) {
     937                    if (p.getDataSet() != null) {
     938                        surrounding.addAll(p.getDataSet().searchWays(p.getBBox()));
     939                        surrounding.addAll(p.getDataSet().searchRelations(p.getBBox()));
     940                    }
    867941                }
    868942            }
     943
    869944            final boolean includeOtherSeverity = includeOtherSeverityChecks();
    870945            for (OsmPrimitive p : surrounding) {
    871946                if (tested.contains(p))
     
    876951                        addIfNotSimilar(e, errors);
    877952                }
    878953            }
    879             tested.clear();
    880954        }
    881         // no need to keep the index, it is quickly build and doubles the memory needs
    882         indexData = null;
    883         // always clear the cache to make sure that we catch changes in geometry
    884         mpAreaCache.clear();
    885         super.endTest();
    886955    }
     956
    887957}