Repository: graphhopper/graphhopper
Pull request #910 (2016-12-14 14:08:31)

Make it possible to add value parser
This PR makes it possible to add value parsers e.g. for our current encoders we do not need number parsing and if need this can be added later. Also currently the behaviour is to trigger later added parsers earlier for parsing so that we can use the firstly added date parse as the last that does the parsing if previous parses did return 'invalid'.

boldtrn: > Also currently the behaviour is to trigger later added parsers earlier for parsing so that we can use the firstly added date parse as the last that does the parsing if previous parses did return 'invalid'.

Good decision, therefore we can also "Override" behavior, like in CSS.

Patch:
diff --git a/core/src/main/java/com/graphhopper/GraphHopper.java b/core/src/main/java/com/graphhopper/GraphHopper.java
index d64ca8b59..85b68b526 100644
--- a/core/src/main/java/com/graphhopper/GraphHopper.java
+++ b/core/src/main/java/com/graphhopper/GraphHopper.java
@@ -1036,7 +1036,7 @@ public class GraphHopper implements GraphHopperAPI {
                     return Collections.emptyList();
 
                 RoutingAlgorithmFactory tmpAlgoFactory = getAlgorithmFactory(hints);
-                Weighting weighting = null;
+                Weighting weighting;
                 QueryGraph queryGraph;
 
                 boolean forceFlexibleMode = hints.getBool(CH.DISABLE, false);
diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java
index db9d1dd2a..e150d466c 100644
--- a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java
+++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalOSMTagInspector.java
@@ -33,19 +33,17 @@ import java.util.*;
 public class ConditionalOSMTagInspector implements ConditionalTagInspector {
     private final Logger logger = LoggerFactory.getLogger(getClass());
     private final List<String> tagsToCheck;
-    private final Map<String, Object> valueMap;
     private final ConditionalParser permitParser, restrictiveParser;
     // enabling by default makes noise but could improve OSM data
     private boolean enabledLogs = true;
 
     public ConditionalOSMTagInspector(Object value, List<String> tagsToCheck,
                                       Set<String> restrictiveValues, Set<String> permittedValues) {
-        this(tagsToCheck, createDefaultMapping(value), restrictiveValues, permittedValues, false);
+        this(tagsToCheck, Arrays.asList(new DateRangeParser((Calendar) value)), restrictiveValues, permittedValues, false);
     }
 
-    public ConditionalOSMTagInspector(List<String> tagsToCheck, Map<String, Object> valueMap,
+    public ConditionalOSMTagInspector(List<String> tagsToCheck, List<? extends ConditionalValueParser> valueParsers,
                                       Set<String> restrictiveValues, Set<String> permittedValues, boolean enabledLogs) {
-        this.valueMap = valueMap;
         this.tagsToCheck = new ArrayList<>(tagsToCheck.size());
         for (String tagToCheck : tagsToCheck) {
             this.tagsToCheck.add(tagToCheck + ":conditional");
@@ -57,13 +55,15 @@ public class ConditionalOSMTagInspector implements ConditionalTagInspector {
         boolean logUnsupportedFeatures = false;
         this.permitParser = new ConditionalParser(permittedValues, logUnsupportedFeatures);
         this.restrictiveParser = new ConditionalParser(restrictiveValues, logUnsupportedFeatures);
+        for (ConditionalValueParser cvp : valueParsers) {
+            permitParser.addConditionalValueParser(cvp);
+            restrictiveParser.addConditionalValueParser(cvp);
+        }
     }
 
-    static Map<String, Object> createDefaultMapping(Object value) {
-        // parse date range and value is the time
-        Map<String, Object> map = new HashMap<String, Object>(1);
-        map.put(DateRange.KEY, value);
-        return map;
+    public void addValueParser(ConditionalValueParser vp) {
+        permitParser.addConditionalValueParser(vp);
+        restrictiveParser.addConditionalValueParser(vp);
     }
 
     @Override
@@ -84,22 +84,19 @@ public class ConditionalOSMTagInspector implements ConditionalTagInspector {
                 continue;
 
             try {
-                ValueRange valueRange;
-                if (checkPermissiveValues)
-                    valueRange = permitParser.getRange(val);
-                else
-                    valueRange = restrictiveParser.getRange(val);
-
-                if (valueRange != null) {
-                    Object value = valueMap.get(valueRange.getKey());
-                    if (value != null && valueRange.isInRange(value))
+                if (checkPermissiveValues) {
+                    if (permitParser.checkCondition(val))
+                        return true;
+                } else {
+                    if (restrictiveParser.checkCondition(val))
                         return true;
                 }
+
             } catch (Exception e) {
                 if (enabledLogs) {
                     // log only if no date ala 21:00 as currently date and numbers do not support time precise restrictions
                     if (!val.contains(":"))
-                        logger.warn(way.getId() + " - could not parse the conditional value:" + val + " of tag:" + tagToCheck + ". Exception:" + e.getMessage());
+                        logger.warn("for way " + way.getId() + " could not parse the conditional value '" + val + "' of tag '" + tagToCheck + "'. Exception:" + e.getMessage());
                 }
             }
         }
diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalParser.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalParser.java
index b39009d4b..81f407d8f 100644
--- a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalParser.java
+++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalParser.java
@@ -21,6 +21,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -33,6 +36,7 @@ import java.util.Set;
 public class ConditionalParser {
     private final Logger logger = LoggerFactory.getLogger(getClass());
     private final Set<String> restrictedTags;
+    private final List<ConditionalValueParser> valueParsers = new ArrayList<>(5);
     private final boolean enabledLogs;
 
     public ConditionalParser(Set<String> restrictedTags) {
@@ -45,14 +49,69 @@ public class ConditionalParser {
         this.enabledLogs = enabledLogs;
     }
 
-    public ValueRange getRange(String conditionalTag) throws ParseException {
+    public static ConditionalValueParser createNumberParser(final String assertKey, final Number obj) {
+        return new ConditionalValueParser() {
+            @Override
+            public ConditionState checkCondition(String conditionalValue) throws ParseException {
+                int indexLT = conditionalValue.indexOf("<");
+                if (indexLT > 0 && conditionalValue.length() > 2) {
+                    final String key = conditionalValue.substring(0, indexLT).trim();
+                    if (!assertKey.equals(key))
+                        return ConditionState.INVALID;
+
+                    if (conditionalValue.charAt(indexLT + 1) == '=')
+                        indexLT++;
+                    final double value = parseNumber(conditionalValue.substring(indexLT + 1));
+                    if (obj.doubleValue() < value)
+                        return ConditionState.TRUE;
+                    else
+                        return ConditionState.FALSE;
+                }
+
+                int indexGT = conditionalValue.indexOf(">");
+                if (indexGT > 0 && conditionalValue.length() > 2) {
+                    final String key = conditionalValue.substring(0, indexGT).trim();
+                    if (!assertKey.equals(key))
+                        return ConditionState.INVALID;
+
+                    // for now just ignore equals sign
+                    if (conditionalValue.charAt(indexGT + 1) == '=')
+                        indexGT++;
+
+                    final double value = parseNumber(conditionalValue.substring(indexGT + 1));
+                    if (obj.doubleValue() > value)
+                        return ConditionState.TRUE;
+                    else
+                        return ConditionState.FALSE;
+                }
+
+                return ConditionState.INVALID;
+            }
+        };
+    }
+
+    /**
+     * This method adds a new value parser. The one added last has a higher priority.
+     */
+    public ConditionalParser addConditionalValueParser(ConditionalValueParser vp) {
+        valueParsers.add(0, vp);
+        return this;
+    }
+
+    public ConditionalParser setConditionalValueParser(ConditionalValueParser vp) {
+        valueParsers.clear();
+        valueParsers.add(vp);
+        return this;
+    }
+
+    public boolean checkCondition(String conditionalTag) throws ParseException {
         if (conditionalTag == null || conditionalTag.isEmpty() || !conditionalTag.contains("@"))
-            return null;
+            return false;
 
         if (conditionalTag.contains(";")) {
             if (enabledLogs)
                 logger.warn("We do not support multiple conditions yet: " + conditionalTag);
-            return null;
+            return false;
         }
 
         String[] conditionalArr = conditionalTag.split("@");
@@ -62,59 +121,22 @@ public class ConditionalParser {
 
         String restrictiveValue = conditionalArr[0].trim();
         if (!restrictedTags.contains(restrictiveValue))
-            return null;
-
-        String conditional = conditionalArr[1];
-        conditional = conditional.replace('(', ' ');
-        conditional = conditional.replace(')', ' ');
-        conditional = conditional.trim();
-
-        int index = conditional.indexOf(">");
-        if (index > 0 && conditional.length() > 2) {
-            final String key = conditional.substring(0, index).trim();
-            // for now just ignore equals sign
-            if (conditional.charAt(index + 1) == '=')
-                index++;
-
-            final double value = parseNumber(conditional.substring(index + 1));
-            return new ValueRange<Number>() {
-                @Override
-                public boolean isInRange(Number obj) {
-                    return obj.doubleValue() > value;
-                }
-
-                @Override
-                public String getKey() {
-                    return key;
-                }
-            };
-        }
-
-        index = conditional.indexOf("<");
-        if (index > 0 && conditional.length() > 2) {
-            final String key = conditional.substring(0, index).trim();
-            if (conditional.charAt(index + 1) == '=')
-                index++;
+            return false;
 
-            final double value = parseNumber(conditional.substring(index + 1));
-            return new ValueRange<Number>() {
+        String conditionalValue = conditionalArr[1];
+        conditionalValue = conditionalValue.replace('(', ' ');
+        conditionalValue = conditionalValue.replace(')', ' ');
+        conditionalValue = conditionalValue.trim();
 
-                @Override
-                public boolean isInRange(Number obj) {
-                    return obj.doubleValue() < value;
-                }
-
-                @Override
-                public String getKey() {
-                    return key;
-                }
-            };
+        for (ConditionalValueParser valueParser : valueParsers) {
+            ConditionalValueParser.ConditionState c = valueParser.checkCondition(conditionalValue);
+            if (c.isValid())
+                return c.isCheckPassed();
         }
-
-        return DateRangeParser.parseDateRange(conditional);
+        return false;
     }
 
-    protected double parseNumber(String str) {
+    protected static double parseNumber(String str) {
         int untilIndex = str.length() - 1;
         for (; untilIndex >= 0; untilIndex--) {
             if (Character.isDigit(str.charAt(untilIndex)))
diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalValueParser.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalValueParser.java
new file mode 100644
index 000000000..6d1925da4
--- /dev/null
+++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/ConditionalValueParser.java
@@ -0,0 +1,39 @@
+package com.graphhopper.reader.osm.conditional;
+
+import java.text.ParseException;
+
+/**
+ * This interface defines how to parse a OSM value from conditional restrictions.
+ */
+public interface ConditionalValueParser {
+
+    /**
+     * This method checks if the condition is satisfied for this parser.
+     */
+    ConditionState checkCondition(String conditionalValue) throws ParseException;
+
+    enum ConditionState {
+        TRUE(true, true),
+        FALSE(true, false),
+        INVALID(false, false);
+
+        boolean valid;
+        boolean checkPassed;
+
+        ConditionState(boolean valid, boolean checkPassed) {
+            this.valid = valid;
+            this.checkPassed = checkPassed;
+        }
+
+        public boolean isValid() {
+            return valid;
+        }
+
+        public boolean isCheckPassed() {
+            if (!isValid())
+                throw new IllegalStateException("Cannot call this method for invalid state");
+
+            return checkPassed;
+        }
+    }
+}
diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRange.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRange.java
index c8e5aeb60..2cc4dd51e 100644
--- a/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRange.java
+++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRange.java
@@ -24,12 +24,10 @@ import java.util.Calendar;
 
 /**
  * This class represents a date range and is able to determine if a given date is in that range.
- * <p>
  *
  * @author Robin Boldt
  */
-public class DateRange implements ValueRange<Calendar> {
-    public static final String KEY = "DateRange";
+public class DateRange {
     private final Calendar from;
     private final Calendar to;
     // Do not compare years
@@ -43,7 +41,7 @@ public class DateRange implements ValueRange<Calendar> {
 
         // This should never happen
         if (fromCal.get(Calendar.ERA) != toCal.get(Calendar.ERA)) {
-            throw new IllegalArgumentException("Different ERAs are not allowed. From:" + from + " To:" + to);
+            throw new IllegalArgumentException("Different calendar eras are not allowed. From:" + from + " To:" + to);
         }
 
         if (from.isYearless() && to.isYearless()) {
@@ -56,7 +54,7 @@ public class DateRange implements ValueRange<Calendar> {
 
         if (fromCal.getTimeInMillis() > toCal.getTimeInMillis()) {
             if (!yearless && !dayOnly) {
-                throw new IllegalArgumentException("From after to makes no sense, except for isYearless and isDayOnly DateRanges. From:" + from + " To:" + to);
+                throw new IllegalArgumentException("'from' after 'to' not allowed, except for isYearless and isDayOnly DateRanges. From:" + from + " To:" + to);
             } else {
                 reverse = true;
             }
@@ -66,12 +64,6 @@ public class DateRange implements ValueRange<Calendar> {
         this.to = to.getMax();
     }
 
-    @Override
-    public String getKey() {
-        return KEY;
-    }
-
-    @Override
     public boolean isInRange(Calendar date) {
         if (!yearless && !dayOnly)
             return date.after(from) && date.before(to);
diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRangeParser.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRangeParser.java
index a496697e5..03eb23ef7 100644
--- a/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRangeParser.java
+++ b/core/src/main/java/com/graphhopper/reader/osm/conditional/DateRangeParser.java
@@ -36,16 +36,26 @@ import static com.graphhopper.util.Helper.createFormatter;
  *
  * @author Robin Boldt
  */
-public class DateRangeParser {
+public class DateRangeParser implements ConditionalValueParser {
     private static final DateFormat YEAR_MONTH_DAY_DF = createFormatter("yyyy MMM dd");
     private static final DateFormat MONTH_DAY_DF = createFormatter("MMM dd");
     private static final DateFormat MONTH_DAY2_DF = createFormatter("dd.MM");
     private static final DateFormat YEAR_MONTH_DF = createFormatter("yyyy MMM");
     private static final DateFormat MONTH_DF = createFormatter("MMM");
     private static final List<String> DAY_NAMES = Arrays.asList(new String[]{
-        "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"
+            "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"
     });
 
+    private Calendar date;
+
+    public DateRangeParser() {
+        this(createCalendar());
+    }
+
+    public DateRangeParser(Calendar date) {
+        this.date = date;
+    }
+
     public static Calendar createCalendar() {
         // Use locale US as exception here (instead of UK) to match week order "Su-Sa" used in Calendar for day_of_week.
         // Inconsistent but we should not use US for other date handling stuff like strange default formatting, related to #647.
@@ -94,13 +104,14 @@ public class DateRangeParser {
         return parsedCalendar;
     }
 
-    public static DateRange parseDateRange(String dateRangeString) throws ParseException {
+    public DateRange getRange(String dateRangeString) throws ParseException {
         if (dateRangeString == null || dateRangeString.isEmpty())
             throw new IllegalArgumentException("Passing empty Strings is not allowed");
 
         String[] dateArr = dateRangeString.split("-");
         if (dateArr.length > 2 || dateArr.length < 1)
-            throw new IllegalArgumentException("Only Strings containing two Date separated by a '-' or a single Date are allowed");
+            return null;
+        // throw new IllegalArgumentException("Only Strings containing two Date separated by a '-' or a single Date are allowed");
 
         ParsedCalendar from = parseDateString(dateArr[0]);
         ParsedCalendar to;
@@ -114,4 +125,15 @@ public class DateRangeParser {
         return new DateRange(from, to);
     }
 
+    @Override
+    public ConditionState checkCondition(String dateRangeString) throws ParseException {
+        DateRange dr = getRange(dateRangeString);
+        if (dr == null)
+            return ConditionState.INVALID;
+
+        if (dr.isInRange(date))
+            return ConditionState.TRUE;
+        else
+            return ConditionState.FALSE;
+    }
 }
diff --git a/core/src/main/java/com/graphhopper/reader/osm/conditional/ValueRange.java b/core/src/main/java/com/graphhopper/reader/osm/conditional/ValueRange.java
deleted file mode 100644
index 5867d3e19..000000000
--- a/core/src/main/java/com/graphhopper/reader/osm/conditional/ValueRange.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  Licensed to GraphHopper GmbH under one or more contributor
- *  license agreements. See the NOTICE file distributed with this work for 
- *  additional information regarding copyright ownership.
- * 
- *  GraphHopper GmbH licenses this file to you under the Apache License, 
- *  Version 2.0 (the "License"); you may not use this file except in 
- *  compliance with the License. You may obtain a copy of the License at
- * 
- *       http://www.apache.org/licenses/LICENSE-2.0
- * 
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package com.graphhopper.reader.osm.conditional;
-
-/**
- * @author Peter Karich
- */
-public interface ValueRange<T> {
-    /**
-     * Checks if the value is in range of this ValueRange check method.
-     */
-    boolean isInRange(T value);
-
-    String getKey();
-}


Test patch:
diff --git a/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalParserTest.java b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalParserTest.java
index d78a2380a..811913688 100644
--- a/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalParserTest.java
+++ b/core/src/test/java/com/graphhopper/reader/osm/conditional/ConditionalParserTest.java
@@ -31,11 +31,10 @@ import static org.junit.Assert.*;
  * @author Robin Boldt
  */
 public class ConditionalParserTest extends CalendarBasedTest {
-    ConditionalParser parser;
 
-    @Before
-    public void setup() {
-        HashSet<String> restrictedValues = new HashSet<String>();
+    private final HashSet<String> restrictedValues = new HashSet<String>();
+
+    public ConditionalParserTest() {
         restrictedValues.add("private");
         restrictedValues.add("agricultural");
         restrictedValues.add("forestry");
@@ -44,86 +43,94 @@ public class ConditionalParserTest extends CalendarBasedTest {
         restrictedValues.add("delivery");
         restrictedValues.add("military");
         restrictedValues.add("emergency");
+    }
 
-        parser = new ConditionalParser(restrictedValues);
+    ConditionalParser createParser(Calendar date) {
+        return new ConditionalParser(restrictedValues).addConditionalValueParser(new DateRangeParser(date));
     }
 
     @Test
     public void testParseConditional() throws ParseException {
-        ValueRange dateRange = parser.getRange("no @ (2015 Sep 1-2015 Sep 30)");
-        assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.AUGUST, 31)));
-        assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.SEPTEMBER, 30)));
+        String str = "no @ (2015 Sep 1-2015 Sep 30)";
+        assertFalse(createParser(getCalendar(2015, Calendar.AUGUST, 31)).checkCondition(str));
+        assertTrue(createParser(getCalendar(2015, Calendar.SEPTEMBER, 30)).checkCondition(str));
     }
 
     @Test
     public void testParseAllowingCondition() throws ParseException {
-        ValueRange dateRange = parser.getRange("yes @ (2015 Sep 1-2015 Sep 30)");
-        assertNull(dateRange);
+        assertFalse(createParser(getCalendar(2015, Calendar.JANUARY, 12)).
+                checkCondition("yes @ (2015 Sep 1-2015 Sep 30)"));
     }
 
     @Test
     public void testParsingOfLeading0() throws ParseException {
-        ValueRange dateRange = parser.getRange("no @ (01.11. - 31.03.)");
-        assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 2)));
+        assertTrue(createParser(getCalendar(2015, Calendar.DECEMBER, 2)).
+                checkCondition("no @ (01.11. - 31.03.)"));
 
-        dateRange = parser.getRange("no @ (01.11 - 31.03)");
-        assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 2)));
+        assertTrue(createParser(getCalendar(2015, Calendar.DECEMBER, 2)).
+                checkCondition("no @ (01.11 - 31.03)"));
     }
 
     @Test
     public void testGetRange() throws Exception {
+        assertTrue(ConditionalParser.createNumberParser("weight", 11).checkCondition("weight > 10").isCheckPassed());
+        assertFalse(ConditionalParser.createNumberParser("weight", 10).checkCondition("weight > 10").isCheckPassed());
+        assertFalse(ConditionalParser.createNumberParser("weight", 9).checkCondition("weight > 10").isCheckPassed());
+        assertFalse(ConditionalParser.createNumberParser("xy", 9).checkCondition("weight > 10").isValid());
+
         Set<String> set = new HashSet<>();
         set.add("no");
-        ConditionalParser instance = new ConditionalParser(set);
-
-        ValueRange result = instance.getRange("no @ weight > 10");
-        assertEquals("weight", result.getKey());
-        assertTrue(result.isInRange(11));
-        assertFalse(result.isInRange(10));
-        assertFalse(result.isInRange(9));
-
-        result = instance.getRange("no @weight>10");
-        assertTrue(result.isInRange(11));
-        assertFalse(result.isInRange(10));
-        assertFalse(result.isInRange(9));
-
-        result = instance.getRange("no @ weight < 10");
-        assertFalse(result.isInRange(11));
-        assertFalse(result.isInRange(10));
-        assertTrue(result.isInRange(9));
+        ConditionalParser instance = new ConditionalParser(set).
+                setConditionalValueParser(ConditionalParser.createNumberParser("weight", 11));
+        assertTrue(instance.checkCondition("no @weight>10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 10));
+        assertFalse(instance.checkCondition("no @weight>10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 9));
+        assertFalse(instance.checkCondition("no @weight>10"));
+
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 11));
+        assertFalse(instance.checkCondition("no @ weight < 10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 10));
+        assertFalse(instance.checkCondition("no @ weight < 10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 9));
+        assertTrue(instance.checkCondition("no @ weight < 10"));
 
         // equals is ignored for now (not that bad for weight)
-        result = instance.getRange("no @ weight <= 10");
-        assertFalse(result.isInRange(11));
-        assertFalse(result.isInRange(10));
-        assertTrue(result.isInRange(9));
-
-        result = instance.getRange("no @ weight<=10");
-        assertFalse(result.isInRange(11));
-        assertFalse(result.isInRange(10));
-        assertTrue(result.isInRange(9));
-
-        result = instance.getRange("no @ height > 2");
-        assertEquals("height", result.getKey());
-        assertFalse(result.isInRange(1));
-        assertFalse(result.isInRange(2));
-        assertTrue(result.isInRange(3));
-
-        // unit is allowed according to wiki :/
-        result = instance.getRange("no @ height > 2t");
-        assertEquals("height", result.getKey());
-        assertFalse(result.isInRange(1));
-        assertFalse(result.isInRange(2));
-        assertTrue(result.isInRange(3));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 11));
+        assertFalse(instance.checkCondition("no @ weight <= 10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 10));
+        assertFalse(instance.checkCondition("no @ weight <= 10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 9));
+        assertTrue(instance.checkCondition("no @ weight <= 10"));
+
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 11));
+        assertFalse(instance.checkCondition("no @ weight<=10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 10));
+        assertFalse(instance.checkCondition("no @ weight<=10"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("weight", 9));
+        assertTrue(instance.checkCondition("no @ weight<=10"));
+
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("height", 1));
+        assertFalse(instance.checkCondition("no @ height > 2"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("height", 2));
+        assertFalse(instance.checkCondition("no @ height > 2"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("height", 3));
+        assertTrue(instance.checkCondition("no @ height > 2"));
+
+        // unit is allowed according to wiki
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("height", 1));
+        assertFalse(instance.checkCondition("no @ height > 2t"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("height", 2));
+        assertFalse(instance.checkCondition("no @ height > 2t"));
+        instance.setConditionalValueParser(ConditionalParser.createNumberParser("height", 3));
+        assertTrue(instance.checkCondition("no @ height > 2t"));
     }
 
     @Test
     public void parseNumber() {
-        // TODO currently no unit conversation is done which can be required if a different one is passed in isInRange        
-        Set<String> set = new HashSet<>();
-        ConditionalParser p = new ConditionalParser(set);
-        assertEquals(3, p.parseNumber("3t"), .1);
-        assertEquals(3.1, p.parseNumber("3.1 t"), .1);
-        assertEquals(3, p.parseNumber("3 meters"), .1);
+        // TODO currently no unit conversation is done which can be required if a different one is passed in checkCondition
+        assertEquals(3, ConditionalParser.parseNumber("3t"), .1);
+        assertEquals(3.1, ConditionalParser.parseNumber("3.1 t"), .1);
+        assertEquals(3, ConditionalParser.parseNumber("3 meters"), .1);
     }
 }
diff --git a/core/src/test/java/com/graphhopper/reader/osm/conditional/DateRangeParserTest.java b/core/src/test/java/com/graphhopper/reader/osm/conditional/DateRangeParserTest.java
index 92c5284fe..eeaa8f6ef 100644
--- a/core/src/test/java/com/graphhopper/reader/osm/conditional/DateRangeParserTest.java
+++ b/core/src/test/java/com/graphhopper/reader/osm/conditional/DateRangeParserTest.java
@@ -28,6 +28,8 @@ import static org.junit.Assert.*;
  * @author Robin Boldt
  */
 public class DateRangeParserTest extends CalendarBasedTest {
+    final DateRangeParser dateRangeParser = new DateRangeParser();
+
     @Test
     public void testParseConditional() throws ParseException {
         assertSameDate(2014, Calendar.DECEMBER, 15, "2014 Dec 15");
@@ -39,13 +41,13 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testToString() throws ParseException {
-        DateRange instance = DateRangeParser.parseDateRange("Mar-Oct");
+        DateRange instance = dateRangeParser.getRange("Mar-Oct");
         assertEquals("yearless:true, dayOnly:false, reverse:false, from:1970-03-01T00:00:00Z, to:1970-10-31T23:59:59Z", instance.toString());
     }
 
     @Test
     public void testParseSimpleDateRange() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("2014 Aug 10-2014 Aug 14");
+        DateRange dateRange = dateRangeParser.getRange("2014 Aug 10-2014 Aug 14");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 9)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 10)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 12)));
@@ -55,7 +57,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSimpleDateRangeWithoutYear() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Aug 10-Aug 14");
+        DateRange dateRange = dateRangeParser.getRange("Aug 10-Aug 14");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 9)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 10)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 12)));
@@ -65,7 +67,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSimpleDateRangeWithoutYearAndDay() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Jul-Aug");
+        DateRange dateRange = dateRangeParser.getRange("Jul-Aug");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.JUNE, 9)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.JULY, 10)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 12)));
@@ -74,7 +76,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSimpleDateRangeWithoutYearAndDay2() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Mar-Sep");
+        DateRange dateRange = dateRangeParser.getRange("Mar-Sep");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.FEBRUARY, 25)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.MARCH, 1)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30)));
@@ -83,7 +85,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseReverseDateRange() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("2014 Aug 14-2015 Mar 10");
+        DateRange dateRange = dateRangeParser.getRange("2014 Aug 14-2015 Mar 10");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 13)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 14)));
         assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.MARCH, 10)));
@@ -92,7 +94,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseReverseDateRangeWithoutYear() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Aug 14-Aug 10");
+        DateRange dateRange = dateRangeParser.getRange("Aug 14-Aug 10");
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.JANUARY, 9)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 9)));
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 10)));
@@ -104,7 +106,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseReverseDateRangeWithoutYearAndDay() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Sep-Mar");
+        DateRange dateRange = dateRangeParser.getRange("Sep-Mar");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.DECEMBER, 24)));
@@ -115,7 +117,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseReverseDateRangeWithoutYearAndDay_645() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Aug 10-Jan");
+        DateRange dateRange = dateRangeParser.getRange("Aug 10-Jan");
         assertFalse(dateRange.isInRange(getCalendar(2016, Calendar.AUGUST, 9)));
         assertTrue(dateRange.isInRange(getCalendar(2016, Calendar.AUGUST, 10)));
         assertTrue(dateRange.isInRange(getCalendar(2016, Calendar.JANUARY, 1)));
@@ -126,7 +128,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSingleDateRange() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("2014 Sep 1");
+        DateRange dateRange = dateRangeParser.getRange("2014 Sep 1");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1)));
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30)));
@@ -136,7 +138,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSingleDateRangeWithoutDay() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("2014 Sep");
+        DateRange dateRange = dateRangeParser.getRange("2014 Sep");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30)));
@@ -146,7 +148,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSingleDateRangeWithoutYearAndDay() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Sep");
+        DateRange dateRange = dateRangeParser.getRange("Sep");
         assertFalse(dateRange.isInRange(getCalendar(2014, Calendar.AUGUST, 31)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 1)));
         assertTrue(dateRange.isInRange(getCalendar(2014, Calendar.SEPTEMBER, 30)));
@@ -155,7 +157,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSingleDateRangeOneDayOnly() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Sa");
+        DateRange dateRange = dateRangeParser.getRange("Sa");
         assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 25)));
         assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 26)));
         assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 27)));
@@ -163,7 +165,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSingleDateRangeOneDayOnlyIncludingPh() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Su, PH");
+        DateRange dateRange = dateRangeParser.getRange("Su, PH");
         assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 26)));
         assertTrue(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 27)));
         assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 28)));
@@ -171,7 +173,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test
     public void testParseSingleDateRangeDayOnly() throws ParseException {
-        DateRange dateRange = DateRangeParser.parseDateRange("Mo-Fr");
+        DateRange dateRange = dateRangeParser.getRange("Mo-Fr");
         assertTrue(dateRange.dayOnly);
         assertFalse(dateRange.reverse);
         assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 20)));
@@ -186,7 +188,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
         // This is reverse since Su=7 and Mo=1 
         // Note: If we use Locale.Germany or Locale.UK for calendar creation 
         // then cal.set(DAY_OF_WEEK, 7) results in a "time in millis" after Saturday leading to reverse=false
-        DateRange dateRange = DateRangeParser.parseDateRange("Sa-Su");
+        DateRange dateRange = dateRangeParser.getRange("Sa-Su");
         assertTrue(dateRange.dayOnly);
         assertTrue(dateRange.reverse);
         assertFalse(dateRange.isInRange(getCalendar(2015, Calendar.DECEMBER, 25)));
@@ -197,7 +199,7 @@ public class DateRangeParserTest extends CalendarBasedTest {
 
     @Test(expected = ParseException.class)
     public void testParseUnparsableDate() throws ParseException {
-        DateRangeParser.parseDateRange("Sat");
+        dateRangeParser.getRange("Sat");
         fail();
     }