Ticket #9470: 9470.patch

File 9470.patch, 8.9 KB (added by simon04, 12 years ago)
  • data/validator/numeric.mapcss

    diff --git a/data/validator/numeric.mapcss b/data/validator/numeric.mapcss
    index 5d3abbb..24b3978 100644
    a b  
    22
    33*[layer =~ /\+.*/] {
    44  throwWarning: tr("layer tag with + sign");
     5  fixAdd: concat("layer=", substring(tag("layer"), 1));
    56  assertMatch: "node layer=+1";
    67  assertNoMatch: "node layer=1";
    78  assertNoMatch: "node layer=-1";
  • src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

    diff --git a/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java b/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
    index 853ae9e..488d779 100644
    a b import org.openstreetmap.josm.data.validation.Severity;  
    2828import org.openstreetmap.josm.data.validation.Test;
    2929import org.openstreetmap.josm.data.validation.TestError;
    3030import org.openstreetmap.josm.gui.mappaint.Environment;
    31 import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory;
     31import org.openstreetmap.josm.gui.mappaint.mapcss.Expression;
    3232import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction;
    3333import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSRule;
    3434import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
    public class MapCSSTagChecker extends Test {  
    5656
    5757    static class TagCheck implements Predicate<OsmPrimitive> {
    5858        protected final List<Selector> selector;
    59         protected final List<Tag> change = new ArrayList<Tag>();
     59        protected final List<PrimitiveToTag> change = new ArrayList<PrimitiveToTag>();
    6060        protected final Map<String, String> keyChange = new LinkedHashMap<String, String>();
    6161        protected final List<Tag> alternatives = new ArrayList<Tag>();
    6262        protected final Map<String, Severity> errors = new HashMap<String, Severity>();
    public class MapCSSTagChecker extends Test {  
    6666            this.selector = selector;
    6767        }
    6868
     69        static abstract class PrimitiveToTag implements Utils.Function<OsmPrimitive, Tag> {
     70
     71            static PrimitiveToTag ofMapCSSObject(final Object obj, final boolean keyOnly) {
     72                if (obj instanceof Expression) {
     73                    return new PrimitiveToTag() {
     74                        @Override
     75                        public Tag apply(OsmPrimitive p) {
     76                            final String s = (String) ((Expression) obj).evaluate(new Environment().withPrimitive(p));
     77                            return keyOnly? new Tag(s) : Tag.ofString(s);
     78                        }
     79                    };
     80                } else if (obj instanceof String) {
     81                    final Tag tag = keyOnly ? new Tag((String) obj) : Tag.ofString((String) obj);
     82                    return new PrimitiveToTag() {
     83                        @Override
     84                        public Tag apply(OsmPrimitive ignore) {
     85                            return tag;
     86                        }
     87                    };
     88                } else {
     89                    return null;
     90                }
     91            }
     92        }
     93
    6994        static TagCheck ofMapCSSRule(final MapCSSRule rule) {
    7095            final TagCheck check = new TagCheck(rule.selectors);
    7196            for (Instruction i : rule.declaration) {
    7297                if (i instanceof Instruction.AssignmentInstruction) {
    7398                    final Instruction.AssignmentInstruction ai = (Instruction.AssignmentInstruction) i;
    74                     final String val = ai.val instanceof ExpressionFactory.ArrayFunction
    75                             ? (String) ((ExpressionFactory.ArrayFunction) ai.val).evaluate(new Environment())
     99                    final String val = ai.val instanceof Expression
     100                            ? (String) ((Expression) ai.val).evaluate(new Environment())
    76101                            : ai.val instanceof String
    77102                            ? (String) ai.val
    78103                            : null;
    79104                    if (ai.key.startsWith("throw")) {
    80105                        final Severity severity = Severity.valueOf(ai.key.substring("throw".length()).toUpperCase());
    81106                        check.errors.put(val, severity);
    82                     } else if ("fixAdd".equals(ai.key) && val != null) {
    83                         check.change.add(Tag.ofString(val));
    84                     } else if ("fixRemove".equals(ai.key) && val != null) {
    85                         CheckParameterUtil.ensureThat(!val.contains("="), "Unexpected '='. Please only specify the key to remove!");
    86                         check.change.add(new Tag(val));
     107                    } else if ("fixAdd".equals(ai.key)) {
     108                        final PrimitiveToTag toTag = PrimitiveToTag.ofMapCSSObject(ai.val, false);
     109                        check.change.add(toTag);
     110                    } else if ("fixRemove".equals(ai.key)) {
     111                        CheckParameterUtil.ensureThat(!(ai.val instanceof String) || !val.contains("="), "Unexpected '='. Please only specify the key to remove!");
     112                        final PrimitiveToTag toTag = PrimitiveToTag.ofMapCSSObject(ai.val, true);
     113                        check.change.add(toTag);
    87114                    } else if ("fixChangeKey".equals(ai.key) && val != null) {
    88115                        CheckParameterUtil.ensureThat(val.contains("=>"), "Separate old from new key by '=>'!");
    89116                        final String[] x = val.split("=>", 2);
    public class MapCSSTagChecker extends Test {  
    158185                return null;
    159186            }
    160187            Collection<Command> cmds = new LinkedList<Command>();
    161             for (Tag tag : change) {
     188            for (PrimitiveToTag toTag : change) {
     189                final Tag tag = toTag.apply(p);
    162190                cmds.add(new ChangePropertyCommand(p, tag.getKey(), tag.getValue()));
    163191            }
    164192            for (Map.Entry<String, String> i : keyChange.entrySet()) {
  • src/org/openstreetmap/josm/gui/mappaint/Cascade.java

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/Cascade.java b/src/org/openstreetmap/josm/gui/mappaint/Cascade.java
    index 0a9107a..26c2eb2 100644
    a b public final class Cascade implements Cloneable {  
    114114    }
    115115
    116116    private static Float toFloat(Object o) {
    117         if (o instanceof Float)
    118             return (Float) o;
    119         if (o instanceof Double)
    120             return new Float((Double) o);
    121         if (o instanceof Integer)
    122             return new Float((Integer) o);
     117        if (o instanceof Number)
     118            return ((Number) o).floatValue();
    123119        if (o instanceof String && !((String) o).isEmpty()) {
    124120            try {
    125121                return Float.parseFloat((String) o);
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java b/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
    index a3fdb3f..a1a994c 100644
    a b public final class ExpressionFactory {  
    364364            System.arraycopy(args, 1, args, 0, args.length - 1);
    365365            return org.openstreetmap.josm.tools.I18n.tr(text, args);
    366366        }
     367
     368        public static String substring(String s, /* due to missing Cascade.convertTo for int*/ float begin) {
     369            return s == null ? null : s.substring((int) begin);
     370        }
     371
     372        public static String substring(String s, float begin, float end) {
     373            return s == null ? null : s.substring((int) begin, (int) end);
     374        }
     375
     376        public static int length(String s) {
     377            return s == null ? 0 : s.length();
     378        }
    367379    }
    368380
    369381    /**
  • test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java

    diff --git a/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java b/test/unit/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerTest.java
    index 567bb0b..43eb475 100644
    a b public class MapCSSTagCheckerTest {  
    4242        assertThat(checks.size(), is(1));
    4343        final MapCSSTagChecker.TagCheck check = checks.get(0);
    4444        assertThat(check, notNullValue());
    45         assertThat(check.change.get(0), is(new Tag("natural")));
    46         assertThat(check.change.get(1), is(new Tag("natural", "wetland")));
    47         assertThat(check.change.get(2), is(new Tag("wetland", "marsh")));
     45        assertThat(check.change.get(0).apply(null), is(new Tag("natural")));
     46        assertThat(check.change.get(1).apply(null), is(new Tag("natural", "wetland")));
     47        assertThat(check.change.get(2).apply(null), is(new Tag("wetland", "marsh")));
    4848        assertThat(check.errors.keySet().iterator().next(), is("natural=marsh is deprecated"));
    4949        final Node n1 = new Node();
    5050        n1.put("natural", "marsh");