Changeset 8838 in josm


Ignore:
Timestamp:
2015-10-08T21:38:54+02:00 (4 years ago)
Author:
simon04
Message:

fix #11894 - Search: ">" unexpected behavior when values are not numbers

key<X and key>X behave as follows:

  • missing tag for key: no match
  • if value for key or X is in ISO8601 format, perform string comparison
  • if X is a numeric value, perform numeric comparison
  • otherwise perform natural string comparison using AlphanumComparator
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java

    r8836 r8838  
    3333import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser;
    3434import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.ParseException;
     35import org.openstreetmap.josm.tools.AlphanumComparator;
    3536import org.openstreetmap.josm.tools.Geometry;
    3637import org.openstreetmap.josm.tools.Predicate;
     
    613614        private final String key;
    614615        private final String referenceValue;
     616        private final Double referenceNumber;
    615617        private final int compareMode;
     618        private static final Pattern ISO8601 = Pattern.compile("\\d+-\\d+-\\d+");
    616619
    617620        public ValueComparison(String key, String referenceValue, int compareMode) {
    618621            this.key = key;
    619622            this.referenceValue = referenceValue;
     623            Double v = null;
     624            try {
     625                v = Double.parseDouble(referenceValue);
     626            } catch (NumberFormatException ignore) {
     627            }
     628            this.referenceNumber = v;
    620629            this.compareMode = compareMode;
    621630        }
     
    623632        @Override
    624633        public boolean match(OsmPrimitive osm) {
    625             int compareResult;
    626             String currentValue = osm.get(key);
    627             if (currentValue == null) return false;
    628             try {
    629                 compareResult = Double.compare(
    630                         Double.parseDouble(currentValue),
    631                         Double.parseDouble(referenceValue)
    632                 );
    633             } catch (NumberFormatException ignore) {
    634                 compareResult = osm.get(key).compareTo(referenceValue);
     634            final String currentValue = osm.get(key);
     635            final int compareResult;
     636            if (currentValue == null) {
     637                return false;
     638            } else if (ISO8601.matcher(currentValue).matches() || ISO8601.matcher(referenceValue).matches()) {
     639                compareResult = currentValue.compareTo(referenceValue);
     640            } else if (referenceNumber != null) {
     641                try {
     642                    compareResult = Double.compare(Double.parseDouble(currentValue), referenceNumber);
     643                } catch (NumberFormatException ignore) {
     644                    return false;
     645                }
     646            } else {
     647                compareResult = AlphanumComparator.getInstance().compare(currentValue, referenceValue);
    635648            }
    636649            return compareMode < 0 ? compareResult < 0 : compareMode > 0 ? compareResult > 0 : compareResult == 0;
  • trunk/test/unit/org/openstreetmap/josm/actions/search/SearchCompilerTest.java

    r8811 r8838  
    5454        Assert.assertFalse(c1.match(newPrimitive("start_date", "1000")));
    5555        Assert.assertTrue(c1.match(newPrimitive("start_date", "101010")));
     56
    5657        final SearchCompiler.Match c2 = SearchCompiler.compile("start_date<1960");
    5758        Assert.assertTrue(c2.match(newPrimitive("start_date", "1950-01-01")));
     
    6061        Assert.assertTrue(c2.match(newPrimitive("start_date", "1000")));
    6162        Assert.assertTrue(c2.match(newPrimitive("start_date", "200")));
     63
    6264        final SearchCompiler.Match c3 = SearchCompiler.compile("name<I");
    6365        Assert.assertTrue(c3.match(newPrimitive("name", "Alpha")));
    6466        Assert.assertFalse(c3.match(newPrimitive("name", "Sigma")));
     67
    6568        final SearchCompiler.Match c4 = SearchCompiler.compile("\"start_date\"<1960");
    6669        Assert.assertTrue(c4.match(newPrimitive("start_date", "1950-01-01")));
    6770        Assert.assertFalse(c4.match(newPrimitive("start_date", "2000")));
    6871
     72        final SearchCompiler.Match c5 = SearchCompiler.compile("height>180");
     73        Assert.assertTrue(c5.match(newPrimitive("height", "200")));
     74        Assert.assertTrue(c5.match(newPrimitive("height", "99999")));
     75        Assert.assertFalse(c5.match(newPrimitive("height", "50")));
     76        Assert.assertFalse(c5.match(newPrimitive("height", "-9999")));
     77        Assert.assertFalse(c5.match(newPrimitive("height", "fixme")));
     78
     79        final SearchCompiler.Match c6 = SearchCompiler.compile("name>C");
     80        Assert.assertTrue(c6.match(newPrimitive("name", "Delta")));
     81        Assert.assertFalse(c6.match(newPrimitive("name", "Alpha")));
    6982    }
    7083
Note: See TracChangeset for help on using the changeset viewer.