Changeset 6601 in josm


Ignore:
Timestamp:
2014-01-02T23:58:58+01:00 (11 years ago)
Author:
simon04
Message:

see #9414 fix #9485 - MapCSSTagChecker: add support for set class_name instruction and .class_name condition

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/data/validator/highway.mapcss

    r6550 r6601  
     1way[highway=~/^(motorway|trunk|primary|secondary|tertiary)(_link)?$/] {
     2  set major_road;
     3}
     4way[highway=~/^(unclassified|residential|living_street|service)$/] {
     5  set minor_road;
     6}
     7
    18way[highway][name =~ /(?i).* (Ave|Blvd|Br|Brg|Cct|Cir|Cl|Cr|Crct|Cres|Crt|Ct|Dr|Drv|Esp|Espl|Hwy|Ln|Mw|Mwy|Pl|Rd|Qy|Qys|Sq|St|Str|Ter|Tce|Tr|Wy)[.]?$/] {
    29  throwWarning: tr("abbreviated street name");
     
    4047}
    4148
    42 way[highway =~ /motorway|trunk|primary|secondary|tertiary/][!ref] {
     49way.major_road[!ref] {
    4350  throwOther: tr("highway without a reference");
    4451  assertMatch: "way highway=primary";
     
    4653}
    4754
    48 way[foot][highway =~ /motorway|trunk|primary|secondary|tertiary/] {
    49   throwWarning: tr("{0} used with {1}", "{0.key}", "{1.tag}");
     55way.major_road[foot] {
     56  throwWarning: tr("{0} used with {1}", tr("major road"), "{0.tag}");
    5057  suggestAlternative: "sidewalk";
    51   suggestAlternative: "separate footway";
     58  suggestAlternative: tr("separate footway");
    5259  assertMatch: "way highway=primary foot=yes";
    5360  assertNoMatch: "way highway=primary";
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

    r6591 r6601  
    2323import org.openstreetmap.josm.command.Command;
    2424import org.openstreetmap.josm.command.SequenceCommand;
    25 import org.openstreetmap.josm.data.osm.Node;
    2625import org.openstreetmap.josm.data.osm.OsmPrimitive;
    27 import org.openstreetmap.josm.data.osm.Relation;
    2826import org.openstreetmap.josm.data.osm.Tag;
    29 import org.openstreetmap.josm.data.osm.Way;
    3027import org.openstreetmap.josm.data.preferences.CollectionProperty;
    3128import org.openstreetmap.josm.data.validation.FixableTestError;
     
    3431import org.openstreetmap.josm.data.validation.TestError;
    3532import org.openstreetmap.josm.gui.mappaint.Environment;
     33import org.openstreetmap.josm.gui.mappaint.MultiCascade;
    3634import org.openstreetmap.josm.gui.mappaint.mapcss.Condition;
    3735import org.openstreetmap.josm.gui.mappaint.mapcss.Expression;
     
    6866
    6967    static class TagCheck implements Predicate<OsmPrimitive> {
    70         protected final List<Selector> selector;
     68        protected final MapCSSRule rule;
    7169        protected final List<PrimitiveToTag> change = new ArrayList<PrimitiveToTag>();
    7270        protected final Map<String, String> keyChange = new LinkedHashMap<String, String>();
     
    7573        protected final Map<String, Boolean> assertions = new HashMap<String, Boolean>();
    7674
    77         TagCheck(List<Selector> selector) {
    78             this.selector = selector;
     75        TagCheck(MapCSSRule rule) {
     76            this.rule = rule;
    7977        }
    8078
     
    113111
    114112        static TagCheck ofMapCSSRule(final MapCSSRule rule) {
    115             final TagCheck check = new TagCheck(rule.selectors);
     113            final TagCheck check = new TagCheck(rule);
     114            boolean containsSetClassExpression = false;
    116115            for (Instruction i : rule.declaration) {
    117116                if (i instanceof Instruction.AssignmentInstruction) {
     
    142141                    } else if ("assertNoMatch".equals(ai.key) && val != null) {
    143142                        check.assertions.put(val, false);
     143                    } else if (ai.val instanceof Boolean && ((Boolean) ai.val)) {
     144                        containsSetClassExpression = true;
    144145                    } else {
    145146                        throw new RuntimeException("Cannot add instruction " + ai.key + ": " + ai.val + "!");
     
    147148                }
    148149            }
    149             if (check.errors.isEmpty()) {
     150            if (check.errors.isEmpty() && !containsSetClassExpression) {
    150151                throw new RuntimeException("No throwError/throwWarning/throwOther given! You should specify a validation error message for " + rule.selectors);
    151152            } else if (check.errors.size() > 1) {
     
    183184         * @param primitive the primitive to test
    184185         * @return true when the primitive contains a deprecated tag
    185          */
     186         * @deprecated since it does not handle MapCSS-classes
     187         */
     188        @Deprecated
    186189        boolean matchesPrimitive(OsmPrimitive primitive) {
    187190            return whichSelectorMatchesPrimitive(primitive) != null;
     
    189192
    190193        Selector whichSelectorMatchesPrimitive(OsmPrimitive primitive) {
    191             final Environment env = new Environment().withPrimitive(primitive);
    192             for (Selector i : selector) {
     194            return whichSelectorMatchesEnvironment(new Environment().withPrimitive(primitive));
     195        }
     196
     197        Selector whichSelectorMatchesEnvironment(Environment env) {
     198            for (Selector i : rule.selectors) {
     199                env.clearSelectorMatchingInformation();
    193200                if (i.matches(env)) {
    194201                    return i;
     
    318325         */
    319326        TestError getErrorForPrimitive(OsmPrimitive p) {
    320             final Selector matchingSelector = whichSelectorMatchesPrimitive(p);
    321             if (matchingSelector != null) {
     327            return getErrorForPrimitive(p, whichSelectorMatchesPrimitive(p));
     328        }
     329
     330        TestError getErrorForPrimitive(OsmPrimitive p, Selector matchingSelector) {
     331            if (matchingSelector != null && !errors.isEmpty()) {
    322332                final Command fix = fixPrimitive(p);
    323333                final String description = getDescriptionForMatchingSelector(matchingSelector);
     
    331341            }
    332342        }
     343    }
     344
     345    static class MapCSSTagCheckerAndRule extends MapCSSTagChecker {
     346        public final MapCSSRule rule;
     347
     348        MapCSSTagCheckerAndRule(MapCSSRule rule) {
     349            this.rule = rule;
     350        }
     351
     352        @Override
     353        public boolean equals(Object obj) {
     354            return super.equals(obj)
     355                    || (obj instanceof TagCheck && rule.equals(((TagCheck) obj).rule))
     356                    || (obj instanceof MapCSSRule && rule.equals(obj));
     357        }
     358    }
     359
     360    /**
     361     * Obtains all {@link TestError}s for the {@link OsmPrimitive} {@code p}.
     362     */
     363    public Collection<TestError> getErrorsForPrimitive(OsmPrimitive p) {
     364        final ArrayList<TestError> r = new ArrayList<TestError>();
     365        final Environment env = new Environment(p, new MultiCascade(), Environment.DEFAULT_LAYER, null);
     366        for (TagCheck check : checks) {
     367            final Selector selector = check.whichSelectorMatchesEnvironment(env);
     368            if (selector != null) {
     369                check.rule.execute(env);
     370                final TestError error = check.getErrorForPrimitive(p, selector);
     371                if (error != null) {
     372                    error.setTester(new MapCSSTagCheckerAndRule(check.rule));
     373                    r.add(error);
     374                }
     375            }
     376        }
     377        return r;
    333378    }
    334379
     
    340385    @Override
    341386    public void check(OsmPrimitive p) {
    342         for (TagCheck check : checks) {
    343             final TestError error = check.getErrorForPrimitive(p);
    344             if (error != null) {
    345                 error.setTester(this);
    346                 errors.add(error);
    347             }
    348         }
     387        errors.addAll(getErrorsForPrimitive(p));
    349388    }
    350389
  • trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java

    r6175 r6601  
    2121    public StyleSource source;
    2222    private Context context = Context.PRIMITIVE;
     23    public static final String DEFAULT_LAYER = "default";
    2324
    2425    /**
  • trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java

    r6579 r6601  
    291291        @Override
    292292        public boolean applies(Environment env) {
    293             return not ^ env.mc.getCascade(env.layer).containsKey(id);
     293            return env != null && env.mc != null && env.mc.getCascade(env.layer) != null && not ^ env.mc.getCascade(env.layer).containsKey(id);
    294294        }
    295295
  • trunk/test/unit/org/openstreetmap/TestUtils.java

    r6592 r6601  
    6060        assertThat(p.get("railway"), is("rail"));
    6161    }
     62
     63    @Test(expected = IllegalArgumentException.class)
     64    public void testCreatePrimitiveFail() throws Exception {
     65        TestUtils.createPrimitive("noway name=Foo");
     66    }
     67
    6268}
  • trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java

    r6592 r6601  
    99import org.openstreetmap.josm.data.osm.Node;
    1010import org.openstreetmap.josm.data.osm.OsmPrimitive;
    11 import org.openstreetmap.josm.data.osm.Relation;
    1211import org.openstreetmap.josm.data.osm.Tag;
    13 import org.openstreetmap.josm.data.osm.Way;
    1412import org.openstreetmap.josm.data.validation.Severity;
    15 import org.openstreetmap.josm.tools.TextTagParser;
     13import org.openstreetmap.josm.data.validation.TestError;
     14import org.openstreetmap.josm.tools.Predicate;
     15import org.openstreetmap.josm.tools.Predicates;
     16import org.openstreetmap.josm.tools.Utils;
    1617
    1718import java.io.StringReader;
     
    6263        n2.put("natural", "wood");
    6364        assertFalse(check.matchesPrimitive(n2));
    64         assertThat(MapCSSTagChecker.TagCheck.insertArguments(check.selector.get(0), "The key is {0.key} and the value is {0.value}"),
     65        assertThat(MapCSSTagChecker.TagCheck.insertArguments(check.rule.selectors.get(0), "The key is {0.key} and the value is {0.value}"),
    6566                is("The key is natural and the value is marsh"));
    66     }
    67 
    68     @Test(expected = IllegalArgumentException.class)
    69     public void testCreatePrimitiveForAssertionFail() throws Exception {
    70         final OsmPrimitive p = TestUtils.createPrimitive("noway name=Foo");
    7167    }
    7268
     
    8076            for (final Map.Entry<String, Boolean> i : check.assertions.entrySet()) {
    8177                final OsmPrimitive p = TestUtils.createPrimitive(i.getKey());
    82                 if (check.matchesPrimitive(p) != i.getValue()) {
     78                final boolean isError = Utils.exists(c.getErrorsForPrimitive(p), new Predicate<TestError>() {
     79                    @Override
     80                    public boolean evaluate(TestError e) {
     81                        //noinspection EqualsBetweenInconvertibleTypes
     82                        return e.getTester().equals(check.rule);
     83                    }
     84                });
     85                if (isError != i.getValue()) {
    8386                    final String error = MessageFormat.format("Expecting test ''{0}'' (i.e., {1}) to {2} {3} (i.e., {4})",
    84                             check.getMessage(), check.selector, i.getValue() ? "match" : "not match", i.getKey(), p.getKeys());
     87                            check.getMessage(), check.rule.selectors, i.getValue() ? "match" : "not match", i.getKey(), p.getKeys());
    8588                    System.err.println(error);
    8689                    assertionErrors.add(error);
Note: See TracChangeset for help on using the changeset viewer.