Ticket #10467: 10467.patch

File 10467.patch, 6.3 KB (added by simon04, 9 years ago)
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
    index 56b5bba..ffbe0af 100644
    a b  
    77import java.util.Arrays;
    88import java.util.Collection;
    99import java.util.EnumSet;
     10import java.util.Map;
    1011import java.util.Objects;
    1112import java.util.Set;
    1213import java.util.regex.Pattern;
    else if ("index".equalsIgnoreCase(k))  
    5556        }
    5657    }
    5758
     59    public static Condition createRegexpKeyRegexpValueCondition(String k, String v, Op op) {
     60        return new RegexpKeyValueRegexpCondition(k, v, op);
     61    }
     62
    5863    public static Condition createKeyCondition(String k, boolean not, KeyMatchType matchType, Context context) {
    5964        switch (context) {
    6065        case PRIMITIVE:
    public KeyValueRegexpCondition(String k, String v, Op op, boolean considerValAsK  
    286291            this.pattern = Pattern.compile(v);
    287292        }
    288293
    289         @Override
    290         public boolean applies(Environment env) {
     294        protected boolean matches(Environment env) {
    291295            final String value = env.osm.get(k);
     296            return value != null && pattern.matcher(value).find();
     297        }
     298
     299        @Override
     300        public boolean applies(Environment env) {
    292301            if (Op.REGEX.equals(op)) {
    293                 return value != null && pattern.matcher(value).find();
     302                return matches(env);
    294303            } else if (Op.NREGEX.equals(op)) {
    295                 return value == null || !pattern.matcher(value).find();
     304                return !matches(env);
    296305            } else {
    297306                throw new IllegalStateException();
    298307            }
    299308        }
    300309    }
    301310
     311    public static class RegexpKeyValueRegexpCondition extends KeyValueRegexpCondition {
     312
     313        public final Pattern keyPattern;
     314
     315        public RegexpKeyValueRegexpCondition(String k, String v, Op op) {
     316            super(k, v, op, false);
     317            this.keyPattern = Pattern.compile(k);
     318        }
     319
     320        @Override
     321        protected boolean matches(Environment env) {
     322            for (Map.Entry<String,String> kv: env.osm.getKeys().entrySet()) {
     323                if (keyPattern.matcher(kv.getKey()).find() && pattern.matcher(kv.getValue()).find()) {
     324                    return true;
     325                }
     326            }
     327            return false;
     328        }
     329    }
     330
    302331    public static class RoleCondition extends Condition {
    303332        public final String role;
    304333        public final Op op;
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj b/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
    index d9e4f01..3bd4370 100644
    a b Condition simple_key_value_condition(Context context) :  
    754754    String val;
    755755    float f;
    756756    int i;
     757    Condition.KeyMatchType matchType = null;;
    757758    Condition.Op op;
    758759    boolean considerValAsKey = false;
    759760}
    760761{
    761     key=tag_key() s()
     762    (
     763        key = regex() s() { matchType = Condition.KeyMatchType.REGEX; }
     764    |
     765        key=tag_key() s()
     766    )
    762767    (
    763768        LOOKAHEAD(3)
    764769            (
    Condition simple_key_value_condition(Context context) :  
    806811            s()
    807812            f=float_() { val=Float.toString(f); }
    808813    )
    809     { return Condition.createKeyValueCondition(key, val, op, context, considerValAsKey); }
     814    { return Condition.KeyMatchType.REGEX == matchType
     815            ? Condition.createRegexpKeyRegexpValueCondition(key, val, op)
     816            : Condition.createKeyValueCondition(key, val, op, context, considerValAsKey); }
    810817}
    811818
    812819Condition class_or_pseudoclass(Context context) :
  • test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/KeyValueConditionTest.groovy

    diff --git a/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/KeyValueConditionTest.groovy b/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/KeyValueConditionTest.groovy
    index d025e94..675a623 100644
    a b  
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.mappaint.mapcss;
    33
    4 import static org.junit.Assert.*
    5 
    64import org.junit.*
    75import org.openstreetmap.josm.JOSMFixture
    86import org.openstreetmap.josm.data.coor.LatLon
    97import org.openstreetmap.josm.data.osm.DataSet
    108import org.openstreetmap.josm.data.osm.Node
     9import org.openstreetmap.josm.data.osm.OsmUtils
    1110import org.openstreetmap.josm.data.osm.Relation
    1211import org.openstreetmap.josm.data.osm.RelationMember
    1312import org.openstreetmap.josm.gui.mappaint.Environment
    1413import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context
    1514import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Op
     15import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser
    1616
    1717
    1818class KeyValueConditionTest {
    class KeyValueConditionTest {  
    8585        cond = Condition.createKeyValueCondition("role", "another_role", Op.NEQ, Context.LINK, false)
    8686        assert cond.applies(e)
    8787    }
     88
     89    @Test
     90    public void testKeyRegexValueRegex() throws Exception {
     91        def selPos = new MapCSSParser(new StringReader("*[/^source/ =~ /.*,.*/]")).selector()
     92        def selNeg = new MapCSSParser(new StringReader("*[/^source/ !~ /.*,.*/]")).selector()
     93        assert !selPos.matches(new Environment(OsmUtils.createPrimitive("way foo=bar")))
     94        assert selPos.matches(new Environment(OsmUtils.createPrimitive("way source=1,2")))
     95        assert selPos.matches(new Environment(OsmUtils.createPrimitive("way source_foo_bar=1,2")))
     96        assert !selPos.matches(new Environment(OsmUtils.createPrimitive("way source=1")))
     97        assert !selPos.matches(new Environment(OsmUtils.createPrimitive("way source=1")))
     98        assert !selNeg.matches(new Environment(OsmUtils.createPrimitive("way source=1,2")))
     99        assert !selNeg.matches(new Environment(OsmUtils.createPrimitive("way foo=bar source=1,2")))
     100        assert selNeg.matches(new Environment(OsmUtils.createPrimitive("way foo=bar source=baz")))
     101        assert selNeg.matches(new Environment(OsmUtils.createPrimitive("way foo=bar src=1,2")))
     102    }
    88103}