From 762d13817fcfac93142963daf2925c40e456112e Mon Sep 17 00:00:00 2001
From: Francescu Garoby <windu.2b@gmail.com>
Date: Sat, 6 Jun 2015 17:25:05 +0200
Subject: [PATCH 2/2] Validate the 'maxweight:*' tags and values

---
 .../josm/data/validation/OsmValidator.java         |  2 +
 .../josm/data/validation/tests/Maxweight.java      | 74 ++++++++++++++++++++++
 .../data/validation/tests/MaxweightTest.groovy     | 73 +++++++++++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 src/org/openstreetmap/josm/data/validation/tests/Maxweight.java
 create mode 100644 test/unit/org/openstreetmap/josm/data/validation/tests/MaxweightTest.groovy

diff --git a/src/org/openstreetmap/josm/data/validation/OsmValidator.java b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
index acd2efa..3a6eae9 100644
--- a/src/org/openstreetmap/josm/data/validation/OsmValidator.java
+++ b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
@@ -42,6 +42,7 @@ import org.openstreetmap.josm.data.validation.tests.Lanes;
 import org.openstreetmap.josm.data.validation.tests.LongSegment;
 import org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker;
 import org.openstreetmap.josm.data.validation.tests.Maxspeed;
+import org.openstreetmap.josm.data.validation.tests.Maxweight;
 import org.openstreetmap.josm.data.validation.tests.MultipolygonTest;
 import org.openstreetmap.josm.data.validation.tests.NameMismatch;
 import org.openstreetmap.josm.data.validation.tests.OpeningHourTest;
@@ -128,6 +129,7 @@ public class OsmValidator implements LayerChangeListener {
         ApiCapabilitiesTest.class, // 3400 .. 3499
         LongSegment.class, // 3500 .. 3599
         Maxspeed.class, // 3600 .. 3699
+        Maxweight.class, // 3600 .. 3799
     };
 
     private static Map<String, Test> allTestsMap;
diff --git a/src/org/openstreetmap/josm/data/validation/tests/Maxweight.java b/src/org/openstreetmap/josm/data/validation/tests/Maxweight.java
new file mode 100644
index 0000000..d8cfb31
--- /dev/null
+++ b/src/org/openstreetmap/josm/data/validation/tests/Maxweight.java
@@ -0,0 +1,74 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.validation.tests;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.validation.Severity;
+import org.openstreetmap.josm.data.validation.Test.TagTest;
+import org.openstreetmap.josm.data.validation.TestError;
+import org.openstreetmap.josm.tools.Predicates;
+import org.openstreetmap.josm.tools.Utils;
+
+/**
+ * Test that validates {@code maxweight:} tags.
+ *
+ */
+public class Maxweight extends TagTest {
+    protected static Pattern maxweightPattern = Pattern.compile("^((\\+?\\d*(\\.\\d+)?)(\\s(t|kg))?)$");
+
+    private static final String[] BLACKLIST = {
+    };
+
+    /**
+     * Constructs a new {@code Maxweight} test.
+     */
+    public Maxweight() {
+        super(tr("Maxweight"),
+              tr("This tests for maxweights, which are usually errors."));
+    }
+
+    protected void checkMaxweightByKey(final OsmPrimitive p, String maxweightKey, Pattern pattern, int errorCode, String errorMessage) {
+        final Collection<String> keysForPattern = new ArrayList<>(Utils.filter(p.keySet(),
+                Predicates.stringContainsPattern(Pattern.compile(maxweightKey))));
+        keysForPattern.removeAll(Arrays.asList(BLACKLIST));
+        if (keysForPattern.isEmpty()) {
+            // nothing to check
+            return;
+        }
+        String value = p.get(keysForPattern.iterator().next());
+        if( !pattern.matcher(value).find()) {
+            errors.add(new TestError(this, Severity.WARNING, tr(errorMessage, maxweightKey), errorCode, p));
+        }
+    }
+
+    protected void checkMaxweight(final OsmPrimitive p) {
+        final String backward = Utils.firstNonNull(p.get("maxweight:backward"), 0.0).toString();
+        final String forward = Utils.firstNonNull(p.get("maxweight:forward"), 0.0).toString();
+        try {
+            if (Float.compare(Float.parseFloat(backward), Float.parseFloat(forward)) == 0 && Float.parseFloat(backward) > 0) {
+                errors.add(new TestError(this, Severity.WARNING,
+                        tr("Value of {0} and {1} are equals. You should merge them in one tag : {2}", "maxweight:backward", "maxweight:forward", "maxweight"), 3710, p));
+            }
+        } catch (NumberFormatException ignore) {
+            if (backward.compareTo(forward) == 0) {
+            errors.add(new TestError(this, Severity.WARNING,
+                    tr("Value of {0} and {1} are equals. You should merge them in one tag : {2}", "maxweight:backward", "maxweight:forward", "maxweight"), 3710, p));
+            }
+        }
+    }
+
+    @Override
+    public void check(OsmPrimitive p) {
+        checkMaxweightByKey(p, "maxweight", maxweightPattern, 3701, "Value of {0} is not correct");
+        checkMaxweightByKey(p, "maxweight:backward", maxweightPattern, 3701, "Value of {0} is not correct");
+        checkMaxweightByKey(p, "maxweight:forward", maxweightPattern, 3701, "Value of {0} is not correct");
+        checkMaxweight(p);
+    }
+
+}
diff --git a/test/unit/org/openstreetmap/josm/data/validation/tests/MaxweightTest.groovy b/test/unit/org/openstreetmap/josm/data/validation/tests/MaxweightTest.groovy
new file mode 100644
index 0000000..297f6ad
--- /dev/null
+++ b/test/unit/org/openstreetmap/josm/data/validation/tests/MaxweightTest.groovy
@@ -0,0 +1,73 @@
+
+package org.openstreetmap.josm.data.validation.tests
+
+import org.openstreetmap.josm.JOSMFixture
+import org.openstreetmap.josm.data.osm.OsmPrimitive
+import org.openstreetmap.josm.data.osm.OsmUtils
+import org.openstreetmap.josm.data.osm.Way
+
+
+class MaxweightTest extends GroovyTestCase {
+
+    Maxweight lanes = new Maxweight()
+
+    @Override
+    void setUp() {
+        JOSMFixture.createUnitTestFixture().init()
+        lanes.initialize()
+        lanes.startTest(null)
+    }
+
+    void test1() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=5"))
+        assert lanes.errors.size() == 0
+    }
+
+    void test2() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=3.5"))
+        assert lanes.errors.size() == 0
+    }
+
+    void test3() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=5 t"))
+        assert lanes.errors.size() == 0
+    }
+
+    void test4() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=3500 kg"))
+        assert lanes.errors.size() == 0
+    }
+
+    void test5() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=3.5 t"))
+        assert lanes.errors.size() == 0
+    }
+
+    void test6() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=5t"))
+        assert lanes.errors.get(0).getMessage() == "Value of maxweight is not correct"
+    }
+
+    void test7() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=3500kg"))
+        assert lanes.errors.get(0).getMessage() == "Value of maxweight is not correct"
+    }
+
+    void test8() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=5 to"))
+        assert lanes.errors.get(0).getMessage() == "Value of maxweight is not correct"
+    }
+
+    void test9() {
+        lanes.check(OsmUtils.createPrimitive("way maxweight=5. t"))
+        assert lanes.errors.get(0).getMessage() == "Value of maxweight is not correct"
+    }
+
+    void test10() {
+        OsmPrimitive p = new Way();
+        p.put("maxweight:forward", "5 t");
+        p.put("maxweight:backward", "5 t");
+        lanes.check(p)
+        assert lanes.errors.get(0).getMessage() == "Value of maxweight:backward and maxweight:forward are equals. You should merge them in one tag : maxweight"
+    }
+}
-- 
2.4.2

