com.contentgrid.thunx.predicates.model.FunctionExpression Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of thunx-model Show documentation
Show all versions of thunx-model Show documentation
Set of (vendor-neutral) data structures to model authorization policy expressions
package com.contentgrid.thunx.predicates.model;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
public interface FunctionExpression extends ThunkExpression {
Operator getOperator();
List> getTerms();
default R accept(ThunkExpressionVisitor visitor, C context) {
return visitor.visit(this, context);
}
default String toDebugString() {
return String.format("%s(%s)",
this.getOperator().getKey().toUpperCase(Locale.ROOT),
this.getTerms().stream().map(Object::toString).collect(Collectors.joining(", ")));
}
// TASK switch this to an interface Operator with sealed classes as subtypes
// that would eliminate much of the casting
@RequiredArgsConstructor
enum Operator {
// Comparison operators
EQUALS("eq", Boolean.class, (FunctionExpressionFactory) Comparison::areEqual),
NOT_EQUAL_TO("neq", Boolean.class, (FunctionExpressionFactory) Comparison::notEqual),
GREATER_THAN("gt", Boolean.class, (FunctionExpressionFactory) Comparison::greater),
GREATER_THAN_OR_EQUAL_TO("gte", Boolean.class, (FunctionExpressionFactory) Comparison::greaterOrEquals),
LESS_THAN("lt", Boolean.class, (FunctionExpressionFactory) Comparison::less),
LESS_THEN_OR_EQUAL_TO("lte", Boolean.class, (FunctionExpressionFactory) Comparison::lessOrEquals),
// Logical operator
AND("and", Boolean.class, (FunctionExpressionFactory) LogicalOperation::uncheckedConjunction),
OR("or", Boolean.class, (FunctionExpressionFactory) LogicalOperation::uncheckedDisjunction),
NOT("not", Boolean.class, (FunctionExpressionFactory) LogicalOperation::uncheckedNegation),
// Numeric operators
PLUS("plus", Number.class, (FunctionExpressionFactory) NumericFunction::plus),
MINUS("minus", Number.class, (FunctionExpressionFactory) NumericFunction::minus),
DIVIDE("div", Number.class, (FunctionExpressionFactory) NumericFunction::divide),
MULTIPLY("mul", Number.class, (FunctionExpressionFactory) NumericFunction::multiply),
MODULUS("mod", Number.class, (FunctionExpressionFactory) NumericFunction::modulus);
@Getter
@NonNull
private final String key;
@Getter
@NonNull
private final Class> type;
// TODO remove getter, expose create method directly and delegate to the factory instead
@Getter
@NonNull
private final FunctionExpressionFactory> factory;
public static Operator resolve(@NonNull String key) {
return Arrays.stream(Operator.values())
.filter(op -> Objects.equals(key, op.getKey()))
.findFirst()
.orElseThrow(() -> {
String message = String.format("Invalid %s key: '%s'", Operator.class.getSimpleName(), key);
return new IllegalArgumentException(message);
});
}
public FunctionExpression> create(List> terms) {
return this.factory.create(terms);
}
}
@FunctionalInterface
interface FunctionExpressionFactory {
FunctionExpression create(List> terms);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy