commit ca1b0013680e30cc419f726fab6282f488084531
Author: Simon Legner <Simon.Legner@gmail.com>
Date: Fri Jan 11 17:43:05 2019 +0100
v1
diff --git a/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java b/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
index 31d9438b8..9d70b60da 100644
a
|
b
|
|
41 | 41 | import org.openstreetmap.josm.data.osm.OsmUtils; |
42 | 42 | import org.openstreetmap.josm.data.osm.Relation; |
43 | 43 | import org.openstreetmap.josm.data.osm.Tag; |
| 44 | import org.openstreetmap.josm.data.osm.Tagged; |
44 | 45 | import org.openstreetmap.josm.data.osm.Way; |
45 | 46 | import org.openstreetmap.josm.data.preferences.sources.SourceEntry; |
46 | 47 | import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper; |
… |
… |
|
49 | 50 | import org.openstreetmap.josm.data.validation.Test; |
50 | 51 | import org.openstreetmap.josm.data.validation.TestError; |
51 | 52 | import org.openstreetmap.josm.gui.mappaint.Environment; |
52 | | import org.openstreetmap.josm.gui.mappaint.Keyword; |
53 | 53 | import org.openstreetmap.josm.gui.mappaint.MultiCascade; |
54 | 54 | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; |
55 | 55 | import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ClassCondition; |
… |
… |
public ParseResult(List<TagCheck> parseChecks, Collection<Throwable> parseErrors
|
286 | 286 | protected final GroupedMapCSSRule rule; |
287 | 287 | /** Commands to apply in order to fix a matching primitive */ |
288 | 288 | protected final List<FixCommand> fixCommands = new ArrayList<>(); |
289 | | /** Tags (or arbitraty strings) of alternatives to be presented to the user */ |
| 289 | /** Tags (or arbitrary strings) of alternatives to be presented to the user */ |
290 | 290 | protected final List<String> alternatives = new ArrayList<>(); |
291 | 291 | /** An {@link org.openstreetmap.josm.gui.mappaint.mapcss.Instruction.AssignmentInstruction}-{@link Severity} pair. |
292 | 292 | * Is evaluated on the matching primitive to give the error message. Map is checked to contain exactly one element. */ |
… |
… |
static TagCheck ofMapCSSRule(final GroupedMapCSSRule rule) throws IllegalDataExc
|
329 | 329 | continue; |
330 | 330 | } |
331 | 331 | try { |
332 | | final String val = ai.val instanceof Expression |
333 | | ? Optional.ofNullable(((Expression) ai.val).evaluate(new Environment())).map(Object::toString).orElse(null) |
334 | | : ai.val instanceof String |
335 | | ? (String) ai.val |
336 | | : ai.val instanceof Keyword |
337 | | ? ((Keyword) ai.val).val |
338 | | : null; |
| 332 | final String val = ai.getValAsString(); |
339 | 333 | if (ai.key.startsWith("throw")) { |
340 | 334 | try { |
341 | 335 | check.errors.put(ai, Severity.valueOf(ai.key.substring("throw".length()).toUpperCase(Locale.ENGLISH))); |
… |
… |
Selector whichSelectorMatchesEnvironment(Environment env) {
|
445 | 439 | * @param matchingSelector matching selector |
446 | 440 | * @param index index |
447 | 441 | * @param type selector type ("key", "value" or "tag") |
448 | | * @param p OSM primitive |
| 442 | * @param p a tagged object |
449 | 443 | * @return argument value, can be {@code null} |
450 | 444 | */ |
451 | | static String determineArgument(OptimizedGeneralSelector matchingSelector, int index, String type, OsmPrimitive p) { |
| 445 | static String determineArgument(OptimizedGeneralSelector matchingSelector, int index, String type, Tagged p) { |
452 | 446 | try { |
453 | 447 | final Condition c = matchingSelector.getConditions().get(index); |
454 | | final Tag tag = c instanceof Condition.ToTagConvertable |
455 | | ? ((Condition.ToTagConvertable) c).asTag(p) |
| 448 | final Tag tag = c instanceof Condition.TagCondition |
| 449 | ? ((Condition.TagCondition) c).asTag(p) |
456 | 450 | : null; |
457 | 451 | if (tag == null) { |
458 | 452 | return null; |
… |
… |
static String determineArgument(OptimizedGeneralSelector matchingSelector, int i
|
474 | 468 | * key/value/tag of the {@code index}-th {@link Condition} of {@code matchingSelector}. |
475 | 469 | * @param matchingSelector matching selector |
476 | 470 | * @param s any string |
477 | | * @param p OSM primitive |
| 471 | * @param p a tagged object |
478 | 472 | * @return string with arguments inserted |
479 | 473 | */ |
480 | | static String insertArguments(Selector matchingSelector, String s, OsmPrimitive p) { |
| 474 | static String insertArguments(Selector matchingSelector, String s, Tagged p) { |
481 | 475 | if (s != null && matchingSelector instanceof Selector.ChildOrParentSelector) { |
482 | 476 | return insertArguments(((Selector.ChildOrParentSelector) matchingSelector).right, s, p); |
483 | 477 | } else if (s == null || !(matchingSelector instanceof Selector.OptimizedGeneralSelector)) { |
diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
index f0eab71e3..d10aa1be9 100644
a
|
b
|
|
3 | 3 | |
4 | 4 | import org.openstreetmap.josm.data.osm.OsmPrimitive; |
5 | 5 | import org.openstreetmap.josm.data.osm.Tag; |
| 6 | import org.openstreetmap.josm.data.osm.Tagged; |
6 | 7 | import org.openstreetmap.josm.gui.mappaint.Environment; |
| 8 | import org.openstreetmap.josm.tools.Utils; |
7 | 9 | |
8 | 10 | /** |
9 | 11 | * This is a condition that needs to be fulfilled in order to apply a MapCSS style. |
… |
… |
|
38 | 40 | * @author Michael Zangl |
39 | 41 | * @since 10674 |
40 | 42 | */ |
41 | | @FunctionalInterface |
42 | | interface ToTagConvertable { |
| 43 | interface TagCondition extends Condition { |
| 44 | |
| 45 | @Override |
| 46 | default boolean applies(Environment e) { |
| 47 | return applies(e.osm); |
| 48 | } |
| 49 | |
| 50 | /** |
| 51 | * Checks if the condition applies in the given {@link Tagged} element. |
| 52 | * @param tagged The tagged to check. |
| 53 | * @return <code>true</code> if the condition applies. |
| 54 | */ |
| 55 | boolean applies(Tagged tagged); |
| 56 | |
43 | 57 | /** |
44 | 58 | * Converts the current condition to a tag |
45 | | * @param primitive A primitive to use as context. May be ignored. |
| 59 | * @param tagged A tagged object to use as context. May be ignored. |
46 | 60 | * @return A tag with the key/value of this condition. |
47 | 61 | */ |
48 | | Tag asTag(OsmPrimitive primitive); |
| 62 | Tag asTag(Tagged tagged); |
49 | 63 | } |
50 | 64 | } |
diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java
index e0cc01b46..29d6ce2a1 100644
a
|
b
|
|
23 | 23 | import org.openstreetmap.josm.data.osm.OsmUtils; |
24 | 24 | import org.openstreetmap.josm.data.osm.Relation; |
25 | 25 | import org.openstreetmap.josm.data.osm.Tag; |
| 26 | import org.openstreetmap.josm.data.osm.Tagged; |
26 | 27 | import org.openstreetmap.josm.data.osm.search.SearchCompiler.InDataSourceArea; |
27 | 28 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; |
28 | 29 | import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; |
… |
… |
|
30 | 31 | import org.openstreetmap.josm.gui.mappaint.ElemStyles; |
31 | 32 | import org.openstreetmap.josm.gui.mappaint.Environment; |
32 | 33 | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context; |
33 | | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.ToTagConvertable; |
| 34 | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.TagCondition; |
34 | 35 | import org.openstreetmap.josm.tools.CheckParameterUtil; |
35 | 36 | import org.openstreetmap.josm.tools.JosmRuntimeException; |
36 | 37 | import org.openstreetmap.josm.tools.Utils; |
… |
… |
public boolean eval(String testString, String prototypeString) {
|
243 | 244 | * |
244 | 245 | * Extra class for performance reasons. |
245 | 246 | */ |
246 | | public static class SimpleKeyValueCondition implements Condition, ToTagConvertable { |
| 247 | public static class SimpleKeyValueCondition implements TagCondition { |
247 | 248 | /** |
248 | 249 | * The key to search for. |
249 | 250 | */ |
… |
… |
public SimpleKeyValueCondition(String k, String v) {
|
264 | 265 | } |
265 | 266 | |
266 | 267 | @Override |
267 | | public boolean applies(Environment e) { |
268 | | return v.equals(e.osm.get(k)); |
| 268 | public boolean applies(Tagged tagged) { |
| 269 | return v.equals(tagged.get(k)); |
269 | 270 | } |
270 | 271 | |
271 | 272 | @Override |
272 | | public Tag asTag(OsmPrimitive primitive) { |
| 273 | public Tag asTag(Tagged tagged) { |
273 | 274 | return new Tag(k, v); |
274 | 275 | } |
275 | 276 | |
… |
… |
public String toString() {
|
284 | 285 | * <p>Represents a key/value condition which is either applied to a primitive.</p> |
285 | 286 | * |
286 | 287 | */ |
287 | | public static class KeyValueCondition implements Condition, ToTagConvertable { |
| 288 | public static class KeyValueCondition implements TagCondition { |
288 | 289 | /** |
289 | 290 | * The key to search for. |
290 | 291 | */ |
… |
… |
public boolean requiresExactKeyMatch() {
|
327 | 328 | } |
328 | 329 | |
329 | 330 | @Override |
330 | | public boolean applies(Environment env) { |
331 | | return op.eval(env.osm.get(k), considerValAsKey ? env.osm.get(v) : v); |
| 331 | public boolean applies(Tagged tagged) { |
| 332 | return op.eval(tagged.get(k), considerValAsKey ? tagged.get(v) : v); |
332 | 333 | } |
333 | 334 | |
334 | 335 | @Override |
335 | | public Tag asTag(OsmPrimitive primitive) { |
| 336 | public Tag asTag(Tagged tagged) { |
336 | 337 | return new Tag(k, v); |
337 | 338 | } |
338 | 339 | |
… |
… |
public boolean applies(Environment env) {
|
512 | 513 | * LINK: not supported |
513 | 514 | * </pre> |
514 | 515 | */ |
515 | | public static class KeyCondition implements Condition, ToTagConvertable { |
| 516 | public static class KeyCondition implements TagCondition { |
516 | 517 | |
517 | 518 | /** |
518 | 519 | * The key name. |
… |
… |
public KeyCondition(String label, boolean negateResult, KeyMatchType matchType)
|
550 | 551 | @Override |
551 | 552 | public boolean applies(Environment e) { |
552 | 553 | switch(e.getContext()) { |
553 | | case PRIMITIVE: |
554 | | switch (matchType) { |
| 554 | case PRIMITIVE: |
| 555 | return applies(e.osm); |
| 556 | case LINK: |
| 557 | Utils.ensure(false, "Illegal state: {0} not supported in LINK context", getClass()); |
| 558 | return false; |
| 559 | default: throw new AssertionError(); |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | @Override |
| 564 | public boolean applies(Tagged tagged) { |
| 565 | switch (matchType) { |
555 | 566 | case TRUE: |
556 | | return e.osm.isKeyTrue(label) ^ negateResult; |
| 567 | return tagged.isKeyTrue(label) ^ negateResult; |
557 | 568 | case FALSE: |
558 | | return e.osm.isKeyFalse(label) ^ negateResult; |
| 569 | return tagged.isKeyFalse(label) ^ negateResult; |
559 | 570 | case REGEX: |
560 | | return e.osm.keySet().stream().anyMatch(containsPattern) ^ negateResult; |
| 571 | return tagged.keySet().stream().anyMatch(containsPattern) ^ negateResult; |
561 | 572 | default: |
562 | | return e.osm.hasKey(label) ^ negateResult; |
563 | | } |
564 | | case LINK: |
565 | | Utils.ensure(false, "Illegal state: KeyCondition not supported in LINK context"); |
566 | | return false; |
567 | | default: throw new AssertionError(); |
| 573 | return tagged.hasKey(label) ^ negateResult; |
568 | 574 | } |
569 | 575 | } |
570 | 576 | |
… |
… |
public boolean applies(Environment e) {
|
578 | 584 | * @return The tag. |
579 | 585 | */ |
580 | 586 | @Override |
581 | | public Tag asTag(OsmPrimitive p) { |
| 587 | public Tag asTag(Tagged p) { |
582 | 588 | String key = label; |
583 | 589 | if (KeyMatchType.REGEX == matchType) { |
584 | 590 | key = p.keySet().stream().filter(containsPattern).findAny().orElse(key); |
diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java
index 793b85eaa..58b4082d8 100644
a
|
b
|
|
2 | 2 | package org.openstreetmap.josm.gui.mappaint.mapcss; |
3 | 3 | |
4 | 4 | import java.util.Arrays; |
| 5 | import java.util.Optional; |
5 | 6 | |
6 | 7 | import org.openstreetmap.josm.gui.mappaint.Cascade; |
7 | 8 | import org.openstreetmap.josm.gui.mappaint.Environment; |
… |
… |
public void execute(Environment env) {
|
102 | 103 | env.mc.getOrCreateCascade(env.layer).putOrClear(key, value); |
103 | 104 | } |
104 | 105 | |
| 106 | public String getValAsString() { |
| 107 | return this.val instanceof Expression |
| 108 | ? Optional.ofNullable(((Expression) this.val).evaluate(new Environment())).map(Object::toString).orElse(null) |
| 109 | : this.val instanceof String |
| 110 | ? (String) this.val |
| 111 | : this.val instanceof Keyword |
| 112 | ? ((Keyword) this.val).val |
| 113 | : null; |
| 114 | } |
| 115 | |
105 | 116 | @Override |
106 | 117 | public String toString() { |
107 | 118 | return key + ": " + (val instanceof float[] ? Arrays.toString((float[]) val) : |
diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSRule.java
index fca2760f4..511fd351c 100644
a
|
b
|
|
43 | 43 | |
44 | 44 | /** |
45 | 45 | * Create a new {@link Declaration} |
46 | | * @param instructions The instructions for this dectlaration |
| 46 | * @param instructions The instructions for this declaration |
47 | 47 | * @param idx The index in the {@link StyleSource} |
48 | 48 | */ |
49 | 49 | public Declaration(List<Instruction> instructions, int idx) { |
diff --git a/src/org/openstreetmap/josm/tools/Tag2Link.java b/src/org/openstreetmap/josm/tools/Tag2Link.java
new file mode 100644
index 000000000..e9490c14b
-
|
+
|
|
| 1 | package org.openstreetmap.josm.tools; |
| 2 | |
| 3 | import java.net.URL; |
| 4 | import java.util.ArrayList; |
| 5 | import java.util.List; |
| 6 | |
| 7 | import org.openstreetmap.josm.data.osm.Tag; |
| 8 | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; |
| 9 | import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule; |
| 10 | import org.openstreetmap.josm.gui.mappaint.mapcss.Selector; |
| 11 | |
| 12 | public final class Tag2Link { |
| 13 | |
| 14 | final List<MapCSSRule> rules = new ArrayList<>(); |
| 15 | |
| 16 | private Tag2Link() { |
| 17 | } |
| 18 | |
| 19 | public Iterable<URL> getLinksForTag(Tag tag) { |
| 20 | for (MapCSSRule rule : rules) { |
| 21 | for (Condition condition : ((Selector.AbstractSelector) rule.selector).getConditions()) { |
| 22 | if (((Condition.TagCondition) condition).applies(tag)) { |
| 23 | |
| 24 | } |
| 25 | } |
| 26 | } |
| 27 | } |
| 28 | } |
diff --git a/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionTest.java b/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionTest.java
index 4fefb417e..890f311ba 100644
a
|
b
|
|
12 | 12 | import org.openstreetmap.josm.data.osm.OsmUtils; |
13 | 13 | import org.openstreetmap.josm.gui.mappaint.Environment; |
14 | 14 | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context; |
15 | | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.ToTagConvertable; |
| 15 | import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.TagCondition; |
16 | 16 | import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op; |
17 | 17 | import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.SimpleKeyValueCondition; |
18 | 18 | import org.openstreetmap.josm.testutils.JOSMTestRules; |
… |
… |
public void testKeyValueEq() {
|
62 | 62 | |
63 | 63 | assertTrue(op instanceof SimpleKeyValueCondition); |
64 | 64 | assertEquals("[k1=v1]", op.toString()); |
65 | | assertEquals("k1", ((ToTagConvertable) op).asTag(null).getKey()); |
66 | | assertEquals("v1", ((ToTagConvertable) op).asTag(null).getValue()); |
| 65 | assertEquals("k1", ((TagCondition) op).asTag(null).getKey()); |
| 66 | assertEquals("v1", ((TagCondition) op).asTag(null).getValue()); |
67 | 67 | } |
68 | 68 | |
69 | 69 | /** |
… |
… |
public void testKeyValueEqAsKey() {
|
78 | 78 | assertFalse(op.applies(genEnv(node3))); |
79 | 79 | assertFalse(op.applies(genEnv(node4))); |
80 | 80 | |
81 | | assertEquals("k1", ((ToTagConvertable) op).asTag(null).getKey()); |
82 | | assertEquals("k2", ((ToTagConvertable) op).asTag(null).getValue()); |
| 81 | assertEquals("k1", ((TagCondition) op).asTag(null).getKey()); |
| 82 | assertEquals("k2", ((TagCondition) op).asTag(null).getValue()); |
83 | 83 | } |
84 | 84 | |
85 | 85 | /** |