Untitled
unknown
plain_text
5 months ago
6.4 kB
4
Indexable
public final class ApprovalFilterUtils { private ApprovalFilterUtils() {} public static boolean matches( @NonNull Map<String, Object> requestedFilters, @NonNull List<ApprovalFilterModel> storedFilters) { Assert.notNull(requestedFilters, "requestedFilters cannot be null"); Assert.notNull(storedFilters, "storedFilters cannot be null"); Assert.noNullElements(storedFilters, "storedFilters must not contain null elements"); for (ApprovalFilterModel filter : storedFilters) { Object requestedValue = requestedFilters.get(filter.getName());//DISCOUNT if (!validate(requestedValue, filter.getType(), filter.getOperation())) { return false; } boolean match = switch (filter.getOperation()) { case EQUALS -> Objects.equals(requestedValue, filter.getValue()); case NOT_EQUALS -> !Objects.equals(requestedValue, filter.getValue()); case GREATER_THAN -> compare(requestedValue, filter.getValue()) > 0; case GREATER_THAN_EQUALS -> compare(requestedValue, filter.getValue()) >= 0; case LESS_THAN -> compare(requestedValue, filter.getValue()) < 0; case LESS_THAN_EQUALS -> compare(requestedValue, filter.getValue()) <= 0; case IN -> listContains(filter.getValue(), requestedValue); case NIN -> !listContains(filter.getValue(), requestedValue); default -> throw new UnsupportedOperationException( "Unsupported operation: " + filter.getOperation()); }; if (!match) { return false; } } return true; } private static final Map<Class<?>, Function<String, Comparable<?>>> CONVERTERS = Map.of( LocalDateTime.class, str -> LocalDateTime.parse(str), OffsetDateTime.class, str -> OffsetDateTime.parse(str), BigDecimal.class, str -> new BigDecimal(str) ); private static int compare(Object o1, Object o2) { if (o1 == null || o2 == null) { throw new IllegalArgumentException("Cannot compare null values"); } Comparable<Object> c1 = (Comparable<Object>) convertIfString(o1); Comparable<Object> c2 = (Comparable<Object>) convertIfString(o2); if (!c1.getClass().equals(c2.getClass())) { throw new IllegalArgumentException("Cannot compare different types: " + c1.getClass() + " and " + c2.getClass()); } return c1.compareTo(c2); } private static Comparable<?> convertIfString(Object obj) { if (obj instanceof String str) { for (var entry : CONVERTERS.entrySet()) { try { return entry.getValue().apply(str); } catch (Exception ignored) { } } return str; } return (Comparable<?>) obj; } private static boolean listContains(Object storedValue, Object requestedValue) { if (storedValue instanceof List<?> list) { return list.contains(requestedValue); } else if (storedValue instanceof String str) { return Arrays.asList(str.split(",\\s*")).contains(String.valueOf(requestedValue)); } return false; } private static final Map<ApprovalFilterValueType, Class<?>> CLASSES = Map.of( ApprovalFilterValueType.STRING, String.class, ApprovalFilterValueType.NUMBER, BigDecimal.class, ApprovalFilterValueType.DATE, LocalDate.class, ApprovalFilterValueType.DATE_TIME, LocalDateTime.class, ApprovalFilterValueType.DATE_TIME_WITH_TIMEZONE, OffsetDateTime.class); private static final Set<ApprovalFilterOperation> LIST_OPERATIONS = EnumSet.of(ApprovalFilterOperation.IN, ApprovalFilterOperation.NIN); private static final Map<ApprovalFilterValueType, Set<ApprovalFilterOperation>> UNSUPPORTED_OPERATIONS = Map.of( ApprovalFilterValueType.STRING, EnumSet.complementOf( EnumSet.of( ApprovalFilterOperation.EQUALS, ApprovalFilterOperation.NOT_EQUALS, ApprovalFilterOperation.IN, ApprovalFilterOperation.NIN))); private static final ApplicationConversionService CONVERSION_SERVICE = new ApplicationConversionService(); /** * Validates if the provided object can be converted to value of given type that can be used to * provide the requested operation. Not all types support all operations. * * @param o the object to validate. nulls are allowed * @param type the type of the value to consider * @param operation the operation that has to be performed * @return whether the object of requested type supports requested operation */ public static boolean validate( @Nullable Object o, @NonNull ApprovalFilterValueType type, @NonNull ApprovalFilterOperation operation) { //dis,string,eq if (o == null) { return true; } var unsupportedOperations = UNSUPPORTED_OPERATIONS.getOrDefault(type, Set.of()); if (unsupportedOperations.contains(operation)) { return false; } TypeDescriptor td = TypeDescriptor.valueOf(getTargetClass(type)); if (LIST_OPERATIONS.contains(operation)) { td = TypeDescriptor.collection(List.class, td); } return CONVERSION_SERVICE.canConvert(TypeDescriptor.forObject(o), td); } @NonNull private static Class<?> getTargetClass(@NonNull ApprovalFilterValueType type) { Assert.notNull(type, "ApprovalFilterValueType must not be null"); var clazz = CLASSES.get(type); if (clazz == null) { throw new IllegalArgumentException( "ApprovalFilterValueType " + type + " not supported"); } return clazz; } }
Editor is loading...
Leave a Comment