Skip to content

Commit

Permalink
Merge pull request #38 from sidhant92/array_math_functions
Browse files Browse the repository at this point in the history
remove logging and add info to errors
  • Loading branch information
sidhant92 authored Jun 11, 2024
2 parents 1890a67 + 2824651 commit 11ae8af
Show file tree
Hide file tree
Showing 14 changed files with 51 additions and 78 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ repositories {
}

dependencies {
implementation 'ch.qos.logback:logback-classic:1.2.3'
implementation 'org.apache.maven:maven-artifact:3.5.2'
implementation 'org.antlr:antlr4-runtime:4.13.1'
implementation 'io.vavr:vavr:0.10.4'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@
import com.github.sidhant92.boolparser.parser.BoolExpressionParser;
import com.github.sidhant92.boolparser.util.ValueUtils;
import io.vavr.control.Try;
import lombok.extern.slf4j.Slf4j;

/**
* @author sidhant.aggarwal
* @since 15/03/2024
*/
@Slf4j
public class ArithmeticExpressionEvaluator {
private final BoolExpressionParser boolExpressionParser;

Expand Down Expand Up @@ -59,14 +57,13 @@ private Object evaluateToken(final Node node, final Map<String, Object> data) {
case FIELD:
return evaluateFieldToken((FieldNode) node, data);
default:
log.error("unsupported token {}", node.getTokenType());
throw new UnsupportedToken();
throw new UnsupportedToken(node.getTokenType().name());
}
}

private Object evaluateFieldToken(final FieldNode fieldNode, final Map<String, Object> data) {
if (!data.containsKey(fieldNode.getField())) {
throw new DataNotFoundException();
throw new DataNotFoundException(fieldNode.getField());
}
return data.get(fieldNode.getField());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@
import com.github.sidhant92.boolparser.parser.BoolExpressionParser;
import com.github.sidhant92.boolparser.util.ValueUtils;
import io.vavr.control.Try;
import lombok.extern.slf4j.Slf4j;

/**
* @author sidhant.aggarwal
* @since 07/02/2023
*/
@Slf4j
public class BooleanExpressionEvaluator {
private final BoolExpressionParser boolExpressionParser;

Expand Down Expand Up @@ -71,22 +69,25 @@ private boolean evaluateToken(final Node node, final Map<String, Object> data) {
}

private boolean evaluateComparisonToken(final ComparisonNode comparisonToken, final Map<String, Object> data) {
final Object fieldData = ValueUtils.getValueFromMap(comparisonToken.getField(), data).orElseThrow(DataNotFoundException::new);
final Object fieldData = ValueUtils.getValueFromMap(comparisonToken.getField(), data)
.orElseThrow(() -> new DataNotFoundException(comparisonToken.getField()));
final Object value = comparisonToken.getValue() instanceof ArithmeticBaseNode ? arithmeticExpressionEvaluator.evaluate(
comparisonToken.getValue(), data) : comparisonToken.getValue();
return operatorService.evaluateLogicalOperator(comparisonToken.getOperator(), ContainerDataType.PRIMITIVE, comparisonToken.getDataType(),
fieldData, value);
}

private boolean evaluateNumericRangeToken(final NumericRangeNode numericRangeToken, final Map<String, Object> data) {
final Object fieldData = ValueUtils.getValueFromMap(numericRangeToken.getField(), data).orElseThrow(DataNotFoundException::new);
final Object fieldData = ValueUtils.getValueFromMap(numericRangeToken.getField(), data)
.orElseThrow(() -> new DataNotFoundException(numericRangeToken.getField()));
return operatorService.evaluateLogicalOperator(Operator.GREATER_THAN_EQUAL, ContainerDataType.PRIMITIVE, numericRangeToken.getFromDataType(),
fieldData, numericRangeToken.getFromValue()) && operatorService.evaluateLogicalOperator(
Operator.LESS_THAN_EQUAL, ContainerDataType.PRIMITIVE, numericRangeToken.getToDataType(), fieldData, numericRangeToken.getToValue());
}

private boolean evaluateInToken(final InNode inToken, final Map<String, Object> data) {
final Object fieldData = ValueUtils.getValueFromMap(inToken.getField(), data).orElseThrow(DataNotFoundException::new);
final Object fieldData = ValueUtils.getValueFromMap(inToken.getField(), data)
.orElseThrow(() -> new DataNotFoundException(inToken.getField()));
final List<EvaluatedNode> items = resolveArrayElements(inToken.getItems(), data);
final DataType dataType = ValueUtils.getDataType(fieldData);
final Object[] values = items
Expand All @@ -109,7 +110,8 @@ private List<EvaluatedNode> resolveArrayElements(final List<Node> items, final M
}

private boolean evaluateArrayToken(final ArrayNode arrayNode, final Map<String, Object> data) {
final Object fieldData = ValueUtils.getValueFromMap(arrayNode.getField(), data).orElseThrow(DataNotFoundException::new);
final Object fieldData = ValueUtils.getValueFromMap(arrayNode.getField(), data)
.orElseThrow(() -> new DataNotFoundException(arrayNode.getField()));
final List<EvaluatedNode> items = resolveArrayElements(arrayNode.getItems(), data);
if (items
.stream()
Expand All @@ -127,7 +129,8 @@ private boolean evaluateUnaryToken(final UnaryNode unaryToken, final Map<String,
if (unaryToken.getDataType().equals(DataType.BOOLEAN)) {
return (boolean) unaryToken.getValue();
}
final Object fieldData = ValueUtils.getValueFromMap(unaryToken.getValue().toString(), data).orElseThrow(DataNotFoundException::new);
final Object fieldData = ValueUtils.getValueFromMap(unaryToken.getValue().toString(), data)
.orElseThrow(() -> new DataNotFoundException(unaryToken.getValue().toString()));
if (!(fieldData instanceof Boolean)) {
throw new InvalidUnaryOperand();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,19 @@
import com.github.sidhant92.boolparser.exception.InvalidDataType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
* @author sidhant.aggarwal
* @since 05/02/2023
*/
@Getter
@AllArgsConstructor
@Slf4j
public enum ContainerDataType {
PRIMITIVE() {
@Override
public <T> Optional<T> getValue(final DataType dataType, final Object value) {
final Optional<T> result = DataTypeFactory.getDataType(dataType).getValue(value);
if (!result.isPresent()) {
log.error("Invalid data type for value {} for data type {}", value.toString(), dataType.name());
throw new InvalidDataType(String.format("Invalid data type for value %s for data type %s", value, dataType.name()));
}
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

import java.util.Optional;
import com.github.sidhant92.boolparser.constant.DataType;
import lombok.extern.slf4j.Slf4j;

/**
* @author sidhant.aggarwal
* @since 05/03/2023
*/
@Slf4j
public abstract class AbstractDataType<T extends Comparable<? super T>> {
private final Class<T> clazz;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package com.github.sidhant92.boolparser.exception;

public class DataNotFoundException extends RuntimeException {
private static final String MESSAGE = "Data not found";

public DataNotFoundException(final String key) {
super(String.format(MESSAGE + " for the key %s", key));
}

@Override
public String getMessage() {
return "Data not found";
return MESSAGE;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.github.sidhant92.boolparser.exception;

public class InvalidExpressionException extends RuntimeException {
public InvalidExpressionException(final String message) {
super(message);
}

@Override
public String getMessage() {
return "Invalid Expression";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.github.sidhant92.boolparser.exception;

public class UnsupportedToken extends RuntimeException {
public UnsupportedToken(final String message) {
super(message);
private static final String MESSAGE = "Unsupported Token";

public UnsupportedToken(final String token) {
super(String.format(MESSAGE + " %s", token));
}

public UnsupportedToken() {
Expand All @@ -11,6 +13,6 @@ public UnsupportedToken() {

@Override
public String getMessage() {
return "Unsupported Token";
return MESSAGE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@
import com.github.sidhant92.boolparser.exception.InvalidDataType;
import com.github.sidhant92.boolparser.exception.InvalidExpressionException;
import com.github.sidhant92.boolparser.function.arithmetic.AbstractFunction;
import lombok.extern.slf4j.Slf4j;

/**
* @author sidhant.aggarwal
* @since 21/05/2024
*/
@Slf4j
public class FunctionEvaluatorService {
public FunctionEvaluatorService() {
FunctionFactory.initialize();
Expand All @@ -25,25 +23,23 @@ public FunctionEvaluatorService() {
public Object evaluateArithmeticFunction(final FunctionType functionType, final List<EvaluatedNode> items) {
final AbstractFunction abstractFunction = FunctionFactory.getArithmeticFunction(functionType);
if (items.isEmpty()) {
log.error("Empty items not allowed");
throw new InvalidExpressionException();
throw new InvalidExpressionException("Empty items not allowed");
}
final ContainerDataType containerDataType = items.size() > 1 ? ContainerDataType.LIST : ContainerDataType.PRIMITIVE;
if (!abstractFunction.getAllowedContainerTypes().contains(containerDataType)) {
log.error("Invalid container type {} for function {}", containerDataType, functionType.name());
throw new InvalidContainerTypeException();
throw new InvalidContainerTypeException(
String.format("Invalid container type %s for function %s", containerDataType, functionType.name()));
}
final boolean validDataType = items
.stream().allMatch(item -> abstractFunction.getAllowedDataTypes().contains(item.getDataType()));
if (!validDataType) {
log.error("Invalid data type {} for function {}", items, functionType.name());
throw new InvalidDataType();
throw new InvalidDataType(String.format("Invalid data type for function %s", functionType.name()));
}

items.forEach(item -> {
if (!ContainerDataType.PRIMITIVE.isValid(item.getDataType(), item.getValue())) {
log.error("Validation failed for the function {} for the operand {}", functionType.name(), item.getValue());
throw new InvalidDataType();
throw new InvalidDataType(
String.format("Validation failed for the function %s for the operand %s", functionType.name(), item.getValue()));
}
});
return abstractFunction.evaluate(items);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@
import com.github.sidhant92.boolparser.exception.InvalidContainerTypeException;
import com.github.sidhant92.boolparser.exception.InvalidDataType;
import com.github.sidhant92.boolparser.operator.logical.AbstractOperator;
import lombok.extern.slf4j.Slf4j;

/**
* @author sidhant.aggarwal
* @since 05/03/2023
*/
@Slf4j
public class OperatorService {
public OperatorService() {
DataTypeFactory.initialize();
Expand All @@ -25,16 +23,13 @@ public boolean evaluateLogicalOperator(final Operator operator, final ContainerD
final Object leftOperand, final Object... rightOperands) {
final AbstractOperator abstractOperator = OperatorFactory.getLogicalOperator(operator);
if (!abstractOperator.getAllowedContainerTypes().contains(containerDataType)) {
log.error("Invalid left container type {} for operator {}", containerDataType, operator);
throw new InvalidContainerTypeException();
throw new InvalidContainerTypeException(String.format("Invalid left container type %s for operator %s", containerDataType, operator));
}
if (!abstractOperator.getAllowedDataTypes().contains(dataType)) {
log.error("Invalid left operand data type {} for operator {}", dataType, operator);
throw new InvalidDataType();
throw new InvalidDataType(String.format("Invalid left operand data type %s for operator %s", dataType, operator));
}
if (!containerDataType.isValid(dataType, leftOperand)) {
log.error("Validation failed for the operator {} for the operand {}", operator, leftOperand);
throw new InvalidDataType();
throw new InvalidDataType(String.format("Validation failed for the operator %s for the operand %s", operator, leftOperand));
}
return OperatorFactory.getLogicalOperator(operator).evaluate(containerDataType, dataType, leftOperand, rightOperands);
}
Expand All @@ -43,24 +38,19 @@ public Object evaluateArithmeticOperator(final Object leftOperand, final DataTyp
final DataType rightDataType, final Operator operator, final ContainerDataType containerDataType) {
final com.github.sidhant92.boolparser.operator.arithmetic.AbstractOperator abstractOperator = OperatorFactory.getArithmeticOperator(operator);
if (!abstractOperator.getAllowedContainerTypes().contains(containerDataType)) {
log.error("Invalid left container type {} for operator {}", containerDataType, operator);
throw new InvalidContainerTypeException();
throw new InvalidContainerTypeException(String.format("Invalid left container type %s for operator %s", containerDataType, operator));
}
if (!abstractOperator.getAllowedDataTypes().contains(leftDataType)) {
log.error("Invalid left operand data type {} for operator {}", leftDataType, operator);
throw new InvalidDataType();
throw new InvalidDataType(String.format("Invalid left operand data type %s for operator %s", leftDataType, operator));
}
if (!containerDataType.isValid(leftDataType, leftOperand)) {
log.error("Validation failed for the operator {} for the operand {}", operator, leftOperand);
throw new InvalidDataType();
throw new InvalidDataType(String.format("Validation failed for the operator %s for the operand %s", operator, leftOperand));
}
if (Objects.nonNull(rightDataType) && !abstractOperator.getAllowedDataTypes().contains(rightDataType)) {
log.error("Invalid left operand data type {} for operator {}", rightDataType, operator);
throw new InvalidDataType();
throw new InvalidDataType(String.format("Invalid left operand data type %s for operator %s", rightDataType, operator));
}
if (Objects.nonNull(rightOperand) && !containerDataType.isValid(rightDataType, rightOperand)) {
log.error("Validation failed for the operator {} for the operand {}", operator, rightDataType);
throw new InvalidDataType();
throw new InvalidDataType(String.format("Validation failed for the operator %s for the operand %s", operator, rightDataType));
}
return OperatorFactory.getArithmeticOperator(operator).evaluate(leftOperand, leftDataType, rightOperand, rightDataType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.Operator;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@AllArgsConstructor
@Slf4j
public class ContainsAllOperator extends AbstractOperator {
private final InOperator inOperator;

@Override
public <T extends Comparable<? super T>> boolean evaluate(final ContainerDataType containerDataType, final DataType dataType,
final Object leftOperand, final Object... rightOperands) {
if (!containerDataType.isValid(dataType, leftOperand)) {
log.error("Validation failed for any operator for the operand {}", leftOperand);
return false;
}
final Object[] leftOperandArray = ((List<?>) leftOperand).toArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,15 @@
import com.github.sidhant92.boolparser.constant.DataType;
import com.github.sidhant92.boolparser.constant.Operator;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@AllArgsConstructor
@Slf4j
public class ContainsAnyOperator extends AbstractOperator {
private final InOperator inOperator;

@Override
public <T extends Comparable<? super T>> boolean evaluate(final ContainerDataType containerDataType, final DataType dataType,
final Object leftOperand, final Object... rightOperands) {
if (!containerDataType.isValid(dataType, leftOperand)) {
log.error("Validation failed for any operator for the operand {}", leftOperand);
return false;
}
final Object[] leftOperandArray = ((List<?>) leftOperand).toArray();
Expand Down
Loading

0 comments on commit 11ae8af

Please sign in to comment.