Changeset 15988 in josm for trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
- Timestamp:
- 2020-03-01T23:36:07+01:00 (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
r15987 r15988 15 15 import java.util.HashSet; 16 16 import java.util.Iterator; 17 import java.util.LinkedHashMap;18 17 import java.util.LinkedList; 19 18 import java.util.List; … … 26 25 import java.util.regex.Matcher; 27 26 import java.util.regex.Pattern; 27 import java.util.stream.Stream; 28 28 29 29 import org.openstreetmap.josm.command.ChangePropertyCommand; … … 47 47 import org.openstreetmap.josm.gui.mappaint.MultiCascade; 48 48 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; 49 import org.openstreetmap.josm.gui.mappaint.mapcss.Declaration;50 49 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression; 51 50 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction; 52 51 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule; 53 52 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource; 54 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource.MapCSSRuleIndex;55 53 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector; 56 54 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; … … 76 74 public class MapCSSTagChecker extends Test.TagTest { 77 75 private MapCSSTagCheckerIndex indexData; 76 final Map<MapCSSRule, MapCSSTagCheckerAndRule> ruleToCheckMap = new HashMap<>(); 78 77 private final Set<OsmPrimitive> tested = new HashSet<>(); 79 78 private static final Map<IPrimitive, Area> mpAreaCache = new HashMap<>(); 80 81 /**82 * A grouped MapCSSRule with multiple selectors for a single declaration.83 * @see MapCSSRule84 */85 public static class GroupedMapCSSRule {86 /** MapCSS selectors **/87 public final List<Selector> selectors;88 /** MapCSS declaration **/89 public final Declaration declaration;90 /** MapCSS source **/91 public final String source;92 93 /**94 * Constructs a new {@code GroupedMapCSSRule} with empty source95 * @param selectors MapCSS selectors96 * @param declaration MapCSS declaration97 */98 public GroupedMapCSSRule(List<Selector> selectors, Declaration declaration) {99 this(selectors, declaration, "");100 }101 102 /**103 * Constructs a new {@code GroupedMapCSSRule}.104 * @param selectors MapCSS selectors105 * @param declaration MapCSS declaration106 * @param source the source of the rule107 */108 public GroupedMapCSSRule(List<Selector> selectors, Declaration declaration, String source) {109 this.selectors = selectors;110 this.declaration = declaration;111 this.source = source;112 }113 114 @Override115 public int hashCode() {116 return Objects.hash(selectors, declaration);117 }118 119 @Override120 public boolean equals(Object obj) {121 if (this == obj) return true;122 if (obj == null || getClass() != obj.getClass()) return false;123 GroupedMapCSSRule that = (GroupedMapCSSRule) obj;124 return Objects.equals(selectors, that.selectors) &&125 Objects.equals(declaration, that.declaration);126 }127 128 @Override129 public String toString() {130 return "GroupedMapCSSRule [selectors=" + selectors + ", declaration=" + declaration + ']';131 }132 }133 79 134 80 /** … … 281 227 public static class TagCheck implements Predicate<OsmPrimitive> { 282 228 /** The selector of this {@code TagCheck} */ 283 protected final GroupedMapCSSRule rule;229 protected final MapCSSRule rule; 284 230 /** Commands to apply in order to fix a matching primitive */ 285 231 protected final List<FixCommand> fixCommands; … … 296 242 protected String group; 297 243 298 TagCheck( GroupedMapCSSRule rule) {244 TagCheck(MapCSSRule rule) { 299 245 this.rule = rule; 300 246 this.fixCommands = new ArrayList<>(); … … 320 266 private static final String POSSIBLE_THROWS = "throwError/throwWarning/throwOther"; 321 267 322 static TagCheck ofMapCSSRule(final GroupedMapCSSRule rule, AssertionConsumer assertionConsumer) throws IllegalDataException {268 static TagCheck ofMapCSSRule(final MapCSSRule rule, AssertionConsumer assertionConsumer) throws IllegalDataException { 323 269 final TagCheck check = new TagCheck(rule); 324 270 final Map<String, Boolean> assertions = new HashMap<>(); … … 394 340 395 341 static ParseResult readMapCSS(Reader css) throws ParseException { 396 return readMapCSS(css, "",null);397 } 398 399 static ParseResult readMapCSS(Reader css, String url,AssertionConsumer assertionConsumer) throws ParseException {342 return readMapCSS(css, null); 343 } 344 345 static ParseResult readMapCSS(Reader css, AssertionConsumer assertionConsumer) throws ParseException { 400 346 CheckParameterUtil.ensureParameterNotNull(css, "css"); 401 347 … … 407 353 // Ignore "meta" rule(s) from external rules of JOSM wiki 408 354 source.removeMetaRules(); 409 // group rules with common declaration block 410 Map<Declaration, List<Selector>> g = new LinkedHashMap<>(); 355 List<TagCheck> parseChecks = new ArrayList<>(); 411 356 for (MapCSSRule rule : source.rules) { 412 if (!g.containsKey(rule.declaration)) {413 List<Selector> sels = new ArrayList<>();414 sels.add(rule.selector);415 g.put(rule.declaration, sels);416 } else {417 g.get(rule.declaration).add(rule.selector);418 }419 }420 List<TagCheck> parseChecks = new ArrayList<>();421 for (Map.Entry<Declaration, List<Selector>> map : g.entrySet()) {422 357 try { 423 parseChecks.add(TagCheck.ofMapCSSRule( 424 new GroupedMapCSSRule(map.getValue(), map.getKey(), url), assertionConsumer)); 358 parseChecks.add(TagCheck.ofMapCSSRule(rule, assertionConsumer)); 425 359 } catch (IllegalDataException e) { 426 360 Logging.error("Cannot add MapCss rule: "+e.getMessage()); … … 661 595 662 596 static class MapCSSTagCheckerAndRule extends MapCSSTagChecker { 663 public final GroupedMapCSSRule rule; 664 665 MapCSSTagCheckerAndRule(GroupedMapCSSRule rule) { 597 public final MapCSSRule rule; 598 private final TagCheck tagCheck; 599 private final String source; 600 601 MapCSSTagCheckerAndRule(MapCSSRule rule) { 666 602 this.rule = rule; 603 this.tagCheck = null; 604 this.source = ""; 605 } 606 607 MapCSSTagCheckerAndRule(TagCheck tagCheck, String source) { 608 this.rule = tagCheck.rule; 609 this.tagCheck = tagCheck; 610 this.source = source; 667 611 } 668 612 … … 674 618 @Override 675 619 public String getSource() { 676 return tr("URL / File: {0}", rule.source); 677 } 620 return tr("URL / File: {0}", source); 621 } 622 } 623 624 static MapCSSTagCheckerIndex createMapCSSTagCheckerIndex(MultiMap<String, TagCheck> checks, boolean includeOtherSeverity, boolean allTests) { 625 final MapCSSTagCheckerIndex index = new MapCSSTagCheckerIndex(); 626 final Stream<MapCSSRule> ruleStream = checks.values().stream() 627 .flatMap(Collection::stream) 628 // Ignore "information" level checks if not wanted, unless they also set a MapCSS class 629 .filter(c -> includeOtherSeverity || Severity.OTHER != c.getSeverity() || !c.setClassExpressions.isEmpty()) 630 .filter(c -> allTests || c.rule.selectors.stream().anyMatch(Selector.ChildOrParentSelector.class::isInstance)) 631 .map(c -> c.rule); 632 index.buildIndex(ruleStream); 633 return index; 678 634 } 679 635 … … 687 643 final List<TestError> res = new ArrayList<>(); 688 644 if (indexData == null) { 689 indexData = new MapCSSTagCheckerIndex(checks, includeOtherSeverity, MapCSSTagCheckerIndex.ALL_TESTS); 690 } 691 692 MapCSSRuleIndex matchingRuleIndex = indexData.get(p); 645 indexData = MapCSSTagCheckerIndex.createMapCSSTagCheckerIndex(checks, includeOtherSeverity, MapCSSTagCheckerIndex.ALL_TESTS); 646 } 693 647 694 648 Environment env = new Environment(p, new MultiCascade(), Environment.DEFAULT_LAYER, null); 695 649 env.mpAreaCache = mpAreaCache; 696 650 697 // the declaration indices are sorted, so it suffices to save the last used index 698 Declaration lastDeclUsed = null; 699 700 Iterator<MapCSSRule> candidates = matchingRuleIndex.getRuleCandidates(p); 651 Iterator<MapCSSRule> candidates = indexData.getRuleCandidates(p); 701 652 while (candidates.hasNext()) { 702 653 MapCSSRule r = candidates.next(); 703 env.clearSelectorMatchingInformation(); 704 if (r.matches(env)) { // as side effect env.parent will be set (if s is a child selector) 705 TagCheck check = indexData.getCheck(r); 654 for (Selector selector : r.selectors) { 655 env.clearSelectorMatchingInformation(); 656 if (!selector.matches(env)) { // as side effect env.parent will be set (if s is a child selector) 657 continue; 658 } 659 MapCSSTagCheckerAndRule test = ruleToCheckMap.computeIfAbsent(r, rule -> checks.entrySet().stream() 660 .map(e -> e.getValue().stream() 661 // rule.selectors might be different due to MapCSSStyleIndex, however, the declarations are the same object 662 .filter(c -> c.rule.declaration == rule.declaration) 663 .findFirst() 664 .map(c -> new MapCSSTagCheckerAndRule(c, e.getKey())) 665 .orElse(null)) 666 .filter(Objects::nonNull) 667 .findFirst() 668 .orElse(null)); 669 TagCheck check = test == null ? null : test.tagCheck; 706 670 if (check != null) { 707 if (r.declaration == lastDeclUsed)708 continue; // don't apply one declaration more than once709 lastDeclUsed = r.declaration;710 711 671 r.declaration.execute(env); 712 672 if (!check.errors.isEmpty()) { 713 for (TestError e: check.getErrorsForPrimitive(p, r.selector, env, new MapCSSTagCheckerAndRule(check.rule))) {673 for (TestError e: check.getErrorsForPrimitive(p, selector, env, test)) { 714 674 addIfNotSimilar(e, res); 715 675 } … … 831 791 if (zip != null) 832 792 I18n.addTexts(cache.getFile()); 833 result = TagCheck.readMapCSS(reader, url,assertionConsumer);793 result = TagCheck.readMapCSS(reader, assertionConsumer); 834 794 checks.remove(url); 835 795 checks.putAll(url, result.parseChecks); … … 890 850 super.setShowElements(true); 891 851 if (indexData == null) { 892 indexData = newMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), MapCSSTagCheckerIndex.ALL_TESTS);852 indexData = MapCSSTagCheckerIndex.createMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), MapCSSTagCheckerIndex.ALL_TESTS); 893 853 } 894 854 tested.clear(); … … 904 864 // rebuild index with a reduced set of rules (those that use ChildOrParentSelector) and thus may have left selectors 905 865 // matching the previously tested elements 906 indexData = newMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), MapCSSTagCheckerIndex.ONLY_SELECTED_TESTS);866 indexData = MapCSSTagCheckerIndex.createMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), MapCSSTagCheckerIndex.ONLY_SELECTED_TESTS); 907 867 908 868 Set<OsmPrimitive> surrounding = new HashSet<>();
Note:
See TracChangeset
for help on using the changeset viewer.