in src/main/software/amazon/event/ruler/Ruler.java [101:203]
private static boolean matches(final JsonNode val, final Patterns pattern) {
switch (pattern.type()) {
case EXACT:
ValuePatterns valuePattern = (ValuePatterns) pattern;
// if it's a string we match the "-quoted form, otherwise (true, false, null) as-is.
final String compareTo = (val.isTextual()) ? '"' + val.asText() + '"' : val.asText();
return compareTo.equals(valuePattern.pattern());
case PREFIX:
valuePattern = (ValuePatterns) pattern;
return val.isTextual() && ('"' + val.asText()).startsWith(valuePattern.pattern());
case PREFIX_EQUALS_IGNORE_CASE:
valuePattern = (ValuePatterns) pattern;
return val.isTextual() && ('"' + val.asText().toLowerCase(Locale.ROOT))
.startsWith(valuePattern.pattern().toLowerCase(Locale.ROOT));
case SUFFIX:
valuePattern = (ValuePatterns) pattern;
// Undoes the reverse on the pattern value to match against the provided value
return val.isTextual() && (val.asText() + '"')
.endsWith(new StringBuilder(valuePattern.pattern()).reverse().toString());
case SUFFIX_EQUALS_IGNORE_CASE:
valuePattern = (ValuePatterns) pattern;
// Undoes the reverse on the pattern value to match against the provided value
return val.isTextual() && (val.asText().toLowerCase(Locale.ROOT) + '"')
.endsWith(new StringBuilder(valuePattern.pattern().toLowerCase(Locale.ROOT)).reverse().toString());
case ANYTHING_BUT:
assert (pattern instanceof AnythingBut);
AnythingBut anythingButPattern = (AnythingBut) pattern;
if (val.isTextual()) {
return anythingButPattern.getValues().stream().noneMatch(v -> v.equals('"' + val.asText() + '"'));
} else if (val.isNumber()) {
return anythingButPattern.getValues().stream()
.noneMatch(v -> v.equals(ComparableNumber.generate(val.asText())));
}
return false;
case ANYTHING_BUT_IGNORE_CASE:
assert (pattern instanceof AnythingButValuesSet);
AnythingButValuesSet anythingButIgnoreCasePattern = (AnythingButValuesSet) pattern;
if (val.isTextual()) {
return anythingButIgnoreCasePattern.getValues().stream().noneMatch(v -> v.equalsIgnoreCase('"' + val.asText() + '"'));
}
return false;
case ANYTHING_BUT_SUFFIX:
AnythingButValuesSet anythingButSuffixPattern = (AnythingButValuesSet) pattern;
String valueForSuffix = val.asText() + '"';
if (val.isTextual()) {
return anythingButSuffixPattern.getValues().stream().noneMatch(v -> valueForSuffix.startsWith(v));
}
return false;
case ANYTHING_BUT_PREFIX:
AnythingButValuesSet anythingButPrefixPattern = (AnythingButValuesSet) pattern;
String valueForPrefix = '"' + val.asText() + '"';
if (val.isTextual()) {
return anythingButPrefixPattern.getValues().stream().noneMatch(v -> valueForPrefix.startsWith(v));
}
return false;
case NUMERIC_EQ:
valuePattern = (ValuePatterns) pattern;
return val.isNumber() && ComparableNumber.generate(val.asText()).equals(valuePattern.pattern());
case EXISTS:
return true;
case ABSENT:
return false;
case NUMERIC_RANGE:
final Range nr = (Range) pattern;
byte[] bytes;
if (nr.isCIDR) {
if (!val.isTextual()) {
return false;
}
try {
bytes = CIDR.ipToString(val.asText()).getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
return false;
}
} else {
if (!val.isNumber()) {
return false;
}
bytes = ComparableNumber.generate(val.asText()).getBytes(StandardCharsets.UTF_8);
}
final int comparedToBottom = compare(bytes, nr.bottom);
if ((comparedToBottom > 0) || (comparedToBottom == 0 && !nr.openBottom)) {
final int comparedToTop = compare(bytes, nr.top);
return comparedToTop < 0 || (comparedToTop == 0 && !nr.openTop);
}
return false;
case EQUALS_IGNORE_CASE:
valuePattern = (ValuePatterns) pattern;
return val.isTextual() && ('"' + val.asText() + '"').equalsIgnoreCase(valuePattern.pattern());
case WILDCARD:
valuePattern = (ValuePatterns) pattern;
return val.isTextual() &&
('"' + val.asText() + '"').matches(valuePattern.pattern().replaceAll("\\*", ".*"));
default:
throw new RuntimeException("Unsupported Pattern type " + pattern.type());
}
}