diff --git a/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java b/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
index c5b17638f1..ca5773ef0b 100644
|
a
|
b
|
public class SearchCompiler {
|
| 290 | 290 | public final boolean test(OsmPrimitive object) { |
| 291 | 291 | return match(object); |
| 292 | 292 | } |
| | 293 | |
| | 294 | /** |
| | 295 | * Check if this is a valid match object |
| | 296 | * @return {@code this}, for easy chaining |
| | 297 | * @throws SearchParseError If the match is not valid |
| | 298 | */ |
| | 299 | public Match validate() throws SearchParseError { |
| | 300 | // Default to no-op |
| | 301 | return this; |
| | 302 | } |
| 293 | 303 | } |
| 294 | 304 | |
| 295 | 305 | public abstract static class TaggedMatch extends Match { |
| … |
… |
public class SearchCompiler {
|
| 861 | 871 | return false; |
| 862 | 872 | return true; |
| 863 | 873 | } |
| | 874 | |
| | 875 | @Override |
| | 876 | public Match validate() throws SearchParseError { |
| | 877 | if (this.referenceValue == null) { |
| | 878 | throw new SearchParseError(tr("Reference value must not be null")); |
| | 879 | } |
| | 880 | return this; |
| | 881 | } |
| 864 | 882 | } |
| 865 | 883 | |
| 866 | 884 | /** |
| … |
… |
public class SearchCompiler {
|
| 2108 | 2126 | // factor consists of key:value or key=value |
| 2109 | 2127 | String key = tokenizer.getText(); |
| 2110 | 2128 | if (tokenizer.readIfEqual(Token.EQUALS)) { |
| 2111 | | return new ExactKeyValue(regexSearch, caseSensitive, key, tokenizer.readTextOrNumber()); |
| | 2129 | return new ExactKeyValue(regexSearch, caseSensitive, key, tokenizer.readTextOrNumber()).validate(); |
| 2112 | 2130 | } else if (tokenizer.readIfEqual(Token.TILDE)) { |
| 2113 | | return new ExactKeyValue(true, caseSensitive, key, tokenizer.readTextOrNumber()); |
| | 2131 | return new ExactKeyValue(true, caseSensitive, key, tokenizer.readTextOrNumber()).validate(); |
| 2114 | 2132 | } else if (tokenizer.readIfEqual(Token.LESS_THAN)) { |
| 2115 | | return new ValueComparison(key, tokenizer.readTextOrNumber(), -1); |
| | 2133 | return new ValueComparison(key, tokenizer.readTextOrNumber(), -1).validate(); |
| 2116 | 2134 | } else if (tokenizer.readIfEqual(Token.GREATER_THAN)) { |
| 2117 | | return new ValueComparison(key, tokenizer.readTextOrNumber(), +1); |
| | 2135 | return new ValueComparison(key, tokenizer.readTextOrNumber(), +1).validate(); |
| 2118 | 2136 | } else if (tokenizer.readIfEqual(Token.COLON)) { |
| 2119 | 2137 | // see if we have a Match that takes a data parameter |
| 2120 | 2138 | SimpleMatchFactory factory = simpleMatchFactoryMap.get(key); |
| … |
… |
public class SearchCompiler {
|
| 2123 | 2141 | |
| 2124 | 2142 | UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key); |
| 2125 | 2143 | if (unaryFactory != null) |
| 2126 | | return unaryFactory.get(key, parseFactor(), tokenizer); |
| | 2144 | return unaryFactory.get(key, parseFactor(), tokenizer).validate(); |
| 2127 | 2145 | |
| 2128 | 2146 | // key:value form where value is a string (may be OSM key search) |
| 2129 | 2147 | final String value = tokenizer.readTextOrNumber(); |
| 2130 | | return new KeyValue(key, value != null ? value : "", regexSearch, caseSensitive); |
| | 2148 | return new KeyValue(key, value != null ? value : "", regexSearch, caseSensitive).validate(); |
| 2131 | 2149 | } else if (tokenizer.readIfEqual(Token.QUESTION_MARK)) |
| 2132 | 2150 | return new BooleanMatch(key, false); |
| 2133 | 2151 | else { |
| 2134 | 2152 | SimpleMatchFactory factory = simpleMatchFactoryMap.get(key); |
| 2135 | 2153 | if (factory != null) |
| 2136 | | return factory.get(key, caseSensitive, regexSearch, null); |
| | 2154 | return factory.get(key, caseSensitive, regexSearch, null).validate(); |
| 2137 | 2155 | |
| 2138 | 2156 | UnaryMatchFactory unaryFactory = unaryMatchFactoryMap.get(key); |
| 2139 | 2157 | if (unaryFactory != null) |
| 2140 | | return unaryFactory.get(key, parseFactor(), null); |
| | 2158 | return unaryFactory.get(key, parseFactor(), null).validate(); |
| 2141 | 2159 | |
| 2142 | 2160 | // match string in any key or value |
| 2143 | | return new Any(key, regexSearch, caseSensitive); |
| | 2161 | return new Any(key, regexSearch, caseSensitive).validate(); |
| 2144 | 2162 | } |
| 2145 | 2163 | } else |
| 2146 | 2164 | return null; |
diff --git a/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java b/test/unit/org/openstreetmap/josm/data/osm/search/SearchCompilerTest.java
index 9545c88cd7..1e34009fb6 100644
|
a
|
b
|
import java.util.Collection;
|
| 18 | 18 | import java.util.Collections; |
| 19 | 19 | import java.util.Set; |
| 20 | 20 | |
| | 21 | import nl.jqno.equalsverifier.EqualsVerifier; |
| | 22 | import nl.jqno.equalsverifier.Warning; |
| | 23 | import org.junit.Assert; |
| | 24 | import org.junit.jupiter.api.Test; |
| | 25 | import org.junit.jupiter.api.Timeout; |
| | 26 | import org.junit.jupiter.params.ParameterizedTest; |
| | 27 | import org.junit.jupiter.params.provider.ValueSource; |
| 21 | 28 | import org.openstreetmap.josm.TestUtils; |
| 22 | 29 | import org.openstreetmap.josm.data.coor.LatLon; |
| 23 | 30 | import org.openstreetmap.josm.data.osm.DataSet; |
| … |
… |
import org.openstreetmap.josm.gui.tagging.presets.items.Key;
|
| 42 | 49 | import org.openstreetmap.josm.testutils.annotations.BasicPreferences; |
| 43 | 50 | import org.openstreetmap.josm.tools.Logging; |
| 44 | 51 | |
| 45 | | import nl.jqno.equalsverifier.EqualsVerifier; |
| 46 | | import nl.jqno.equalsverifier.Warning; |
| 47 | | import org.junit.Assert; |
| 48 | | import org.junit.jupiter.api.Test; |
| 49 | | import org.junit.jupiter.api.Timeout; |
| 50 | | |
| 51 | 52 | /** |
| 52 | 53 | * Unit tests for class {@link SearchCompiler}. |
| 53 | 54 | */ |
| … |
… |
class SearchCompilerTest {
|
| 828 | 829 | sc.match(sc.n1, true); |
| 829 | 830 | sc.match(sc.n2, false); |
| 830 | 831 | } |
| | 832 | |
| | 833 | /** |
| | 834 | * Non-regression test for JOSM #21300 |
| | 835 | */ |
| | 836 | @ParameterizedTest |
| | 837 | @ValueSource(strings = {"maxweight<" /* #21300 */, "maxweight>"}) |
| | 838 | void testNonRegression21300(final String searchString) { |
| | 839 | assertThrows(SearchParseError.class, () -> SearchCompiler.compile(searchString)); |
| | 840 | } |
| 831 | 841 | } |