ValueMatcher implements JsonSerializable, Predicate<JsonSerializable> { @NonNull public static ValueMatcher parse(@Nullable JsonValue jsonValue) throws JsonException { JsonMap map = jsonValue == null ? JsonMap.EMPTY_MAP : jsonValue.optMap(); if (map.containsKey(ExactValueMatcher.EQUALS_VALUE_KEY)) { return newValueMatcher(map.opt(ExactValueMatcher.EQUALS_VALUE_KEY)); } if (map.containsKey(NumberRangeMatcher.MIN_VALUE_KEY) || map.containsKey(NumberRangeMatcher.MAX_VALUE_KEY)) { Double min = map.containsKey(NumberRangeMatcher.MIN_VALUE_KEY) ? map.opt(NumberRangeMatcher.MIN_VALUE_KEY).getDouble(0) : null; Double max = map.containsKey(NumberRangeMatcher.MAX_VALUE_KEY) ? map.opt(NumberRangeMatcher.MAX_VALUE_KEY).getDouble(0) : null; try { return newNumberRangeMatcher(min, max); } catch (IllegalArgumentException e) { throw new JsonException("Invalid range matcher: " + jsonValue, e); } } if (map.containsKey(PresenceMatcher.IS_PRESENT_VALUE_KEY)) { boolean isPresent = map.opt(PresenceMatcher.IS_PRESENT_VALUE_KEY).getBoolean(false); return isPresent ? newIsPresentMatcher() : newIsAbsentMatcher(); } if (map.containsKey(VersionMatcher.VERSION_KEY)) { try { String constraint = map.opt(VersionMatcher.VERSION_KEY).optString(); return newVersionMatcher(constraint); } catch (NumberFormatException e) { throw new JsonException("Invalid version constraint: " + map.opt(VersionMatcher.VERSION_KEY), e); } } if (map.containsKey(VersionMatcher.ALTERNATE_VERSION_KEY)) { try { String constraint = map.opt(VersionMatcher.ALTERNATE_VERSION_KEY).optString(); return newVersionMatcher(constraint); } catch (NumberFormatException e) { throw new JsonException("Invalid version constraint: " + map.opt(VersionMatcher.ALTERNATE_VERSION_KEY), e); } } if (map.containsKey(ArrayContainsMatcher.ARRAY_CONTAINS_KEY)) { JsonPredicate predicate = JsonPredicate.parse(map.get(ArrayContainsMatcher.ARRAY_CONTAINS_KEY)); if (map.containsKey(ArrayContainsMatcher.INDEX_KEY)) { int index = map.opt(ArrayContainsMatcher.INDEX_KEY).getInt(-1); if (index == -1) { throw new JsonException("Invalid index for array_contains matcher: " + map.get(ArrayContainsMatcher.INDEX_KEY)); } return newArrayContainsMatcher(predicate, index); } else { return newArrayContainsMatcher(predicate); } } throw new JsonException("Unknown value matcher: " + jsonValue); } protected  ValueMatcher(); @NonNull static ValueMatcher newNumberRangeMatcher(@Nullable Double min, @Nullable Double max); @NonNull static ValueMatcher newValueMatcher(@NonNull JsonValue value); @NonNull static ValueMatcher newIsPresentMatcher(); @NonNull static ValueMatcher newIsAbsentMatcher(); @NonNull static ValueMatcher newVersionMatcher(@NonNull String constraint); @NonNull static ValueMatcher newArrayContainsMatcher(@NonNull JsonPredicate predicate, int index); @NonNull static ValueMatcher newArrayContainsMatcher(@NonNull JsonPredicate predicate); @NonNull static ValueMatcher parse(@Nullable JsonValue jsonValue); @Override boolean apply(@Nullable JsonSerializable jsonSerializable); @NonNull @Override String toString();  }
@Test public void testParse() throws JsonException { Double min = 5.0; Double max = 7.0; JsonValue json = JsonMap.newBuilder() .put("at_least", min) .put("at_most", max) .build() .toJsonValue(); ValueMatcher matcher = ValueMatcher.newNumberRangeMatcher(min, max); assertEquals(matcher, ValueMatcher.parse(json)); json = JsonMap.newBuilder() .put("is_present", true) .build() .toJsonValue(); matcher = ValueMatcher.newIsPresentMatcher(); assertEquals(matcher, ValueMatcher.parse(json)); json = JsonMap.newBuilder() .put("equals", "string") .build() .toJsonValue(); matcher = ValueMatcher.newValueMatcher(JsonValue.wrap("string")); assertEquals(matcher, ValueMatcher.parse(json)); json = JsonMap.newBuilder() .put("equals", "string") .put("ignore_case", true) .build() .toJsonValue(); matcher = ValueMatcher.newValueMatcher(JsonValue.wrap("string")); assertEquals(matcher, ValueMatcher.parse(json)); json = JsonMap.newBuilder() .put("equals", "string") .put("ignore_case", true) .build() .toJsonValue(); matcher = ValueMatcher.newValueMatcher(JsonValue.wrap("string")); assertEquals(matcher, ValueMatcher.parse(json)); json = JsonMap.newBuilder() .put("version_matches", "1.2.4") .build() .toJsonValue(); matcher = ValueMatcher.newVersionMatcher("1.2.4"); assertEquals(matcher, ValueMatcher.parse(json)); json = JsonMap.newBuilder() .put("version", "1.2.4") .build() .toJsonValue(); matcher = ValueMatcher.newVersionMatcher("1.2.4"); assertEquals(matcher, ValueMatcher.parse(json)); }