@Nullable @Override public Boolean visit(LikeCondition condition, @Nullable String context) { return context != null && condition.matches(context); } }
@Override public Boolean visit(LikeCondition right, Void context) { // Example: like("val*ue") subset? like("v*e") return _left.isSubsetOf(right); } };
@Override public boolean visit(LikeCondition right) { return !_left.overlaps(right); } };
@Override public boolean overlaps(LikeCondition condition) { // If either condition is a constant then the other condition must contain the the condition's string to overlap. // For example, "door" overlaps "d*r" if (!hasWildcards()) { return condition.matches(getCondition()); } else if (!condition.hasWildcards()) { return matches(condition.getCondition()); } // Any internal wildcards surrounded by constants can match any other internal values, so determining overlap // only depends on the prefixes and suffixes. String prefix = getPrefix(); String otherPrefix = condition.getPrefix(); String suffix = getSuffix(); String otherSuffix = condition.getSuffix(); return (prefix == null || otherPrefix == null || prefix.startsWith(otherPrefix) || otherPrefix.startsWith(prefix)) && (suffix == null || otherSuffix == null || suffix.endsWith(otherSuffix) || otherSuffix.endsWith(suffix)); }
@Override public Boolean visit(ComparisonCondition right, Void context) { // Example: like("v*") subset? gt("v") if (right.getValue() instanceof String) { String value = (String) right.getValue(); // If the condition has a prefix then it can be used for comparison. String prefix = _left.getPrefix(); if (prefix == null) { // The condition is something like "*abc", so it cannot be definitively bound for comparison. return false; } return prefix.length() >= value.length() && ConditionEvaluator.eval(right, prefix, null); } return false; }
@Override public Boolean visit(EqualCondition right, Void context) { // Example: like("value") subset? "value" Object value = right.getValue(); if (value != null && value instanceof String) { String rValue = (String) value; String lValue = _left.getCondition(); // If it contains any wildcards it can't be a subset if (lValue.matches(".*(?<!\\\\)\\*.*")) { return false; } // Unescape all slashes lValue = lValue.replaceAll("\\\\\\\\", "\\\\"); return lValue.equals(rValue); } return false; }
@Override public boolean visit(ComparisonCondition right) { // Numeric comparisons such as gt(10) are always distinct from a "like" condition which only matches strings. if (!(right.getValue() instanceof String)) { return true; } // If the condition has a prefix then it can be used for comparison. String prefix = _left.getPrefix(); if (prefix == null) { // The condition is something like "*abc", so it cannot be distinct from a comparison. return false; } // The two are distinct if the "like" conditions prefix can never overlap with the comparison. // For example, like("ba*") is distinct from ge("be") but not gt("b"), since "bat" would satisfy both. String comparisonValue = (String) right.getValue(); return prefix.length() >= comparisonValue.length() && !ConditionEvaluator.eval(right, prefix, null); }
@Nullable @Override public Boolean visit(LikeCondition condition, @Nullable Object json) { // Null values and non-strings always don't match return json != null && json instanceof String && condition.matches(json.toString()); }
@Override public boolean isSubsetOf(LikeCondition condition) { // This condition is a subset of the other condition if this condition, with all wildcards replaced with // unique characters, matches the other condition. String testString = substituteWildcardsWith("\u0000"); return condition.matches(testString); }
@Override public boolean visit(InCondition right) { // The conditions are distinct if the "in" condition contains no values the match the "like" condition. for (Object value : right.getValues()) { if (value instanceof String && _left.matches((String) value)) { return false; } } return true; }
@Override public boolean visit(EqualCondition right) { // "Like" conditions are true only for strings, so it is distinct if the "equal" condition does not // contain a string constant which matches the "like" condition. return !(right.getValue() instanceof String && _left.matches((String) right.getValue())); }