Changeset 17762 in josm
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactory.java
r17745 r17762 2 2 package org.openstreetmap.josm.gui.mappaint.mapcss; 3 3 4 import java.lang.reflect.Method;5 4 import java.text.MessageFormat; 6 import java.util.Arrays;7 5 import java.util.EnumSet; 6 import java.util.HashMap; 7 import java.util.Locale; 8 import java.util.Map; 8 9 import java.util.Objects; 9 10 import java.util.Set; … … 33 34 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.TagCondition; 34 35 import org.openstreetmap.josm.tools.CheckParameterUtil; 35 import org.openstreetmap.josm.tools.JosmRuntimeException;36 36 import org.openstreetmap.josm.tools.Utils; 37 37 … … 883 883 public static class PseudoClassCondition implements Condition { 884 884 885 final Method method; 886 final boolean not; 887 888 protected PseudoClassCondition(Method method, boolean not) { 889 this.method = method; 890 this.not = not; 885 static final Map<String, PseudoClassCondition> CONDITION_MAP = new HashMap<>(); 886 887 static { 888 PseudoClassCondition.register("anticlockwise", PseudoClasses::anticlockwise); 889 PseudoClassCondition.register("areaStyle", PseudoClasses::areaStyle); 890 PseudoClassCondition.register("clockwise", PseudoClasses::clockwise); 891 PseudoClassCondition.register("closed", PseudoClasses::closed); 892 PseudoClassCondition.register("closed2", PseudoClasses::closed2); 893 PseudoClassCondition.register("completely_downloaded", PseudoClasses::completely_downloaded); 894 PseudoClassCondition.register("connection", PseudoClasses::connection); 895 PseudoClassCondition.register("inDownloadedArea", PseudoClasses::inDownloadedArea); 896 PseudoClassCondition.register("modified", PseudoClasses::modified); 897 PseudoClassCondition.register("new", PseudoClasses::_new); 898 PseudoClassCondition.register("righthandtraffic", PseudoClasses::righthandtraffic); 899 PseudoClassCondition.register("sameTags", PseudoClasses::sameTags); 900 PseudoClassCondition.register("selected", PseudoClasses::selected); 901 PseudoClassCondition.register("tagged", PseudoClasses::tagged); 902 PseudoClassCondition.register("unclosed_multipolygon", PseudoClasses::unclosed_multipolygon); 903 PseudoClassCondition.register("unconnected", PseudoClasses::unconnected); 904 } 905 906 private static void register(String name, Predicate<Environment> predicate) { 907 CONDITION_MAP.put(clean(name), new PseudoClassCondition(":" + name, predicate)); 908 CONDITION_MAP.put("!" + clean(name), new PseudoClassCondition("!:" + name, predicate.negate())); 909 } 910 911 private final String name; 912 private final Predicate<Environment> predicate; 913 914 protected PseudoClassCondition(String name, Predicate<Environment> predicate) { 915 this.name = name; 916 this.predicate = predicate; 891 917 } 892 918 … … 903 929 return new OpenEndPseudoClassCondition(not); 904 930 } 905 final Method method = getMethod(id); 906 if (method != null) { 907 return new PseudoClassCondition(method, not); 931 String cleanId = not ? clean("!" + id) : clean(id); 932 PseudoClassCondition condition = CONDITION_MAP.get(cleanId); 933 if (condition != null) { 934 return condition; 908 935 } 909 936 throw new MapCSSException("Invalid pseudo class specified: " + id); 910 }911 912 protected static Method getMethod(String id) {913 String cleanId = clean(id);914 return Arrays.stream(PseudoClasses.class.getDeclaredMethods())915 .filter(method -> clean(method.getName()).equalsIgnoreCase(cleanId))916 .findFirst().orElse(null);917 937 } 918 938 919 939 private static String clean(String id) { 920 940 // for backwards compatibility, consider :sameTags == :same-tags == :same_tags (#11150) 921 return id. replaceAll("[-_]", "");941 return id.toLowerCase(Locale.ROOT).replaceAll("[-_]", ""); 922 942 } 923 943 924 944 @Override 925 945 public boolean applies(Environment e) { 926 try { 927 return not ^ (Boolean) method.invoke(null, e); 928 } catch (ReflectiveOperationException ex) { 929 throw new JosmRuntimeException(ex); 930 } 946 return predicate.test(e); 931 947 } 932 948 933 949 @Override 934 950 public String toString() { 935 return (not ? "!" : "") + ':' + method.getName();951 return name; 936 952 } 937 953 } … … 941 957 */ 942 958 public static class OpenEndPseudoClassCondition extends PseudoClassCondition { 959 final boolean not; 943 960 /** 944 961 * Constructs a new {@code OpenEndPseudoClassCondition}. … … 946 963 */ 947 964 public OpenEndPseudoClassCondition(boolean not) { 948 super(null, not); 965 super("open_end", null); 966 this.not = not; 949 967 } 950 968 951 969 @Override 952 970 public boolean applies(Environment e) { 953 return true;971 return !not; 954 972 } 955 973 } -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionFactoryTest.java
r17275 r17762 13 13 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 14 14 import net.trajano.commons.testing.UtilityClassTestUtil; 15 16 import java.lang.reflect.Method; 15 17 16 18 /** … … 43 45 UtilityClassTestUtil.assertUtilityClassWellDefined(PseudoClasses.class); 44 46 } 47 48 /** 49 * Tests that all functions have been registered to {@link ConditionFactory.PseudoClassCondition#CONDITION_MAP} 50 */ 51 @Test 52 void testAllPseudoClassesRegistered() { 53 for (Method method : PseudoClasses.class.getDeclaredMethods()) { 54 String name = method.getName().replaceFirst("^_new$", "new"); 55 Context context = name.equals("sameTags") ? Context.LINK : Context.PRIMITIVE; 56 ConditionFactory.PseudoClassCondition.createPseudoClassCondition(name, false, context); 57 ConditionFactory.PseudoClassCondition.createPseudoClassCondition(name, true, context); 58 } 59 } 45 60 } -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.java
r17760 r17762 89 89 @Test 90 90 void testPseudoClassCondition() throws Exception { 91 Condition c0 = ((Selector.GeneralSelector) getParser("way:area-style").selector()).conds.get(0); 91 92 Condition c1 = ((Selector.GeneralSelector) getParser("way!:area-style").selector()).conds.get(0); 92 93 Condition c2 = ((Selector.GeneralSelector) getParser("way!:areaStyle").selector()).conds.get(0); 93 94 Condition c3 = ((Selector.GeneralSelector) getParser("way!:area_style").selector()).conds.get(0); 95 assertEquals(":areaStyle", c0.toString()); 94 96 assertEquals("!:areaStyle", c1.toString()); 95 97 assertEquals("!:areaStyle", c2.toString()); 96 98 assertEquals("!:areaStyle", c3.toString()); 99 Selector tagged = getParser("way:tagged").selector(); 100 Selector notTagged = getParser("way!:tagged").selector(); 101 assertFalse(tagged.matches((new Environment(OsmUtils.createPrimitive("way"))))); 102 assertTrue(tagged.matches((new Environment(OsmUtils.createPrimitive("way building=yes"))))); 103 assertTrue(notTagged.matches((new Environment(OsmUtils.createPrimitive("way"))))); 104 assertFalse(notTagged.matches((new Environment(OsmUtils.createPrimitive("way building=yes"))))); 97 105 } 98 106
Note:
See TracChangeset
for help on using the changeset viewer.