Changeset 17593 in josm for trunk/src/org
- Timestamp:
- 2021-03-20T11:50:06+01:00 (4 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.