Changeset 6547 in josm for trunk/src


Ignore:
Timestamp:
2013-12-27T16:14:28+01:00 (12 years ago)
Author:
simon04
Message:

MapCSS: add regular expression support for key conditions

For instance, [/^addr:/] matches any addr:* key.

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java

    r6538 r6547  
    66import java.text.MessageFormat;
    77import java.util.EnumSet;
    8 import java.util.regex.Matcher;
    98import java.util.regex.Pattern;
    109
     
    1615import org.openstreetmap.josm.gui.mappaint.Cascade;
    1716import org.openstreetmap.josm.gui.mappaint.Environment;
     17import org.openstreetmap.josm.tools.Predicates;
    1818import org.openstreetmap.josm.tools.Utils;
    1919
     
    3939    }
    4040
    41     public static Condition create(String k, boolean not, boolean yes, boolean no, Context context) {
     41    public static Condition create(String k, boolean not, KeyMatchType matchType, Context context) {
    4242        switch (context) {
    4343        case PRIMITIVE:
    44             return new KeyCondition(k, not, yes, no);
     44            return new KeyCondition(k, not, matchType);
    4545        case LINK:
    46             if (yes || no)
    47                 throw new MapCSSException("Question mark operator ''?'' not supported in LINK context");
     46            if (matchType != null)
     47                throw new MapCSSException("Question mark operator ''?'' and regexp match not supported in LINK context");
    4848            if (not)
    4949                return new RoleCondition(k, Op.NEQ);
     
    7777            case REGEX:
    7878            case NREGEX:
    79                 Pattern p = Pattern.compile(prototypeString);
    80                 Matcher m = p.matcher(testString);
    81                 return REGEX.equals(this) ? m.find() : !m.find();
     79                final boolean contains = Pattern.compile(prototypeString).matcher(testString).find();
     80                return REGEX.equals(this) ? contains : !contains;
    8281            case ONE_OF:
    8382                String[] parts = testString.split(";");
     
    142141    public static class KeyValueCondition extends Condition {
    143142
    144         public String k;
    145         public String v;
    146         public Op op;
     143        public final String k;
     144        public final String v;
     145        public final Op op;
    147146
    148147        /**
     
    175174
    176175    public static class RoleCondition extends Condition {
    177         public String role;
    178         public Op op;
     176        public final String role;
     177        public final Op op;
    179178
    180179        public RoleCondition(String role, Op op) {
     
    192191
    193192    public static class IndexCondition extends Condition {
    194         public String index;
    195         public Op op;
     193        public final String index;
     194        public final Op op;
    196195
    197196        public IndexCondition(String index, Op op) {
     
    205204            return op.eval(Integer.toString(env.index + 1), index);
    206205        }
     206    }
     207
     208    public static enum KeyMatchType {
     209        EQ, TRUE, FALSE, REGEX
    207210    }
    208211
     
    228231    public static class KeyCondition extends Condition {
    229232
    230         private String label;
    231         private boolean negateResult;
    232         private boolean testForTrueValues;
    233         private boolean testForFalseValues;
    234 
    235         public KeyCondition(String label, boolean negateResult, boolean testForTrueValues, boolean testForFalseValues){
     233        public final String label;
     234        public final boolean negateResult;
     235        public final KeyMatchType matchType;
     236
     237        public KeyCondition(String label, boolean negateResult, KeyMatchType matchType){
    236238            this.label = label;
    237239            this.negateResult = negateResult;
    238             this.testForTrueValues = testForTrueValues;
    239             this.testForFalseValues = testForFalseValues;
     240            this.matchType = matchType;
    240241        }
    241242
     
    244245            switch(e.getContext()) {
    245246            case PRIMITIVE:
    246                 if (testForTrueValues)
     247                if (KeyMatchType.TRUE.equals(matchType))
    247248                    return OsmUtils.isTrue(e.osm.get(label)) ^ negateResult;
    248                 else if (testForFalseValues)
     249                else if (KeyMatchType.FALSE.equals(matchType))
    249250                    return OsmUtils.isFalse(e.osm.get(label)) ^ negateResult;
     251                else if (KeyMatchType.REGEX.equals(matchType))
     252                    return Utils.exists(e.osm.keySet(), Predicates.stringContainsPattern(Pattern.compile(label))) ^ negateResult;
    250253                else
    251254                    return e.osm.hasKey(label) ^ negateResult;
     
    269272    public static class PseudoClassCondition extends Condition {
    270273
    271         String id;
    272         boolean not;
     274        public final String id;
     275        public final boolean not;
    273276
    274277        public PseudoClassCondition(String id, boolean not) {
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj

    r6532 r6547  
    345345{
    346346    boolean not = false;
    347     boolean yes = false;
    348     boolean no = false;
     347    Condition.KeyMatchType matchType = null;;
    349348    String key;
    350349}
    351350{
    352351    ( <EXCLAMATION> { not = true; } )?
    353     key=tag_key()
    354     ( LOOKAHEAD(2) <QUESTION> <EXCLAMATION> { no = true; } )?
    355     ( <QUESTION> { yes = true; } )?
    356     { return Condition.create(key, not, yes, no, context); }
     352    (
     353        { matchType = Condition.KeyMatchType.REGEX; } key = regex()
     354    |
     355        key = tag_key()
     356    )
     357    ( LOOKAHEAD(2) <QUESTION> <EXCLAMATION> { matchType = Condition.KeyMatchType.FALSE; } )?
     358    (              <QUESTION>               { matchType = Condition.KeyMatchType.TRUE;  } )?
     359    { return Condition.create(key, not, matchType, context); }
    357360}
    358361
Note: See TracChangeset for help on using the changeset viewer.