Changeset 17593 in josm
- Timestamp:
- 2021-03-20T11:50:06+01:00 (4 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/resources/data/validator/deprecated.mapcss
r17469 r17593 1473 1473 /* #17504 */ 1474 1474 *[is_in], 1475 node[/^is_in: .*$/],1476 way[/^is_in: .*$/] {1475 node[/^is_in:$/], 1476 way[/^is_in:$/] { 1477 1477 throwWarning: tr("{0} is deprecated", "{0.key}"); 1478 1478 group: tr("deprecated tagging"); -
trunk/resources/data/validator/unnecessary.mapcss
r17209 r17593 155 155 156 156 /* #2760 */ 157 *[/^(gpx|gpxx|gpxd):/] { 157 *[/^gpx:/], 158 *[/^gpxx:/], 159 *[/^gpxd:/] { 158 160 throwWarning: tr("{0} should not be uploaded", "{0.key}"); 159 161 group: tr("unnecessary tag"); -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java
r17584 r17593 105 105 switch (context) { 106 106 case PRIMITIVE: 107 return new KeyCondition(k, not, matchType); 107 if (KeyMatchType.REGEX == matchType && k.matches("[A-Za-z0-9:_-]+")) { 108 // optimization: using String.contains avoids allocating a Matcher 109 return new KeyCondition(k, not, KeyMatchType.ANY_CONTAINS); 110 } else if (KeyMatchType.REGEX == matchType && k.matches("\\^[A-Za-z0-9:_-]+")) { 111 // optimization: using String.startsWith avoids allocating a Matcher 112 return new KeyCondition(k.substring(1), not, KeyMatchType.ANY_STARTS_WITH); 113 } else if (KeyMatchType.REGEX == matchType && k.matches("[A-Za-z0-9:_-]+\\$")) { 114 // optimization: using String.endsWith avoids allocating a Matcher 115 return new KeyCondition(k.substring(0, k.length() - 1), not, KeyMatchType.ANY_ENDS_WITH); 116 } else if (matchType == KeyMatchType.REGEX) { 117 return new KeyRegexpCondition(Pattern.compile(k), not); 118 } else { 119 return new KeyCondition(k, not, matchType); 120 } 108 121 case LINK: 109 122 if (matchType != null) … … 489 502 * The key needs to match the given regular expression. 490 503 */ 491 REGEX 504 REGEX, 505 /** 506 * The key needs to contain the given label as substring. 507 */ 508 ANY_CONTAINS, 509 /** 510 * The key needs to start with the given label. 511 */ 512 ANY_STARTS_WITH, 513 /** 514 * The key needs to end with the given label. 515 */ 516 ANY_ENDS_WITH, 492 517 } 493 518 … … 510 535 * LINK: not supported 511 536 * </pre> 537 * @see KeyRegexpCondition 512 538 */ 513 539 public static class KeyCondition implements Condition, ToTagConvertable { … … 526 552 */ 527 553 public final KeyMatchType matchType; 528 /**529 * A predicate used to match a the regexp against the key. Only used if the match type is regexp.530 */531 public final Predicate<String> containsPattern;532 554 533 555 /** … … 538 560 */ 539 561 public KeyCondition(String label, boolean negateResult, KeyMatchType matchType) { 562 CheckParameterUtil.ensureThat(matchType != KeyMatchType.REGEX, "Use KeyPatternCondition"); 540 563 this.label = label; 541 564 this.negateResult = negateResult; 542 565 this.matchType = matchType == null ? KeyMatchType.EQ : matchType; 543 this.containsPattern = KeyMatchType.REGEX == matchType544 ? Pattern.compile(label).asPredicate()545 : null;546 566 } 547 567 548 568 @Override 549 569 public boolean applies(Environment e) { 550 switch(e.getContext()) { 551 case PRIMITIVE: 552 switch (matchType) { 570 CheckParameterUtil.ensureThat(!e.isLinkContext(), "Illegal state: KeyCondition not supported in LINK context"); 571 switch (matchType) { 553 572 case TRUE: 554 573 return e.osm.isKeyTrue(label) ^ negateResult; 555 574 case FALSE: 556 575 return e.osm.isKeyFalse(label) ^ negateResult; 557 case REGEX: 558 return e.osm.keys().anyMatch(containsPattern) ^ negateResult; 576 case ANY_CONTAINS: 577 case ANY_STARTS_WITH: 578 case ANY_ENDS_WITH: 579 return e.osm.keys().anyMatch(keyPredicate()) ^ negateResult; 559 580 default: 560 581 return e.osm.hasKey(label) ^ negateResult; 561 } 562 case LINK: 563 Utils.ensure(false, "Illegal state: KeyCondition not supported in LINK context"); 564 return false; 565 default: throw new AssertionError(); 566 } 582 } 583 } 584 585 private Predicate<String> keyPredicate() { 586 switch (matchType) { 587 case ANY_CONTAINS: 588 return key -> key.contains(label); 589 case ANY_STARTS_WITH: 590 return key -> key.startsWith(label); 591 case ANY_ENDS_WITH: 592 return key -> key.endsWith(label); 593 default: 594 return null; 595 } 596 } 597 598 /** 599 * Get the matched key and the corresponding value. 600 * <p> 601 * WARNING: This ignores {@link #negateResult}. 602 * @param p The primitive to get the value from. 603 * @return The tag. 604 */ 605 @Override 606 public Tag asTag(OsmPrimitive p) { 607 String key = label; 608 Predicate<String> keyPredicate = keyPredicate(); 609 if (keyPredicate != null) { 610 key = p.keys().filter(keyPredicate).findAny().orElse(key); 611 } 612 return new Tag(key, p.get(key)); 613 } 614 615 @Override 616 public String toString() { 617 return '[' + (negateResult ? "!" : "") + label + ']'; 618 } 619 } 620 621 /** 622 * KeyPatternCondition represents a conditions matching keys based on a pattern. 623 */ 624 public static class KeyRegexpCondition implements Condition, ToTagConvertable { 625 626 /** 627 * A predicate used to match a the regexp against the key. Only used if the match type is regexp. 628 */ 629 public final Pattern pattern; 630 /** 631 * If we should negate the result of the match. 632 */ 633 public final boolean negateResult; 634 635 /** 636 * Creates a new KeyPatternCondition 637 * @param pattern The regular expression for matching keys. 638 * @param negateResult If we should negate the result. 639 */ 640 public KeyRegexpCondition(Pattern pattern, boolean negateResult) { 641 this.negateResult = negateResult; 642 this.pattern = pattern; 643 } 644 645 @Override 646 public boolean applies(Environment e) { 647 CheckParameterUtil.ensureThat(!e.isLinkContext(), "Illegal state: KeyCondition not supported in LINK context"); 648 return e.osm.keys().anyMatch(pattern.asPredicate()) ^ negateResult; 567 649 } 568 650 … … 578 660 @Override 579 661 public Tag asTag(OsmPrimitive p) { 580 String key = label; 581 if (KeyMatchType.REGEX == matchType) { 582 key = p.keys().filter(containsPattern).findAny().orElse(key); 583 } 662 String key = p.keys().filter(pattern.asPredicate()).findAny().orElse(pattern.pattern());; 584 663 return new Tag(key, p.get(key)); 585 664 } … … 587 666 @Override 588 667 public String toString() { 589 return '[' + (negateResult ? "!" : "") + label+ ']';668 return '[' + (negateResult ? "!" : "") + pattern + ']'; 590 669 } 591 670 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRuleIndex.java
r16821 r17593 16 16 import org.openstreetmap.josm.data.osm.Tagged; 17 17 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyCondition; 18 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyMatchType;19 18 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyValueCondition; 20 19 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.SimpleKeyValueCondition; … … 190 189 if (c instanceof KeyCondition) { 191 190 KeyCondition keyCondition = (KeyCondition) c; 192 if (!keyCondition.negateResult && conditionRequiresKeyPresence(keyCondition.matchType)) {191 if (!keyCondition.negateResult) { 193 192 key = keyCondition.label; 194 193 } … … 201 200 } 202 201 return key; 203 }204 205 private static boolean conditionRequiresKeyPresence(KeyMatchType matchType) {206 return matchType != KeyMatchType.REGEX;207 202 } 208 203 -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/KeyConditionTest.java
r17275 r17593 2 2 package org.openstreetmap.josm.gui.mappaint.mapcss; 3 3 4 import static org.junit.jupiter.api.Assertions.assertEquals; 4 5 import static org.junit.jupiter.api.Assertions.assertFalse; 5 6 import static org.junit.jupiter.api.Assertions.assertTrue; … … 12 13 import org.openstreetmap.josm.data.osm.DataSet; 13 14 import org.openstreetmap.josm.data.osm.Node; 15 import org.openstreetmap.josm.data.osm.OsmUtils; 14 16 import org.openstreetmap.josm.data.osm.Relation; 15 17 import org.openstreetmap.josm.data.osm.RelationMember; … … 82 84 ConditionFactory.createKeyCondition("a key", true, KeyMatchType.TRUE, Context.PRIMITIVE); 83 85 86 // [/regex/] 87 Condition c = ConditionFactory.createKeyCondition("foo|bar", false, KeyMatchType.REGEX, Context.PRIMITIVE); 88 assertTrue(c.applies(new Environment(OsmUtils.createPrimitive("node BARfooBAZ=true")))); 89 assertFalse(c.applies(new Environment(OsmUtils.createPrimitive("node BARBAZ=true")))); 90 c = ConditionFactory.createKeyCondition("colour:", false, KeyMatchType.REGEX, Context.PRIMITIVE); 91 assertEquals(KeyMatchType.ANY_CONTAINS, ((KeyCondition) c).matchType); 92 assertEquals("colour:", ((KeyCondition) c).label); 93 assertTrue(c.applies(new Environment(OsmUtils.createPrimitive("node colour:roof=ref")))); 94 assertFalse(c.applies(new Environment(OsmUtils.createPrimitive("node foo=bar")))); 95 c = ConditionFactory.createKeyCondition("^wikipedia:", false, KeyMatchType.REGEX, Context.PRIMITIVE); 96 assertEquals(KeyMatchType.ANY_STARTS_WITH, ((KeyCondition) c).matchType); 97 assertEquals("wikipedia:", ((KeyCondition) c).label); 98 assertTrue(c.applies(new Environment(OsmUtils.createPrimitive("node wikipedia:en=a")))); 99 assertFalse(c.applies(new Environment(OsmUtils.createPrimitive("node wikipedia=a")))); 100 c = ConditionFactory.createKeyCondition("_name$", false, KeyMatchType.REGEX, Context.PRIMITIVE); 101 assertEquals(KeyMatchType.ANY_ENDS_WITH, ((KeyCondition) c).matchType); 102 assertEquals("_name", ((KeyCondition) c).label); 103 assertTrue(c.applies(new Environment(OsmUtils.createPrimitive("node alt_name=a")))); 104 assertFalse(c.applies(new Environment(OsmUtils.createPrimitive("node name=a")))); 105 84 106 // ["a label"] 85 107 ConditionFactory.createKeyCondition("a key", false, null, Context.LINK);
Note:
See TracChangeset
for help on using the changeset viewer.