source: josm/trunk/src/org/openstreetmap/josm/actions/ValidateAction.java@ 12346

Last change on this file since 12346 was 12211, checked in by michael2402, 7 years ago

Invalidate the validation layer after a valdiation finished.

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.event.ActionEvent;
7import java.awt.event.KeyEvent;
8import java.io.IOException;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.List;
12import java.util.Optional;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.data.validation.OsmValidator;
17import org.openstreetmap.josm.data.validation.Test;
18import org.openstreetmap.josm.data.validation.TestError;
19import org.openstreetmap.josm.data.validation.util.AggregatePrimitivesVisitor;
20import org.openstreetmap.josm.gui.PleaseWaitRunnable;
21import org.openstreetmap.josm.gui.layer.ValidatorLayer;
22import org.openstreetmap.josm.gui.preferences.validator.ValidatorPreference;
23import org.openstreetmap.josm.gui.util.GuiHelper;
24import org.openstreetmap.josm.io.OsmTransferException;
25import org.openstreetmap.josm.tools.Shortcut;
26import org.xml.sax.SAXException;
27
28/**
29 * The action that does the validate thing.
30 * <p>
31 * This action iterates through all active tests and give them the data, so that
32 * each one can test it.
33 *
34 * @author frsantos
35 */
36public class ValidateAction extends JosmAction {
37
38 /** Last selection used to validate */
39 private transient Collection<OsmPrimitive> lastSelection;
40
41 /**
42 * Constructor
43 */
44 public ValidateAction() {
45 super(tr("Validation"), "dialogs/validator", tr("Performs the data validation"),
46 Shortcut.registerShortcut("tools:validate", tr("Tool: {0}", tr("Validation")),
47 KeyEvent.VK_V, Shortcut.SHIFT), true);
48 }
49
50 @Override
51 public void actionPerformed(ActionEvent ev) {
52 doValidate(true);
53 }
54
55 /**
56 * Does the validation.
57 * <p>
58 * If getSelectedItems is true, the selected items (or all items, if no one
59 * is selected) are validated. If it is false, last selected items are revalidated
60 *
61 * @param getSelectedItems If selected or last selected items must be validated
62 */
63 public void doValidate(boolean getSelectedItems) {
64 if (Main.map == null || !Main.map.isVisible())
65 return;
66
67 OsmValidator.initializeTests();
68 OsmValidator.initializeErrorLayer();
69
70 Collection<Test> tests = OsmValidator.getEnabledTests(false);
71 if (tests.isEmpty())
72 return;
73
74 Collection<OsmPrimitive> selection;
75 if (getSelectedItems) {
76 selection = Main.getLayerManager().getEditDataSet().getAllSelected();
77 if (selection.isEmpty()) {
78 selection = Main.getLayerManager().getEditDataSet().allNonDeletedPrimitives();
79 lastSelection = null;
80 } else {
81 AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor();
82 selection = v.visit(selection);
83 lastSelection = selection;
84 }
85 } else {
86 selection = Optional.ofNullable(lastSelection).orElseGet(
87 () -> Main.getLayerManager().getEditDataSet().allNonDeletedPrimitives());
88 }
89
90 Main.worker.submit(new ValidationTask(tests, selection, lastSelection));
91 }
92
93 @Override
94 public void updateEnabledState() {
95 setEnabled(getLayerManager().getEditLayer() != null);
96 }
97
98 @Override
99 public void destroy() {
100 // Hack - this action should stay forever because it could be added to toolbar
101 // Do not call super.destroy() here
102 }
103
104 /**
105 * Asynchronous task for running a collection of tests against a collection
106 * of primitives
107 *
108 */
109 static class ValidationTask extends PleaseWaitRunnable {
110 private Collection<Test> tests;
111 private final Collection<OsmPrimitive> validatedPrimitives;
112 private final Collection<OsmPrimitive> formerValidatedPrimitives;
113 private boolean canceled;
114 private List<TestError> errors;
115
116 /**
117 *
118 * @param tests the tests to run
119 * @param validatedPrimitives the collection of primitives to validate.
120 * @param formerValidatedPrimitives the last collection of primitives being validates. May be null.
121 */
122 ValidationTask(Collection<Test> tests, Collection<OsmPrimitive> validatedPrimitives,
123 Collection<OsmPrimitive> formerValidatedPrimitives) {
124 super(tr("Validating"), false /*don't ignore exceptions */);
125 this.validatedPrimitives = validatedPrimitives;
126 this.formerValidatedPrimitives = formerValidatedPrimitives;
127 this.tests = tests;
128 }
129
130 @Override
131 protected void cancel() {
132 this.canceled = true;
133 }
134
135 @Override
136 protected void finish() {
137 if (canceled) return;
138
139 // update GUI on Swing EDT
140 //
141 GuiHelper.runInEDT(() -> {
142 Main.map.validatorDialog.tree.setErrors(errors);
143 Main.map.validatorDialog.unfurlDialog();
144 //FIXME: nicer way to find / invalidate the corresponding error layer
145 Main.getLayerManager().getLayersOfType(ValidatorLayer.class).forEach(ValidatorLayer::invalidate);
146 });
147 }
148
149 @Override
150 protected void realRun() throws SAXException, IOException,
151 OsmTransferException {
152 if (tests == null || tests.isEmpty())
153 return;
154 errors = new ArrayList<>(200);
155 getProgressMonitor().setTicksCount(tests.size() * validatedPrimitives.size());
156 int testCounter = 0;
157 for (Test test : tests) {
158 if (canceled)
159 return;
160 testCounter++;
161 getProgressMonitor().setCustomText(tr("Test {0}/{1}: Starting {2}", testCounter, tests.size(), test.getName()));
162 test.setPartialSelection(formerValidatedPrimitives != null);
163 test.startTest(getProgressMonitor().createSubTaskMonitor(validatedPrimitives.size(), false));
164 test.visit(validatedPrimitives);
165 test.endTest();
166 errors.addAll(test.getErrors());
167 }
168 tests = null;
169 if (ValidatorPreference.PREF_USE_IGNORE.get()) {
170 getProgressMonitor().subTask(tr("Updating ignored errors ..."));
171 for (TestError error : errors) {
172 if (canceled) return;
173 List<String> s = new ArrayList<>();
174 s.add(error.getIgnoreState());
175 s.add(error.getIgnoreGroup());
176 s.add(error.getIgnoreSubGroup());
177 for (String state : s) {
178 if (state != null && OsmValidator.hasIgnoredError(state)) {
179 error.setIgnored(true);
180 }
181 }
182 }
183 }
184 }
185 }
186}
Note: See TracBrowser for help on using the repository browser.