Changeset 6554 in josm


Ignore:
Timestamp:
2013-12-28T01:31:47+01:00 (6 years ago)
Author:
simon04
Message:

see #9414 fix #9409 - extend MapCSS condition syntax to allow the comparison of two key values

The syntax is [key1 = *key2] where * is inspired by the C de-reference operator, and = stands for any of =/!=/~=/^=/$=/*=/=~/!~.

Location:
trunk
Files:
3 edited

Legend:

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

    r6547 r6554  
    2222    abstract public boolean applies(Environment e);
    2323
    24     public static Condition create(String k, String v, Op op, Context context) {
     24    public static Condition create(String k, String v, Op op, Context context, boolean considerValAsKey) {
    2525        switch (context) {
    2626        case PRIMITIVE:
    27             return new KeyValueCondition(k, v, op);
     27            return new KeyValueCondition(k, v, op, considerValAsKey);
    2828        case LINK:
     29            if (considerValAsKey)
     30                throw new MapCSSException("''considerValAsKey'' not supported in LINK context");
    2931            if ("role".equalsIgnoreCase(k))
    3032                return new RoleCondition(v, op);
     
    144146        public final String v;
    145147        public final Op op;
     148        public boolean considerValAsKey;
    146149
    147150        /**
     
    151154         * @param v the value
    152155         * @param op the operation
     156         * @param considerValAsKey whether to consider {@code v} as another key and compare the values of key {@code k} and key {@code v}.
    153157         */
    154         public KeyValueCondition(String k, String v, Op op) {
     158        public KeyValueCondition(String k, String v, Op op, boolean considerValAsKey) {
    155159            this.k = k;
    156160            this.v = v;
    157161            this.op = op;
     162            this.considerValAsKey = considerValAsKey;
    158163        }
    159164
    160165        @Override
    161166        public boolean applies(Environment env) {
    162             return op.eval(env.osm.get(k), v);
     167            return op.eval(env.osm.get(k), considerValAsKey ? env.osm.get(v) : v);
    163168        }
    164169
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj

    r6547 r6554  
    367367    int i;
    368368    Condition.Op op;
     369    boolean considerValAsKey = false;
    369370}
    370371{
    371372    key=tag_key() s()
    372373    (
    373         LOOKAHEAD(2)
    374             <EQUAL> <TILDE> { op=Condition.Op.REGEX; } s() val=regex()
    375         |
    376         LOOKAHEAD(2)
    377             <EXCLAMATION> <TILDE> { op=Condition.Op.NREGEX; } s() val=regex()
     374        LOOKAHEAD(3)
     375            (
     376                    <EQUAL> <TILDE> { op=Condition.Op.REGEX; }
     377                |
     378                    <EXCLAMATION> <TILDE> { op=Condition.Op.NREGEX; }
     379            )
     380            s()
     381            ( <STAR> { considerValAsKey=true; } )?
     382            val=regex()
    378383        |
    379384            (
     
    391396            )
    392397            s()
     398            ( <STAR> { considerValAsKey=true; } )?
    393399            (
    394400                LOOKAHEAD(2)
     
    412418            f=float_() { val=Float.toString(f); }
    413419    )
    414     { return Condition.create(key, val, op, context); }
     420    { return Condition.create(key, val, op, context, considerValAsKey); }
    415421}
    416422
  • trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy

    r6547 r6554  
    106106        assert !c1.applies(getEnvironment("lanes:foobar", "3"))
    107107    }
     108
     109    @Test
     110    public void testKeyKeyCondition() throws Exception {
     111        def c1 = (Condition.KeyValueCondition) new MapCSSParser(new StringReader("[foo = *bar]")).condition(Condition.Context.PRIMITIVE)
     112        def w1 = new Way()
     113        w1.put("foo", "123")
     114        w1.put("bar", "456")
     115        assert !c1.applies(new Environment().withPrimitive(w1))
     116        w1.put("bar", "123")
     117        assert c1.applies(new Environment().withPrimitive(w1))
     118        def c2 = (Condition.KeyValueCondition) new MapCSSParser(new StringReader("[foo =~ */bar/]")).condition(Condition.Context.PRIMITIVE)
     119        def w2 = new Way(w1)
     120        w2.put("bar", "[0-9]{3}")
     121        assert c2.applies(new Environment().withPrimitive(w2))
     122        w2.put("bar", "[0-9]")
     123        assert c2.applies(new Environment().withPrimitive(w2))
     124        w2.put("bar", "^[0-9]\$")
     125        assert !c2.applies(new Environment().withPrimitive(w2))
     126    }
    108127}
Note: See TracChangeset for help on using the changeset viewer.