Changeset 10837 in josm
- Timestamp:
- 2016-08-18T03:39:22+02:00 (8 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/scripts/TagInfoExtract.groovy
r10769 r10837 32 32 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference 33 33 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource 34 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .SimpleKeyValueCondition34 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.SimpleKeyValueCondition 35 35 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector 36 36 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser -
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
r10729 r10837 48 48 import org.openstreetmap.josm.gui.mappaint.MultiCascade; 49 49 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; 50 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .ClassCondition;50 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ClassCondition; 51 51 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression; 52 52 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction; -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Condition.java
r10717 r10837 2 2 package org.openstreetmap.josm.gui.mappaint.mapcss; 3 3 4 import java.lang.reflect.InvocationTargetException;5 import java.lang.reflect.Method;6 import java.text.MessageFormat;7 import java.util.Arrays;8 import java.util.EnumSet;9 import java.util.Map;10 import java.util.Objects;11 import java.util.Set;12 import java.util.function.BiFunction;13 import java.util.function.IntFunction;14 import java.util.function.Predicate;15 import java.util.regex.Pattern;16 17 import org.openstreetmap.josm.Main;18 import org.openstreetmap.josm.actions.search.SearchCompiler.InDataSourceArea;19 import org.openstreetmap.josm.data.osm.Node;20 4 import org.openstreetmap.josm.data.osm.OsmPrimitive; 21 import org.openstreetmap.josm.data.osm.OsmUtils;22 import org.openstreetmap.josm.data.osm.Relation;23 5 import org.openstreetmap.josm.data.osm.Tag; 24 import org.openstreetmap.josm.data.osm.Way;25 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;26 import org.openstreetmap.josm.gui.mappaint.Cascade;27 import org.openstreetmap.josm.gui.mappaint.ElemStyles;28 6 import org.openstreetmap.josm.gui.mappaint.Environment; 29 import org.openstreetmap.josm.tools.CheckParameterUtil;30 import org.openstreetmap.josm.tools.Utils;31 7 32 8 /** … … 42 18 */ 43 19 boolean applies(Environment e); 44 45 /**46 * Create a new condition that checks the key and the value of the object.47 * @param k The key.48 * @param v The reference value49 * @param op The operation to use when comparing the value50 * @param context The type of context to use.51 * @param considerValAsKey whether to consider {@code v} as another key and compare the values of key {@code k} and key {@code v}.52 * @return The new condition.53 */54 static Condition createKeyValueCondition(String k, String v, Op op, Context context, boolean considerValAsKey) {55 switch (context) {56 case PRIMITIVE:57 if (KeyValueRegexpCondition.SUPPORTED_OPS.contains(op) && !considerValAsKey)58 return new KeyValueRegexpCondition(k, v, op, false);59 if (!considerValAsKey && op.equals(Op.EQ))60 return new SimpleKeyValueCondition(k, v);61 return new KeyValueCondition(k, v, op, considerValAsKey);62 case LINK:63 if (considerValAsKey)64 throw new MapCSSException("''considerValAsKey'' not supported in LINK context");65 if ("role".equalsIgnoreCase(k))66 return new RoleCondition(v, op);67 else if ("index".equalsIgnoreCase(k))68 return new IndexCondition(v, op);69 else70 throw new MapCSSException(71 MessageFormat.format("Expected key ''role'' or ''index'' in link context. Got ''{0}''.", k));72 73 default: throw new AssertionError();74 }75 }76 77 /**78 * Create a condition in which the key and the value need to match a given regexp79 * @param k The key regexp80 * @param v The value regexp81 * @param op The operation to use when comparing the key and the value.82 * @return The new condition.83 */84 static Condition createRegexpKeyRegexpValueCondition(String k, String v, Op op) {85 return new RegexpKeyValueRegexpCondition(k, v, op);86 }87 88 /**89 * Creates a condition that checks the given key.90 * @param k The key to test for91 * @param not <code>true</code> to invert the match92 * @param matchType The match type to check for.93 * @param context The context this rule is found in.94 * @return the new condition.95 */96 static Condition createKeyCondition(String k, boolean not, KeyMatchType matchType, Context context) {97 switch (context) {98 case PRIMITIVE:99 return new KeyCondition(k, not, matchType);100 case LINK:101 if (matchType != null)102 throw new MapCSSException("Question mark operator ''?'' and regexp match not supported in LINK context");103 if (not)104 return new RoleCondition(k, Op.NEQ);105 else106 return new RoleCondition(k, Op.EQ);107 108 default: throw new AssertionError();109 }110 }111 112 /**113 * Create a new pseudo class condition114 * @param id The id of the pseudo class115 * @param not <code>true</code> to invert the condition116 * @param context The context the class is found in.117 * @return The new condition118 */119 static PseudoClassCondition createPseudoClassCondition(String id, boolean not, Context context) {120 return PseudoClassCondition.createPseudoClassCondition(id, not, context);121 }122 123 /**124 * Create a new class condition125 * @param id The id of the class to match126 * @param not <code>true</code> to invert the condition127 * @param context Ignored128 * @return The new condition129 */130 static ClassCondition createClassCondition(String id, boolean not, Context context) {131 return new ClassCondition(id, not);132 }133 134 /**135 * Create a new condition that a expression needs to be fulfilled136 * @param e the expression to check137 * @param context Ignored138 * @return The new condition139 */140 static ExpressionCondition createExpressionCondition(Expression e, Context context) {141 return new ExpressionCondition(e);142 }143 144 /**145 * This is the operation that {@link KeyValueCondition} uses to match.146 */147 enum Op {148 /** The value equals the given reference. */149 EQ(Objects::equals),150 /** The value does not equal the reference. */151 NEQ(EQ),152 /** The value is greater than or equal to the given reference value (as float). */153 GREATER_OR_EQUAL(comparisonResult -> comparisonResult >= 0),154 /** The value is greater than the given reference value (as float). */155 GREATER(comparisonResult -> comparisonResult > 0),156 /** The value is less than or equal to the given reference value (as float). */157 LESS_OR_EQUAL(comparisonResult -> comparisonResult <= 0),158 /** The value is less than the given reference value (as float). */159 LESS(comparisonResult -> comparisonResult < 0),160 /** The reference is treated as regular expression and the value needs to match it. */161 REGEX((test, prototype) -> Pattern.compile(prototype).matcher(test).find()),162 /** The reference is treated as regular expression and the value needs to not match it. */163 NREGEX(REGEX),164 /** The reference is treated as a list separated by ';'. Spaces around the ; are ignored.165 * The value needs to be equal one of the list elements. */166 ONE_OF((test, prototype) -> Arrays.asList(test.split("\\s*;\\s*")).contains(prototype)),167 /** The value needs to begin with the reference string. */168 BEGINS_WITH(String::startsWith),169 /** The value needs to end with the reference string. */170 ENDS_WITH(String::endsWith),171 /** The value needs to contain the reference string. */172 CONTAINS(String::contains);173 174 static final Set<Op> NEGATED_OPS = EnumSet.of(NEQ, NREGEX);175 176 private final BiFunction<String, String, Boolean> function;177 178 private final boolean negated;179 180 /**181 * Create a new string operation.182 * @param func The function to apply during {@link #eval(String, String)}.183 */184 Op(BiFunction<String, String, Boolean> func) {185 this.function = func;186 negated = false;187 }188 189 /**190 * Create a new float operation that compares two float values191 * @param comparatorResult A function to mapt the result of the comparison192 */193 Op(IntFunction<Boolean> comparatorResult) {194 this.function = (test, prototype) -> {195 float testFloat;196 try {197 testFloat = Float.parseFloat(test);198 } catch (NumberFormatException e) {199 return false;200 }201 float prototypeFloat = Float.parseFloat(prototype);202 203 int res = Float.compare(testFloat, prototypeFloat);204 return comparatorResult.apply(res);205 };206 negated = false;207 }208 209 /**210 * Create a new Op by negating an other op.211 * @param negate inverse operation212 */213 Op(Op negate) {214 this.function = (a, b) -> !negate.function.apply(a, b);215 negated = true;216 }217 218 /**219 * Evaluates a value against a reference string.220 * @param testString The value. May be <code>null</code>221 * @param prototypeString The reference string-222 * @return <code>true</code> if and only if this operation matches for the given value/reference pair.223 */224 public boolean eval(String testString, String prototypeString) {225 if (testString == null)226 return negated;227 else228 return function.apply(testString, prototypeString);229 }230 }231 20 232 21 /** … … 246 35 247 36 /** 248 * Most common case of a KeyValueCondition, this is the basic key=value case.249 *250 * Extra class for performance reasons.251 */252 class SimpleKeyValueCondition implements Condition, ToTagConvertable {253 /**254 * The key to search for.255 */256 public final String k;257 /**258 * The value to search for.259 */260 public final String v;261 262 /**263 * Create a new SimpleKeyValueCondition.264 * @param k The key265 * @param v The value.266 */267 public SimpleKeyValueCondition(String k, String v) {268 this.k = k;269 this.v = v;270 }271 272 @Override273 public boolean applies(Environment e) {274 return v.equals(e.osm.get(k));275 }276 277 @Override278 public Tag asTag(OsmPrimitive primitive) {279 return new Tag(k, v);280 }281 282 @Override283 public String toString() {284 return '[' + k + '=' + v + ']';285 }286 287 }288 289 /**290 * <p>Represents a key/value condition which is either applied to a primitive.</p>291 *292 */293 class KeyValueCondition implements Condition, ToTagConvertable {294 /**295 * The key to search for.296 */297 public final String k;298 /**299 * The value to search for.300 */301 public final String v;302 /**303 * The key/value match operation.304 */305 public final Op op;306 /**307 * If this flag is set, {@link #v} is treated as a key and the value is the value set for that key.308 */309 public final boolean considerValAsKey;310 311 /**312 * <p>Creates a key/value-condition.</p>313 *314 * @param k the key315 * @param v the value316 * @param op the operation317 * @param considerValAsKey whether to consider {@code v} as another key and compare the values of key {@code k} and key {@code v}.318 */319 public KeyValueCondition(String k, String v, Op op, boolean considerValAsKey) {320 this.k = k;321 this.v = v;322 this.op = op;323 this.considerValAsKey = considerValAsKey;324 }325 326 @Override327 public boolean applies(Environment env) {328 return op.eval(env.osm.get(k), considerValAsKey ? env.osm.get(v) : v);329 }330 331 @Override332 public Tag asTag(OsmPrimitive primitive) {333 return new Tag(k, v);334 }335 336 @Override337 public String toString() {338 return '[' + k + '\'' + op + '\'' + v + ']';339 }340 }341 342 /**343 * This condition requires a fixed key to match a given regexp344 */345 class KeyValueRegexpCondition extends KeyValueCondition {346 protected static final Set<Op> SUPPORTED_OPS = EnumSet.of(Op.REGEX, Op.NREGEX);347 348 final Pattern pattern;349 350 public KeyValueRegexpCondition(String k, String v, Op op, boolean considerValAsKey) {351 super(k, v, op, considerValAsKey);352 CheckParameterUtil.ensureThat(!considerValAsKey, "considerValAsKey is not supported");353 CheckParameterUtil.ensureThat(SUPPORTED_OPS.contains(op), "Op must be REGEX or NREGEX");354 this.pattern = Pattern.compile(v);355 }356 357 protected boolean matches(Environment env) {358 final String value = env.osm.get(k);359 return value != null && pattern.matcher(value).find();360 }361 362 @Override363 public boolean applies(Environment env) {364 if (Op.REGEX.equals(op)) {365 return matches(env);366 } else if (Op.NREGEX.equals(op)) {367 return !matches(env);368 } else {369 throw new IllegalStateException();370 }371 }372 }373 374 /**375 * A condition that checks that a key with the matching pattern has a value with the matching pattern.376 */377 class RegexpKeyValueRegexpCondition extends KeyValueRegexpCondition {378 379 public final Pattern keyPattern;380 381 /**382 * Create a condition in which the key and the value need to match a given regexp383 * @param k The key regexp384 * @param v The value regexp385 * @param op The operation to use when comparing the key and the value.386 */387 public RegexpKeyValueRegexpCondition(String k, String v, Op op) {388 super(k, v, op, false);389 this.keyPattern = Pattern.compile(k);390 }391 392 @Override393 protected boolean matches(Environment env) {394 for (Map.Entry<String, String> kv: env.osm.getKeys().entrySet()) {395 if (keyPattern.matcher(kv.getKey()).find() && pattern.matcher(kv.getValue()).find()) {396 return true;397 }398 }399 return false;400 }401 }402 403 class RoleCondition implements Condition {404 public final String role;405 public final Op op;406 407 public RoleCondition(String role, Op op) {408 this.role = role;409 this.op = op;410 }411 412 @Override413 public boolean applies(Environment env) {414 String testRole = env.getRole();415 if (testRole == null) return false;416 return op.eval(testRole, role);417 }418 }419 420 class IndexCondition implements Condition {421 public final String index;422 public final Op op;423 424 public IndexCondition(String index, Op op) {425 this.index = index;426 this.op = op;427 }428 429 @Override430 public boolean applies(Environment env) {431 if (env.index == null) return false;432 if (index.startsWith("-")) {433 return env.count != null && op.eval(Integer.toString(env.index - env.count), index);434 } else {435 return op.eval(Integer.toString(env.index + 1), index);436 }437 }438 }439 440 /**441 * This defines how {@link KeyCondition} matches a given key.442 */443 enum KeyMatchType {444 /**445 * The key needs to be equal to the given label.446 */447 EQ,448 /**449 * The key needs to have a true value (yes, ...)450 * @see OsmUtils#isTrue(String)451 */452 TRUE,453 /**454 * The key needs to have a false value (no, ...)455 * @see OsmUtils#isFalse(String)456 */457 FALSE,458 /**459 * The key needs to match the given regular expression.460 */461 REGEX462 }463 464 /**465 * <p>KeyCondition represent one of the following conditions in either the link or the466 * primitive context:</p>467 * <pre>468 * ["a label"] PRIMITIVE: the primitive has a tag "a label"469 * LINK: the parent is a relation and it has at least one member with the role470 * "a label" referring to the child471 *472 * [!"a label"] PRIMITIVE: the primitive doesn't have a tag "a label"473 * LINK: the parent is a relation but doesn't have a member with the role474 * "a label" referring to the child475 *476 * ["a label"?] PRIMITIVE: the primitive has a tag "a label" whose value evaluates to a true-value477 * LINK: not supported478 *479 * ["a label"?!] PRIMITIVE: the primitive has a tag "a label" whose value evaluates to a false-value480 * LINK: not supported481 * </pre>482 */483 class KeyCondition implements Condition, ToTagConvertable {484 485 /**486 * The key name.487 */488 public final String label;489 /**490 * If we should negate the result of the match.491 */492 public final boolean negateResult;493 /**494 * Describes how to match the label against the key.495 * @see KeyMatchType496 */497 public final KeyMatchType matchType;498 /**499 * A predicate used to match a the regexp against the key. Only used if the match type is regexp.500 */501 public final Predicate<String> containsPattern;502 503 /**504 * Creates a new KeyCondition505 * @param label The key name (or regexp) to use.506 * @param negateResult If we should negate the result.,507 * @param matchType The match type.508 */509 public KeyCondition(String label, boolean negateResult, KeyMatchType matchType) {510 this.label = label;511 this.negateResult = negateResult;512 this.matchType = matchType == null ? KeyMatchType.EQ : matchType;513 this.containsPattern = KeyMatchType.REGEX.equals(matchType)514 ? Pattern.compile(label).asPredicate()515 : null;516 }517 518 @Override519 public boolean applies(Environment e) {520 switch(e.getContext()) {521 case PRIMITIVE:522 switch (matchType) {523 case TRUE:524 return e.osm.isKeyTrue(label) ^ negateResult;525 case FALSE:526 return e.osm.isKeyFalse(label) ^ negateResult;527 case REGEX:528 return e.osm.keySet().stream().anyMatch(containsPattern) ^ negateResult;529 default:530 return e.osm.hasKey(label) ^ negateResult;531 }532 case LINK:533 Utils.ensure(false, "Illegal state: KeyCondition not supported in LINK context");534 return false;535 default: throw new AssertionError();536 }537 }538 539 /**540 * Get the matched key and the corresponding value.541 * <p>542 * WARNING: This ignores {@link #negateResult}.543 * <p>544 * WARNING: For regexp, the regular expression is returned instead of a key if the match failed.545 * @param p The primitive to get the value from.546 * @return The tag.547 */548 @Override549 public Tag asTag(OsmPrimitive p) {550 String key = label;551 if (KeyMatchType.REGEX.equals(matchType)) {552 key = p.keySet().stream().filter(containsPattern).findAny().orElse(key);553 }554 return new Tag(key, p.get(key));555 }556 557 @Override558 public String toString() {559 return '[' + (negateResult ? "!" : "") + label + ']';560 }561 }562 563 class ClassCondition implements Condition {564 565 public final String id;566 public final boolean not;567 568 public ClassCondition(String id, boolean not) {569 this.id = id;570 this.not = not;571 }572 573 @Override574 public boolean applies(Environment env) {575 Cascade cascade = env.getCascade(env.layer);576 return cascade != null && (not ^ cascade.containsKey(id));577 }578 579 @Override580 public String toString() {581 return (not ? "!" : "") + '.' + id;582 }583 }584 585 /**586 * Like <a href="http://www.w3.org/TR/css3-selectors/#pseudo-classes">CSS pseudo classes</a>, MapCSS pseudo classes587 * are written in lower case with dashes between words.588 */589 final class PseudoClasses {590 591 private PseudoClasses() {592 // Hide default constructor for utilities classes593 }594 595 /**596 * {@code closed} tests whether the way is closed or the relation is a closed multipolygon597 * @param e MapCSS environment598 * @return {@code true} if the way is closed or the relation is a closed multipolygon599 */600 static boolean closed(Environment e) { // NO_UCD (unused code)601 if (e.osm instanceof Way && ((Way) e.osm).isClosed())602 return true;603 if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon())604 return true;605 return false;606 }607 608 /**609 * {@code :modified} tests whether the object has been modified.610 * @param e MapCSS environment611 * @return {@code true} if the object has been modified612 * @see OsmPrimitive#isModified()613 */614 static boolean modified(Environment e) { // NO_UCD (unused code)615 return e.osm.isModified() || e.osm.isNewOrUndeleted();616 }617 618 /**619 * {@code ;new} tests whether the object is new.620 * @param e MapCSS environment621 * @return {@code true} if the object is new622 * @see OsmPrimitive#isNew()623 */624 static boolean _new(Environment e) { // NO_UCD (unused code)625 return e.osm.isNew();626 }627 628 /**629 * {@code :connection} tests whether the object is a connection node.630 * @param e MapCSS environment631 * @return {@code true} if the object is a connection node632 * @see Node#isConnectionNode()633 */634 static boolean connection(Environment e) { // NO_UCD (unused code)635 return e.osm instanceof Node && e.osm.getDataSet() != null && ((Node) e.osm).isConnectionNode();636 }637 638 /**639 * {@code :tagged} tests whether the object is tagged.640 * @param e MapCSS environment641 * @return {@code true} if the object is tagged642 * @see OsmPrimitive#isTagged()643 */644 static boolean tagged(Environment e) { // NO_UCD (unused code)645 return e.osm.isTagged();646 }647 648 /**649 * {@code :same-tags} tests whether the object has the same tags as its child/parent.650 * @param e MapCSS environment651 * @return {@code true} if the object has the same tags as its child/parent652 * @see OsmPrimitive#hasSameInterestingTags(OsmPrimitive)653 */654 static boolean sameTags(Environment e) { // NO_UCD (unused code)655 return e.osm.hasSameInterestingTags(Utils.firstNonNull(e.child, e.parent));656 }657 658 /**659 * {@code :area-style} tests whether the object has an area style. This is useful for validators.660 * @param e MapCSS environment661 * @return {@code true} if the object has an area style662 * @see ElemStyles#hasAreaElemStyle(OsmPrimitive, boolean)663 */664 static boolean areaStyle(Environment e) { // NO_UCD (unused code)665 // only for validator666 return ElemStyles.hasAreaElemStyle(e.osm, false);667 }668 669 /**670 * {@code unconnected}: tests whether the object is a unconnected node.671 * @param e MapCSS environment672 * @return {@code true} if the object is a unconnected node673 */674 static boolean unconnected(Environment e) { // NO_UCD (unused code)675 return e.osm instanceof Node && OsmPrimitive.getFilteredList(e.osm.getReferrers(), Way.class).isEmpty();676 }677 678 /**679 * {@code righthandtraffic} checks if there is right-hand traffic at the current location.680 * @param e MapCSS environment681 * @return {@code true} if there is right-hand traffic at the current location682 * @see ExpressionFactory.Functions#is_right_hand_traffic(Environment)683 */684 static boolean righthandtraffic(Environment e) { // NO_UCD (unused code)685 return ExpressionFactory.Functions.is_right_hand_traffic(e);686 }687 688 /**689 * {@code clockwise} whether the way is closed and oriented clockwise,690 * or non-closed and the 1st, 2nd and last node are in clockwise order.691 * @param e MapCSS environment692 * @return {@code true} if the way clockwise693 * @see ExpressionFactory.Functions#is_clockwise(Environment)694 */695 static boolean clockwise(Environment e) { // NO_UCD (unused code)696 return ExpressionFactory.Functions.is_clockwise(e);697 }698 699 /**700 * {@code anticlockwise} whether the way is closed and oriented anticlockwise,701 * or non-closed and the 1st, 2nd and last node are in anticlockwise order.702 * @param e MapCSS environment703 * @return {@code true} if the way clockwise704 * @see ExpressionFactory.Functions#is_anticlockwise(Environment)705 */706 static boolean anticlockwise(Environment e) { // NO_UCD (unused code)707 return ExpressionFactory.Functions.is_anticlockwise(e);708 }709 710 /**711 * {@code unclosed-multipolygon} tests whether the object is an unclosed multipolygon.712 * @param e MapCSS environment713 * @return {@code true} if the object is an unclosed multipolygon714 */715 static boolean unclosed_multipolygon(Environment e) { // NO_UCD (unused code)716 return e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon() &&717 !e.osm.isIncomplete() && !((Relation) e.osm).hasIncompleteMembers() &&718 !MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) e.osm).getOpenEnds().isEmpty();719 }720 721 private static final Predicate<OsmPrimitive> IN_DOWNLOADED_AREA = new InDataSourceArea(false);722 723 /**724 * {@code in-downloaded-area} tests whether the object is within source area ("downloaded area").725 * @param e MapCSS environment726 * @return {@code true} if the object is within source area ("downloaded area")727 * @see InDataSourceArea728 */729 static boolean inDownloadedArea(Environment e) { // NO_UCD (unused code)730 return IN_DOWNLOADED_AREA.test(e.osm);731 }732 733 static boolean completely_downloaded(Environment e) { // NO_UCD (unused code)734 if (e.osm instanceof Relation) {735 return !((Relation) e.osm).hasIncompleteMembers();736 } else {737 return true;738 }739 }740 741 static boolean closed2(Environment e) { // NO_UCD (unused code)742 if (e.osm instanceof Way && ((Way) e.osm).isClosed())743 return true;744 if (e.osm instanceof Relation && ((Relation) e.osm).isMultipolygon())745 return MultipolygonCache.getInstance().get(Main.map.mapView, (Relation) e.osm).getOpenEnds().isEmpty();746 return false;747 }748 749 static boolean selected(Environment e) { // NO_UCD (unused code)750 Cascade c = e.mc.getCascade(e.layer);751 c.setDefaultSelectedHandling(false);752 return e.osm.isSelected();753 }754 }755 756 class PseudoClassCondition implements Condition {757 758 public final Method method;759 public final boolean not;760 761 protected PseudoClassCondition(Method method, boolean not) {762 this.method = method;763 this.not = not;764 }765 766 /**767 * Create a new pseudo class condition768 * @param id The id of the pseudo class769 * @param not <code>true</code> to invert the condition770 * @param context The context the class is found in.771 * @return The new condition772 */773 public static PseudoClassCondition createPseudoClassCondition(String id, boolean not, Context context) {774 CheckParameterUtil.ensureThat(!"sameTags".equals(id) || Context.LINK.equals(context), "sameTags only supported in LINK context");775 if ("open_end".equals(id)) {776 return new OpenEndPseudoClassCondition(not);777 }778 final Method method = getMethod(id);779 if (method != null) {780 return new PseudoClassCondition(method, not);781 }782 throw new MapCSSException("Invalid pseudo class specified: " + id);783 }784 785 protected static Method getMethod(String id) {786 id = id.replaceAll("-|_", "");787 for (Method method : PseudoClasses.class.getDeclaredMethods()) {788 // for backwards compatibility, consider :sameTags == :same-tags == :same_tags (#11150)789 final String methodName = method.getName().replaceAll("-|_", "");790 if (methodName.equalsIgnoreCase(id)) {791 return method;792 }793 }794 return null;795 }796 797 @Override798 public boolean applies(Environment e) {799 try {800 return not ^ (Boolean) method.invoke(null, e);801 } catch (IllegalAccessException | InvocationTargetException ex) {802 throw new RuntimeException(ex);803 }804 }805 806 @Override807 public String toString() {808 return (not ? "!" : "") + ':' + method.getName();809 }810 }811 812 class OpenEndPseudoClassCondition extends PseudoClassCondition {813 public OpenEndPseudoClassCondition(boolean not) {814 super(null, not);815 }816 817 @Override818 public boolean applies(Environment e) {819 return true;820 }821 }822 823 /**824 * A condition that is fulfilled whenever the expression is evaluated to be true.825 */826 class ExpressionCondition implements Condition {827 828 private final Expression e;829 830 /**831 * Constructs a new {@code ExpressionFactory}832 * @param e expression833 */834 public ExpressionCondition(Expression e) {835 this.e = e;836 }837 838 @Override839 public boolean applies(Environment env) {840 Boolean b = Cascade.convertTo(e.evaluate(env), Boolean.class);841 return b != null && b;842 }843 844 @Override845 public String toString() {846 return '[' + e.toString() + ']';847 }848 }849 850 /**851 37 * This is a condition that can be converted to a tag 852 38 * @author Michael Zangl 853 39 * @since 10674 854 40 */ 41 @FunctionalInterface 855 42 public interface ToTagConvertable { 856 43 /** -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
r10748 r10837 43 43 44 44 /** 45 * Factory to generate Expressions.46 * 45 * Factory to generate {@link Expression}s. 46 * <p> 47 47 * See {@link #createFunctionExpression}. 48 48 */ -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
r9958 r10837 22 22 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition; 23 23 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context; 24 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory; 25 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyMatchType; 26 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op; 24 27 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression; 25 28 import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory; … … 744 747 c=simple_key_value_condition(context) s() <RSQUARE> { return c; } 745 748 | 746 e=expression() <RSQUARE> { return Condition .createExpressionCondition(e, context); }749 e=expression() <RSQUARE> { return ConditionFactory.createExpressionCondition(e, context); } 747 750 ) 748 751 } … … 762 765 { 763 766 boolean not = false; 764 Condition.KeyMatchType matchType = null;;767 KeyMatchType matchType = null;; 765 768 String key; 766 769 } … … 768 771 ( <EXCLAMATION> { not = true; } )? 769 772 ( 770 { matchType = Condition.KeyMatchType.REGEX; } key = regex()773 { matchType = KeyMatchType.REGEX; } key = regex() 771 774 | 772 775 key = tag_key() 773 776 ) 774 ( LOOKAHEAD(2) <QUESTION> <EXCLAMATION> { matchType = Condition.KeyMatchType.FALSE; } )?775 ( <QUESTION> { matchType = Condition.KeyMatchType.TRUE; } )?776 { return Condition .createKeyCondition(key, not, matchType, context); }777 ( LOOKAHEAD(2) <QUESTION> <EXCLAMATION> { matchType = KeyMatchType.FALSE; } )? 778 ( <QUESTION> { matchType = KeyMatchType.TRUE; } )? 779 { return ConditionFactory.createKeyCondition(key, not, matchType, context); } 777 780 } 778 781 … … 783 786 float f; 784 787 int i; 785 Condition.KeyMatchType matchType = null;;786 Condition.Op op;788 KeyMatchType matchType = null;; 789 Op op; 787 790 boolean considerValAsKey = false; 788 791 } 789 792 { 790 793 ( 791 key = regex() s() { matchType = Condition.KeyMatchType.REGEX; }794 key = regex() s() { matchType = KeyMatchType.REGEX; } 792 795 | 793 796 key=tag_key() s() … … 796 799 LOOKAHEAD(3) 797 800 ( 798 <EQUAL> <TILDE> { op= Condition.Op.REGEX; }801 <EQUAL> <TILDE> { op=Op.REGEX; } 799 802 | 800 <EXCLAMATION> <TILDE> { op= Condition.Op.NREGEX; }803 <EXCLAMATION> <TILDE> { op=Op.NREGEX; } 801 804 ) 802 805 s() … … 805 808 | 806 809 ( 807 <EXCLAMATION> <EQUAL> { op= Condition.Op.NEQ; }810 <EXCLAMATION> <EQUAL> { op=Op.NEQ; } 808 811 | 809 <EQUAL> { op= Condition.Op.EQ; }812 <EQUAL> { op=Op.EQ; } 810 813 | 811 <TILDE> <EQUAL> { op= Condition.Op.ONE_OF; }814 <TILDE> <EQUAL> { op=Op.ONE_OF; } 812 815 | 813 <CARET> <EQUAL> { op= Condition.Op.BEGINS_WITH; }816 <CARET> <EQUAL> { op=Op.BEGINS_WITH; } 814 817 | 815 <DOLLAR> <EQUAL> { op= Condition.Op.ENDS_WITH; }818 <DOLLAR> <EQUAL> { op=Op.ENDS_WITH; } 816 819 | 817 <STAR> <EQUAL> { op= Condition.Op.CONTAINS; }820 <STAR> <EQUAL> { op=Op.CONTAINS; } 818 821 ) 819 822 s() … … 829 832 | 830 833 ( 831 <GREATER_EQUAL> { op= Condition.Op.GREATER_OR_EQUAL; }834 <GREATER_EQUAL> { op=Op.GREATER_OR_EQUAL; } 832 835 | 833 <GREATER> { op= Condition.Op.GREATER; }836 <GREATER> { op=Op.GREATER; } 834 837 | 835 <LESS_EQUAL> { op= Condition.Op.LESS_OR_EQUAL; }838 <LESS_EQUAL> { op=Op.LESS_OR_EQUAL; } 836 839 | 837 <LESS> { op= Condition.Op.LESS; }840 <LESS> { op=Op.LESS; } 838 841 ) 839 842 s() 840 843 f=float_() { val=Float.toString(f); } 841 844 ) 842 { return Condition.KeyMatchType.REGEX == matchType843 ? Condition .createRegexpKeyRegexpValueCondition(key, val, op)844 : Condition .createKeyValueCondition(key, val, op, context, considerValAsKey); }845 { return KeyMatchType.REGEX == matchType 846 ? ConditionFactory.createRegexpKeyRegexpValueCondition(key, val, op) 847 : ConditionFactory.createKeyValueCondition(key, val, op, context, considerValAsKey); } 845 848 } 846 849 … … 860 863 s=ident() 861 864 { return pseudo 862 ? Condition .createPseudoClassCondition(s, not, context)863 : Condition .createClassCondition(s, not, context); }865 ? ConditionFactory.createPseudoClassCondition(s, not, context) 866 : ConditionFactory.createClassCondition(s, not, context); } 864 867 } 865 868 -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
r10268 r10837 45 45 import org.openstreetmap.josm.gui.mappaint.StyleSetting.BooleanStyleSetting; 46 46 import org.openstreetmap.josm.gui.mappaint.StyleSource; 47 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .KeyCondition;48 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .KeyMatchType;49 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .KeyValueCondition;50 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .Op;51 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .SimpleKeyValueCondition;47 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyCondition; 48 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyMatchType; 49 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyValueCondition; 50 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op; 51 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.SimpleKeyValueCondition; 52 52 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; 53 53 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.GeneralSelector; -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r10715 r10837 21 21 import org.openstreetmap.josm.gui.mappaint.Environment; 22 22 import org.openstreetmap.josm.gui.mappaint.Range; 23 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.OpenEndPseudoClassCondition; 23 24 import org.openstreetmap.josm.tools.CheckParameterUtil; 24 25 import org.openstreetmap.josm.tools.Geometry; … … 377 378 } else if (ChildOrParentSelectorType.CHILD.equals(type) 378 379 && link.conds != null && !link.conds.isEmpty() 379 && link.conds.get(0) instanceof Condition.OpenEndPseudoClassCondition) {380 && link.conds.get(0) instanceof OpenEndPseudoClassCondition) { 380 381 if (e.osm instanceof Node) { 381 382 e.osm.visitReferrers(new MultipolygonOpenEndFinder(e)); -
trunk/test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSConditionPerformanceTest.java
r10674 r10837 6 6 import org.junit.Test; 7 7 import org.openstreetmap.josm.PerformanceTestUtils; 8 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .Op;8 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op; 9 9 10 10 /** -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/ConditionTest.java
r10674 r10837 13 13 import org.openstreetmap.josm.gui.mappaint.Environment; 14 14 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context; 15 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Op;16 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.SimpleKeyValueCondition;17 15 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.ToTagConvertable; 16 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op; 17 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.SimpleKeyValueCondition; 18 18 import org.openstreetmap.josm.testutils.JOSMTestRules; 19 19 … … 54 54 @Test 55 55 public void testKeyValueEq() { 56 Condition op = Condition .createKeyValueCondition("k1", "v1", Op.EQ, Context.PRIMITIVE, false);56 Condition op = ConditionFactory.createKeyValueCondition("k1", "v1", Op.EQ, Context.PRIMITIVE, false); 57 57 assertFalse(op.applies(genEnv(node0))); 58 58 assertTrue(op.applies(genEnv(node1))); … … 72 72 @Test 73 73 public void testKeyValueEqAsKey() { 74 Condition op = Condition .createKeyValueCondition("k1", "k2", Op.EQ, Context.PRIMITIVE, true);74 Condition op = ConditionFactory.createKeyValueCondition("k1", "k2", Op.EQ, Context.PRIMITIVE, true); 75 75 assertFalse(op.applies(genEnv(node0))); 76 76 assertTrue(op.applies(genEnv(node1))); … … 88 88 @Test 89 89 public void testKeyValueNeq() { 90 Condition op = Condition .createKeyValueCondition("k1", "v1", Op.NEQ, Context.PRIMITIVE, false);90 Condition op = ConditionFactory.createKeyValueCondition("k1", "v1", Op.NEQ, Context.PRIMITIVE, false); 91 91 assertTrue(op.applies(genEnv(node0))); 92 92 assertFalse(op.applies(genEnv(node1))); … … 101 101 @Test 102 102 public void testKeyValueGreatherEq() { 103 Condition op = Condition .createKeyValueCondition("f1", "0.2", Op.GREATER_OR_EQUAL, Context.PRIMITIVE, false);103 Condition op = ConditionFactory.createKeyValueCondition("f1", "0.2", Op.GREATER_OR_EQUAL, Context.PRIMITIVE, false); 104 104 assertFalse(op.applies(genEnv(node0))); 105 105 assertTrue(op.applies(genEnv(node1))); … … 114 114 @Test 115 115 public void testKeyValueGreather() { 116 Condition op = Condition .createKeyValueCondition("f1", "0.2", Op.GREATER, Context.PRIMITIVE, false);116 Condition op = ConditionFactory.createKeyValueCondition("f1", "0.2", Op.GREATER, Context.PRIMITIVE, false); 117 117 assertFalse(op.applies(genEnv(node0))); 118 118 assertFalse(op.applies(genEnv(node1))); … … 127 127 @Test 128 128 public void testKeyValueLessEq() { 129 Condition op = Condition .createKeyValueCondition("f1", "0.2", Op.LESS_OR_EQUAL, Context.PRIMITIVE, false);129 Condition op = ConditionFactory.createKeyValueCondition("f1", "0.2", Op.LESS_OR_EQUAL, Context.PRIMITIVE, false); 130 130 assertFalse(op.applies(genEnv(node0))); 131 131 assertTrue(op.applies(genEnv(node1))); … … 140 140 @Test 141 141 public void testKeyValueLess() { 142 Condition op = Condition .createKeyValueCondition("f1", "0.2", Op.LESS, Context.PRIMITIVE, false);142 Condition op = ConditionFactory.createKeyValueCondition("f1", "0.2", Op.LESS, Context.PRIMITIVE, false); 143 143 assertFalse(op.applies(genEnv(node0))); 144 144 assertFalse(op.applies(genEnv(node1))); … … 153 153 @Test 154 154 public void testKeyValueRegex() { 155 Condition op = Condition .createKeyValueCondition("r1", "(ab){2}", Op.REGEX, Context.PRIMITIVE, false);155 Condition op = ConditionFactory.createKeyValueCondition("r1", "(ab){2}", Op.REGEX, Context.PRIMITIVE, false); 156 156 assertFalse(op.applies(genEnv(node0))); 157 157 assertTrue(op.applies(genEnv(node1))); … … 166 166 @Test 167 167 public void testKeyValueNregex() { 168 Condition op = Condition .createKeyValueCondition("r1", "(ab){2}", Op.NREGEX, Context.PRIMITIVE, false);168 Condition op = ConditionFactory.createKeyValueCondition("r1", "(ab){2}", Op.NREGEX, Context.PRIMITIVE, false); 169 169 assertTrue(op.applies(genEnv(node0))); 170 170 assertFalse(op.applies(genEnv(node1))); … … 179 179 @Test 180 180 public void testKeyValueOneOf() { 181 Condition op = Condition .createKeyValueCondition("one", "a", Op.ONE_OF, Context.PRIMITIVE, false);181 Condition op = ConditionFactory.createKeyValueCondition("one", "a", Op.ONE_OF, Context.PRIMITIVE, false); 182 182 assertFalse(op.applies(genEnv(node0))); 183 183 assertTrue(op.applies(genEnv(node1))); … … 192 192 @Test 193 193 public void testKeyValueBeginsWith() { 194 Condition op = Condition .createKeyValueCondition("c1", "xy", Op.BEGINS_WITH, Context.PRIMITIVE, false);194 Condition op = ConditionFactory.createKeyValueCondition("c1", "xy", Op.BEGINS_WITH, Context.PRIMITIVE, false); 195 195 assertFalse(op.applies(genEnv(node0))); 196 196 assertTrue(op.applies(genEnv(node1))); … … 205 205 @Test 206 206 public void testKeyValueEndsWith() { 207 Condition op = Condition .createKeyValueCondition("c1", "xy", Op.ENDS_WITH, Context.PRIMITIVE, false);207 Condition op = ConditionFactory.createKeyValueCondition("c1", "xy", Op.ENDS_WITH, Context.PRIMITIVE, false); 208 208 assertFalse(op.applies(genEnv(node0))); 209 209 assertFalse(op.applies(genEnv(node1))); … … 218 218 @Test 219 219 public void testKeyValueContains() { 220 Condition op = Condition .createKeyValueCondition("c1", "xy", Op.CONTAINS, Context.PRIMITIVE, false);221 assertFalse(op.applies(genEnv(node0))); 222 assertTrue(op.applies(genEnv(node1))); 223 assertTrue(op.applies(genEnv(node2))); 224 assertTrue(op.applies(genEnv(node3))); 225 assertTrue(op.applies(genEnv(node4))); 226 } 227 228 /** 229 * Test of {@link Condition #createRegexpKeyRegexpValueCondition(String, String, Op)}220 Condition op = ConditionFactory.createKeyValueCondition("c1", "xy", Op.CONTAINS, Context.PRIMITIVE, false); 221 assertFalse(op.applies(genEnv(node0))); 222 assertTrue(op.applies(genEnv(node1))); 223 assertTrue(op.applies(genEnv(node2))); 224 assertTrue(op.applies(genEnv(node3))); 225 assertTrue(op.applies(genEnv(node4))); 226 } 227 228 /** 229 * Test of {@link ConditionFactory#createRegexpKeyRegexpValueCondition(String, String, Op)} 230 230 */ 231 231 @Test 232 232 public void testRegexpKeyValueRegexpCondition() { 233 Condition op = Condition .createRegexpKeyRegexpValueCondition("^k", "\\da", Op.REGEX);234 assertFalse(op.applies(genEnv(node0))); 235 assertFalse(op.applies(genEnv(node1))); 236 assertTrue(op.applies(genEnv(node2))); 237 assertFalse(op.applies(genEnv(node3))); 238 assertTrue(op.applies(genEnv(node4))); 239 240 Condition notOp = Condition .createRegexpKeyRegexpValueCondition("^k", "\\da", Op.NREGEX);233 Condition op = ConditionFactory.createRegexpKeyRegexpValueCondition("^k", "\\da", Op.REGEX); 234 assertFalse(op.applies(genEnv(node0))); 235 assertFalse(op.applies(genEnv(node1))); 236 assertTrue(op.applies(genEnv(node2))); 237 assertFalse(op.applies(genEnv(node3))); 238 assertTrue(op.applies(genEnv(node4))); 239 240 Condition notOp = ConditionFactory.createRegexpKeyRegexpValueCondition("^k", "\\da", Op.NREGEX); 241 241 assertTrue(notOp.applies(genEnv(node0))); 242 242 assertTrue(notOp.applies(genEnv(node1))); -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/KeyConditionTest.groovy
r9214 r10837 13 13 import org.openstreetmap.josm.gui.mappaint.Environment 14 14 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context 15 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyMatchType 15 16 16 17 class KeyConditionTest { … … 47 48 48 49 // ["a label"] 49 Condition c = Condition .createKeyCondition("a key", false, Condition.KeyMatchType.FALSE, Context.PRIMITIVE)50 Condition c = ConditionFactory.createKeyCondition("a key", false, KeyMatchType.FALSE, Context.PRIMITIVE) 50 51 // ["a label"?] 51 c = Condition .createKeyCondition("a key", false, Condition.KeyMatchType.TRUE, Context.PRIMITIVE)52 c = ConditionFactory.createKeyCondition("a key", false, KeyMatchType.TRUE, Context.PRIMITIVE) 52 53 // [!"a label"] 53 c = Condition .createKeyCondition("a key", true, Condition.KeyMatchType.FALSE, Context.PRIMITIVE)54 c = ConditionFactory.createKeyCondition("a key", true, KeyMatchType.FALSE, Context.PRIMITIVE) 54 55 // [!"a label"?] 55 c = Condition .createKeyCondition("a key", true, Condition.KeyMatchType.TRUE, Context.PRIMITIVE)56 c = ConditionFactory.createKeyCondition("a key", true, KeyMatchType.TRUE, Context.PRIMITIVE) 56 57 57 58 // ["a label"] 58 c = Condition .createKeyCondition("a key", false, null, Context.LINK)59 c = ConditionFactory.createKeyCondition("a key", false, null, Context.LINK) 59 60 // [!"a label"] 60 c = Condition .createKeyCondition("a key", true, null, Context.LINK)61 c = ConditionFactory.createKeyCondition("a key", true, null, Context.LINK) 61 62 62 63 shouldFail(MapCSSException) { 63 64 // ["a label"?] 64 c = Condition .createKeyCondition("a key", false, Condition.KeyMatchType.TRUE, Context.LINK)65 c = ConditionFactory.createKeyCondition("a key", false, KeyMatchType.TRUE, Context.LINK) 65 66 } 66 67 67 68 shouldFail(MapCSSException) { 68 69 // [!"a label"?] 69 c = Condition .createKeyCondition("a key", true, Condition.KeyMatchType.TRUE, Context.LINK)70 c = ConditionFactory.createKeyCondition("a key", true, KeyMatchType.TRUE, Context.LINK) 70 71 } 71 72 } … … 79 80 Environment e = new Environment(n).withParent(r).withIndex(0, r.membersCount).withLinkContext() 80 81 81 Condition cond = Condition .createKeyCondition("my_role", false, null, Context.LINK)82 Condition cond = ConditionFactory.createKeyCondition("my_role", false, null, Context.LINK) 82 83 assert cond.applies(e) 83 84 84 cond = Condition .createKeyCondition("my_role", true, null, Context.LINK)85 cond = ConditionFactory.createKeyCondition("my_role", true, null, Context.LINK) 85 86 assert !cond.applies(e) 86 87 } … … 94 95 Environment e = new Environment(n).withParent(r).withIndex(0, r.membersCount).withLinkContext() 95 96 96 Condition cond = Condition .createKeyCondition("another_role", false, null, Context.LINK)97 Condition cond = ConditionFactory.createKeyCondition("another_role", false, null, Context.LINK) 97 98 assert !cond.applies(e) 98 99 99 cond = Condition .createKeyCondition("another_role", true, null, Context.LINK)100 cond = ConditionFactory.createKeyCondition("another_role", true, null, Context.LINK) 100 101 assert cond.applies(e) 101 102 } -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/KeyValueConditionTest.groovy
r9247 r10837 12 12 import org.openstreetmap.josm.gui.mappaint.Environment 13 13 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition.Context 14 import org.openstreetmap.josm.gui.mappaint.mapcss.Condition .Op14 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op 15 15 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser 16 16 … … 47 47 @Test 48 48 public void create() { 49 Condition c = Condition .createKeyValueCondition("a key", "a value", Op.EQ, Context.PRIMITIVE, false)49 Condition c = ConditionFactory.createKeyValueCondition("a key", "a value", Op.EQ, Context.PRIMITIVE, false) 50 50 51 c = Condition .createKeyValueCondition("role", "a role", Op.EQ, Context.LINK, false)52 c = Condition .createKeyValueCondition("RoLe", "a role", Op.EQ, Context.LINK, false)51 c = ConditionFactory.createKeyValueCondition("role", "a role", Op.EQ, Context.LINK, false) 52 c = ConditionFactory.createKeyValueCondition("RoLe", "a role", Op.EQ, Context.LINK, false) 53 53 54 54 shouldFail(MapCSSException) { 55 c = Condition .createKeyValueCondition("an arbitry tag", "a role", Op.EQ, Context.LINK, false)55 c = ConditionFactory.createKeyValueCondition("an arbitry tag", "a role", Op.EQ, Context.LINK, false) 56 56 } 57 57 } … … 65 65 Environment e = new Environment(n).withParent(r).withLinkContext().withIndex(0, r.membersCount) 66 66 67 Condition cond = new Condition .RoleCondition("my_role", Op.EQ)67 Condition cond = new ConditionFactory.RoleCondition("my_role", Op.EQ) 68 68 assert cond.applies(e) 69 69 70 cond = new Condition .RoleCondition("another_role", Op.EQ)70 cond = new ConditionFactory.RoleCondition("another_role", Op.EQ) 71 71 assert !cond.applies(e) 72 72 } … … 80 80 Environment e = new Environment(n).withParent(r).withIndex(0, r.membersCount).withLinkContext() 81 81 82 Condition cond = Condition .createKeyValueCondition("role", "my_role", Op.NEQ, Context.LINK, false)82 Condition cond = ConditionFactory.createKeyValueCondition("role", "my_role", Op.NEQ, Context.LINK, false) 83 83 assert !cond.applies(e) 84 84 85 cond = Condition .createKeyValueCondition("role", "another_role", Op.NEQ, Context.LINK, false)85 cond = ConditionFactory.createKeyValueCondition("role", "another_role", Op.NEQ, Context.LINK, false) 86 86 assert cond.applies(e) 87 87 } -
trunk/test/unit/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParserTest.groovy
r10193 r10837 14 14 import org.openstreetmap.josm.gui.mappaint.Environment 15 15 import org.openstreetmap.josm.gui.mappaint.MultiCascade 16 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.ClassCondition 17 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyCondition 18 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyMatchType 19 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.KeyValueCondition 20 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.Op 21 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.PseudoClassCondition 22 import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory.SimpleKeyValueCondition 16 23 import org.openstreetmap.josm.gui.mappaint.mapcss.parsergen.MapCSSParser 17 24 import org.openstreetmap.josm.tools.ColorHelper … … 50 57 public void testClassCondition() throws Exception { 51 58 def conditions = ((Selector.GeneralSelector) getParser("way[name=X].highway:closed").selector()).conds 52 assert conditions.get(0) instanceof Condition.SimpleKeyValueCondition59 assert conditions.get(0) instanceof SimpleKeyValueCondition 53 60 assert conditions.get(0).applies(getEnvironment("name", "X")) 54 assert conditions.get(1) instanceof C ondition.ClassCondition55 assert conditions.get(2) instanceof Condition.PseudoClassCondition61 assert conditions.get(1) instanceof ClassCondition 62 assert conditions.get(2) instanceof PseudoClassCondition 56 63 assert !conditions.get(2).applies(getEnvironment("name", "X")) 57 64 } … … 93 100 @Test 94 101 public void testEqualCondition() throws Exception { 95 def condition = ( Condition.SimpleKeyValueCondition) getParser("[surface=paved]").condition(Condition.Context.PRIMITIVE)96 assert condition instanceof Condition.SimpleKeyValueCondition102 def condition = (SimpleKeyValueCondition) getParser("[surface=paved]").condition(Condition.Context.PRIMITIVE) 103 assert condition instanceof SimpleKeyValueCondition 97 104 assert "surface".equals(condition.k) 98 105 assert "paved".equals(condition.v) … … 103 110 @Test 104 111 public void testNotEqualCondition() throws Exception { 105 def condition = ( Condition.KeyValueCondition) getParser("[surface!=paved]").condition(Condition.Context.PRIMITIVE)106 assert Condition.Op.NEQ.equals(condition.op)112 def condition = (KeyValueCondition) getParser("[surface!=paved]").condition(Condition.Context.PRIMITIVE) 113 assert Op.NEQ.equals(condition.op) 107 114 assert !condition.applies(getEnvironment("surface", "paved")) 108 115 assert condition.applies(getEnvironment("surface", "unpaved")) … … 111 118 @Test 112 119 public void testRegexCondition() throws Exception { 113 def condition = ( Condition.KeyValueCondition) getParser("[surface=~/paved|unpaved/]").condition(Condition.Context.PRIMITIVE)114 assert Condition.Op.REGEX.equals(condition.op)120 def condition = (KeyValueCondition) getParser("[surface=~/paved|unpaved/]").condition(Condition.Context.PRIMITIVE) 121 assert Op.REGEX.equals(condition.op) 115 122 assert condition.applies(getEnvironment("surface", "unpaved")) 116 123 assert !condition.applies(getEnvironment("surface", "grass")) … … 119 126 @Test 120 127 public void testRegexConditionParenthesis() throws Exception { 121 def condition = ( Condition.KeyValueCondition) getParser("[name =~ /^\\(foo\\)/]").condition(Condition.Context.PRIMITIVE)128 def condition = (KeyValueCondition) getParser("[name =~ /^\\(foo\\)/]").condition(Condition.Context.PRIMITIVE) 122 129 assert condition.applies(getEnvironment("name", "(foo)")) 123 130 assert !condition.applies(getEnvironment("name", "foo")) … … 127 134 @Test 128 135 public void testNegatedRegexCondition() throws Exception { 129 def condition = ( Condition.KeyValueCondition) getParser("[surface!~/paved|unpaved/]").condition(Condition.Context.PRIMITIVE)130 assert Condition.Op.NREGEX.equals(condition.op)136 def condition = (KeyValueCondition) getParser("[surface!~/paved|unpaved/]").condition(Condition.Context.PRIMITIVE) 137 assert Op.NREGEX.equals(condition.op) 131 138 assert !condition.applies(getEnvironment("surface", "unpaved")) 132 139 assert condition.applies(getEnvironment("surface", "grass")) … … 135 142 @Test 136 143 public void testBeginsEndsWithCondition() throws Exception { 137 def condition = ( Condition.KeyValueCondition) getParser('[foo ^= bar]').condition(Condition.Context.PRIMITIVE)138 assert Condition.Op.BEGINS_WITH.equals(condition.op)144 def condition = (KeyValueCondition) getParser('[foo ^= bar]').condition(Condition.Context.PRIMITIVE) 145 assert Op.BEGINS_WITH.equals(condition.op) 139 146 assert condition.applies(getEnvironment("foo", "bar123")) 140 147 assert !condition.applies(getEnvironment("foo", "123bar")) 141 148 assert !condition.applies(getEnvironment("foo", "123bar123")) 142 condition = ( Condition.KeyValueCondition) getParser('[foo $= bar]').condition(Condition.Context.PRIMITIVE)143 assert Condition.Op.ENDS_WITH.equals(condition.op)149 condition = (KeyValueCondition) getParser('[foo $= bar]').condition(Condition.Context.PRIMITIVE) 150 assert Op.ENDS_WITH.equals(condition.op) 144 151 assert !condition.applies(getEnvironment("foo", "bar123")) 145 152 assert condition.applies(getEnvironment("foo", "123bar")) … … 158 165 @Test 159 166 public void testStandardKeyCondition() throws Exception { 160 def c1 = ( Condition.KeyCondition) getParser("[ highway ]").condition(Condition.Context.PRIMITIVE)161 assert Condition.KeyMatchType.EQ.equals(c1.matchType)167 def c1 = (KeyCondition) getParser("[ highway ]").condition(Condition.Context.PRIMITIVE) 168 assert KeyMatchType.EQ.equals(c1.matchType) 162 169 assert c1.applies(getEnvironment("highway", "unclassified")) 163 170 assert !c1.applies(getEnvironment("railway", "rail")) 164 def c2 = ( Condition.KeyCondition) getParser("[\"/slash/\"]").condition(Condition.Context.PRIMITIVE)165 assert Condition.KeyMatchType.EQ.equals(c2.matchType)171 def c2 = (KeyCondition) getParser("[\"/slash/\"]").condition(Condition.Context.PRIMITIVE) 172 assert KeyMatchType.EQ.equals(c2.matchType) 166 173 assert c2.applies(getEnvironment("/slash/", "yes")) 167 174 assert !c2.applies(getEnvironment("\"slash\"", "no")) … … 170 177 @Test 171 178 public void testYesNoKeyCondition() throws Exception { 172 def c1 = ( Condition.KeyCondition) getParser("[oneway?]").condition(Condition.Context.PRIMITIVE)173 def c2 = ( Condition.KeyCondition) getParser("[oneway?!]").condition(Condition.Context.PRIMITIVE)174 def c3 = ( Condition.KeyCondition) getParser("[!oneway?]").condition(Condition.Context.PRIMITIVE)175 def c4 = ( Condition.KeyCondition) getParser("[!oneway?!]").condition(Condition.Context.PRIMITIVE)179 def c1 = (KeyCondition) getParser("[oneway?]").condition(Condition.Context.PRIMITIVE) 180 def c2 = (KeyCondition) getParser("[oneway?!]").condition(Condition.Context.PRIMITIVE) 181 def c3 = (KeyCondition) getParser("[!oneway?]").condition(Condition.Context.PRIMITIVE) 182 def c4 = (KeyCondition) getParser("[!oneway?!]").condition(Condition.Context.PRIMITIVE) 176 183 def yes = getEnvironment("oneway", "yes") 177 184 def no = getEnvironment("oneway", "no") … … 193 200 @Test 194 201 public void testRegexKeyCondition() throws Exception { 195 def c1 = ( Condition.KeyCondition) getParser("[/.*:(backward|forward)\$/]").condition(Condition.Context.PRIMITIVE)196 assert Condition.KeyMatchType.REGEX.equals(c1.matchType)202 def c1 = (KeyCondition) getParser("[/.*:(backward|forward)\$/]").condition(Condition.Context.PRIMITIVE) 203 assert KeyMatchType.REGEX.equals(c1.matchType) 197 204 assert !c1.applies(getEnvironment("lanes", "3")) 198 205 assert c1.applies(getEnvironment("lanes:forward", "3")) … … 214 221 @Test 215 222 public void testKeyKeyCondition() throws Exception { 216 def c1 = ( Condition.KeyValueCondition) getParser("[foo = *bar]").condition(Condition.Context.PRIMITIVE)223 def c1 = (KeyValueCondition) getParser("[foo = *bar]").condition(Condition.Context.PRIMITIVE) 217 224 def w1 = new Way() 218 225 w1.put("foo", "123") … … 221 228 w1.put("bar", "123") 222 229 assert c1.applies(new Environment(w1)) 223 def c2 = ( Condition.KeyValueCondition) getParser("[foo =~ */bar/]").condition(Condition.Context.PRIMITIVE)230 def c2 = (KeyValueCondition) getParser("[foo =~ */bar/]").condition(Condition.Context.PRIMITIVE) 224 231 def w2 = new Way(w1) 225 232 w2.put("bar", "[0-9]{3}")
Note:
See TracChangeset
for help on using the changeset viewer.