diff --git a/src/org/openstreetmap/josm/data/validation/ValidationTask.java b/src/org/openstreetmap/josm/data/validation/ValidationTask.java
index 02b857898..dbf80fb39 100644
|
a
|
b
|
package org.openstreetmap.josm.data.validation;
|
| 3 | 3 | |
| 4 | 4 | import org.openstreetmap.josm.data.osm.OsmPrimitive; |
| 5 | 5 | import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper; |
| | 6 | import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker; |
| 6 | 7 | import org.openstreetmap.josm.gui.MainApplication; |
| 7 | 8 | import org.openstreetmap.josm.gui.MapFrame; |
| 8 | 9 | import org.openstreetmap.josm.gui.PleaseWaitRunnable; |
| … |
… |
import org.openstreetmap.josm.gui.layer.ValidatorLayer;
|
| 10 | 11 | import org.openstreetmap.josm.gui.progress.ProgressMonitor; |
| 11 | 12 | import org.openstreetmap.josm.gui.progress.swing.PleaseWaitProgressMonitor; |
| 12 | 13 | import org.openstreetmap.josm.gui.util.GuiHelper; |
| | 14 | import org.openstreetmap.josm.tools.Logging; |
| | 15 | import org.openstreetmap.josm.tools.Utils; |
| 13 | 16 | |
| 14 | 17 | import java.util.ArrayList; |
| 15 | 18 | import java.util.Collection; |
| 16 | 19 | import java.util.List; |
| | 20 | import java.util.concurrent.ExecutionException; |
| | 21 | import java.util.concurrent.ForkJoinPool; |
| | 22 | import java.util.concurrent.Future; |
| | 23 | import java.util.concurrent.atomic.AtomicInteger; |
| | 24 | import java.util.function.Consumer; |
| | 25 | import java.util.stream.Collectors; |
| 17 | 26 | |
| 18 | 27 | import static org.openstreetmap.josm.tools.I18n.tr; |
| 19 | 28 | |
| … |
… |
import static org.openstreetmap.josm.tools.I18n.tr;
|
| 21 | 30 | * Asynchronous task for running a collection of tests against a collection of primitives |
| 22 | 31 | */ |
| 23 | 32 | public class ValidationTask extends PleaseWaitRunnable { |
| 24 | | private Collection<Test> tests; |
| | 33 | private final ArrayList<Test> tests; |
| 25 | 34 | private final Collection<OsmPrimitive> validatedPrimitives; |
| 26 | 35 | private final Collection<OsmPrimitive> formerValidatedPrimitives; |
| 27 | 36 | private boolean canceled; |
| 28 | 37 | private List<TestError> errors; |
| | 38 | private static final ForkJoinPool THREAD_POOL = Utils.newForkJoinPool( |
| | 39 | ValidatorPrefHelper.PREFIX + ".numberOfThreads", "validator-%d", Thread.NORM_PRIORITY); |
| 29 | 40 | |
| 30 | 41 | /** |
| 31 | 42 | * Constructs a new {@code ValidationTask} |
| … |
… |
public class ValidationTask extends PleaseWaitRunnable {
|
| 47 | 58 | super(tr("Validating"), progressMonitor, false /*don't ignore exceptions */); |
| 48 | 59 | this.validatedPrimitives = validatedPrimitives; |
| 49 | 60 | this.formerValidatedPrimitives = formerValidatedPrimitives; |
| 50 | | this.tests = tests; |
| | 61 | this.tests = new ArrayList<>(tests); |
| 51 | 62 | } |
| 52 | 63 | |
| 53 | 64 | @Override |
| … |
… |
public class ValidationTask extends PleaseWaitRunnable {
|
| 77 | 88 | if (tests == null || tests.isEmpty()) |
| 78 | 89 | return; |
| 79 | 90 | errors = new ArrayList<>(); |
| 80 | | getProgressMonitor().setTicksCount(tests.size() * validatedPrimitives.size()); |
| 81 | | int testCounter = 0; |
| 82 | | for (Test test : tests) { |
| 83 | | if (canceled) |
| 84 | | return; |
| 85 | | testCounter++; |
| 86 | | getProgressMonitor().setCustomText(tr("Test {0}/{1}: Starting {2}", testCounter, tests.size(), test.getName())); |
| | 91 | |
| | 92 | AtomicInteger testCounter = new AtomicInteger(); |
| | 93 | runParallel(test -> { |
| 87 | 94 | test.setBeforeUpload(false); |
| 88 | 95 | test.setPartialSelection(formerValidatedPrimitives != null); |
| 89 | | test.startTest(getProgressMonitor().createSubTaskMonitor(validatedPrimitives.size(), false)); |
| 90 | | test.visit(validatedPrimitives); |
| 91 | | test.endTest(); |
| 92 | | errors.addAll(test.getErrors()); |
| 93 | | test.clear(); |
| 94 | | } |
| 95 | | tests = null; |
| | 96 | test.startTest(null); |
| | 97 | }); |
| | 98 | runParallel(test -> { |
| | 99 | getProgressMonitor().setCustomText(tr("Test {0}/{1}: Starting {2}", testCounter.incrementAndGet(), tests.size(), test.getName())); |
| | 100 | if (test instanceof MapCSSTagChecker) { |
| | 101 | // VARIANT 1 |
| | 102 | validatedPrimitives.parallelStream() |
| | 103 | .filter(test::isPrimitiveUsable) |
| | 104 | .forEach(p -> p.accept(test)); |
| | 105 | } else { |
| | 106 | test.visit(validatedPrimitives); |
| | 107 | } |
| | 108 | }); |
| | 109 | runParallel(Test::endTest); |
| | 110 | errors = tests.stream().flatMap(test -> test.getErrors().stream()).collect(Collectors.toList()); |
| | 111 | |
| | 112 | runParallel(Test::clear); |
| | 113 | tests.clear(); |
| | 114 | tests.trimToSize(); |
| | 115 | |
| 96 | 116 | if (Boolean.TRUE.equals(ValidatorPrefHelper.PREF_USE_IGNORE.get())) { |
| 97 | 117 | getProgressMonitor().setCustomText(""); |
| 98 | 118 | getProgressMonitor().subTask(tr("Updating ignored errors ...")); |
| … |
… |
public class ValidationTask extends PleaseWaitRunnable {
|
| 103 | 123 | } |
| 104 | 124 | } |
| 105 | 125 | |
| | 126 | private void runParallel(Consumer<Test> testConsumer) { |
| | 127 | try { |
| | 128 | Future<?> future = THREAD_POOL.submit(() -> tests.parallelStream().forEach(testConsumer)); |
| | 129 | future.get(); |
| | 130 | } catch (InterruptedException | ExecutionException e) { |
| | 131 | if (e.getCause() instanceof RuntimeException) { |
| | 132 | throw ((RuntimeException) e.getCause()); |
| | 133 | } |
| | 134 | Logging.warn(e); |
| | 135 | Thread.currentThread().interrupt(); |
| | 136 | } |
| | 137 | } |
| | 138 | |
| 106 | 139 | /** |
| 107 | 140 | * Gets the validation errors accumulated until this moment. |
| 108 | 141 | * @return The list of errors |
diff --git a/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java b/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
index bf38cd13f..2442933c3 100644
|
a
|
b
|
public class MapCSSTagChecker extends Test.TagTest {
|
| 238 | 238 | */ |
| 239 | 239 | @Override |
| 240 | 240 | public void check(OsmPrimitive p) { |
| 241 | | for (TestError e : getErrorsForPrimitive(p, ValidatorPrefHelper.PREF_OTHER.get())) { |
| 242 | | addIfNotSimilar(e, errors); |
| | 241 | Collection<TestError> errorsForPrimitive = getErrorsForPrimitive(p, ValidatorPrefHelper.PREF_OTHER.get()); |
| | 242 | if (errorsForPrimitive.isEmpty()) { |
| | 243 | return; |
| | 244 | } |
| | 245 | synchronized (errors) { |
| | 246 | for (TestError e : errorsForPrimitive) { |
| | 247 | addIfNotSimilar(e, errors); |
| | 248 | } |
| 243 | 249 | } |
| 244 | 250 | } |
| 245 | 251 | |
| … |
… |
public class MapCSSTagChecker extends Test.TagTest {
|
| 382 | 388 | mpAreaCache.clear(); |
| 383 | 389 | |
| 384 | 390 | Set<OsmPrimitive> surrounding = new HashSet<>(); |
| 385 | | for (Entry<String, Set<MapCSSTagCheckerRule>> entry : checks.entrySet()) { |
| | 391 | // VARIANT 2 |
| | 392 | checks.entrySet().parallelStream().forEach(entry -> { |
| 386 | 393 | if (isCanceled()) { |
| 387 | | break; |
| | 394 | return; |
| 388 | 395 | } |
| 389 | 396 | if (urlPredicate != null && !urlPredicate.test(entry.getKey())) { |
| 390 | | continue; |
| | 397 | return; |
| 391 | 398 | } |
| 392 | 399 | visit(entry.getKey(), entry.getValue(), selection, surrounding); |
| 393 | | } |
| | 400 | }); |
| 394 | 401 | } |
| 395 | 402 | |
| 396 | 403 | /** |
| … |
… |
public class MapCSSTagChecker extends Test.TagTest {
|
| 464 | 471 | if (tested.contains(p)) |
| 465 | 472 | continue; |
| 466 | 473 | Collection<TestError> additionalErrors = getErrorsForPrimitive(p, includeOtherSeverity); |
| 467 | | for (TestError e : additionalErrors) { |
| 468 | | if (e.getPrimitives().stream().anyMatch(tested::contains)) |
| 469 | | addIfNotSimilar(e, errors); |
| | 474 | if (additionalErrors.isEmpty()) |
| | 475 | continue; |
| | 476 | synchronized (errors) { |
| | 477 | for (TestError e : additionalErrors) { |
| | 478 | if (e.getPrimitives().stream().anyMatch(tested::contains)) { |
| | 479 | addIfNotSimilar(e, errors); |
| | 480 | } |
| | 481 | } |
| 470 | 482 | } |
| 471 | 483 | } |
| 472 | 484 | |