li.strolch.soql.core.expresssion.ComparisonExpression Maven / Gradle / Ivy
package li.strolch.soql.core.expresssion;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import li.strolch.soql.core.SOQLEvaluationException;
/**
* Compares two or more expressions, for example 'a.name = "12345"'
*
* Currently only the following operators for equality check are supported:
*
* '=' | '<>' | '>' | '>=' | '<' | '<=' ;
*
* @author msmock
*/
public class ComparisonExpression extends AbstractBooleanExpression {
private String operator;
private final List operands = new ArrayList<>();
@Override
public boolean evaluate(Map inputObjects, Map queryParameter) {
return switch (operator) {
case "=" -> evaluateEquals(inputObjects, queryParameter);
case "<>" -> !evaluateEquals(inputObjects, queryParameter);
case ">" -> evaluateMore(inputObjects, queryParameter);
case "<" -> evaluateLess(inputObjects, queryParameter);
case ">=" -> !evaluateLess(inputObjects, queryParameter);
case "<=" -> !evaluateMore(inputObjects, queryParameter);
default -> throw new SOQLEvaluationException(
"Comparison with operator " + operator + " is not supported yet.");
};
}
/**
* TODO: allow comparison, if the classes do not match. I.e. compare Integer with Double
*
* @param inputObjects
* @param queryParameter
*
* @return
*/
private boolean evaluateLess(final Map inputObjects, final Map queryParameter) {
final Object result_1 = operands.get(0).evaluate(inputObjects, queryParameter);
final Object result_2 = operands.get(1).evaluate(inputObjects, queryParameter);
final Class> clazz_1 = result_1.getClass();
final Class> clazz_2 = result_2.getClass();
if (!clazz_1.equals(clazz_2)) {
throw new SOQLEvaluationException(
"Operation < not defined for comparison of " + result_1 + " of class " + clazz_1 + " with "
+ result_2 + " of class " + clazz_2);
}
if (result_1 instanceof Integer && result_2 instanceof Integer) {
return ((Integer) result_1).compareTo((Integer) result_2) < 0;
} else if (result_1 instanceof Long && result_2 instanceof Long) {
return ((Long) result_1).compareTo((Long) result_2) < 0;
} else if (result_1 instanceof Float && result_2 instanceof Float) {
return ((Float) result_1).compareTo((Float) result_2) < 0;
} else if (result_1 instanceof Double && result_2 instanceof Double) {
return ((Double) result_1).compareTo((Double) result_2) < 0;
}
return false;
}
private boolean evaluateMore(final Map inputObjects, final Map queryParameter) {
final Object result_1 = operands.get(0).evaluate(inputObjects, queryParameter);
final Object result_2 = operands.get(1).evaluate(inputObjects, queryParameter);
final Class> clazz_1 = result_1.getClass();
final Class> clazz_2 = result_2.getClass();
if (!clazz_1.equals(clazz_2)) {
throw new SOQLEvaluationException(
"Operation < not defined for comparison of " + result_1 + " of class " + clazz_1 + " with "
+ result_2 + " of class " + clazz_2);
}
if (result_1 instanceof Integer && result_2 instanceof Integer) {
return ((Integer) result_1).compareTo((Integer) result_2) > 0;
} else if (result_1 instanceof Long && result_2 instanceof Long) {
return ((Long) result_1).compareTo((Long) result_2) > 0;
} else if (result_1 instanceof Float && result_2 instanceof Float) {
return ((Float) result_1).compareTo((Float) result_2) > 0;
} else if (result_1 instanceof Double && result_2 instanceof Double) {
return ((Double) result_1).compareTo((Double) result_2) > 0;
}
return false;
}
/**
* @return true if the String representation of the operands match
*/
private boolean evaluateEquals(final Map inputObjects, final Map queryParameter) {
Object result_1 = operands.get(0).evaluate(inputObjects, queryParameter);
Object result_2 = operands.get(1).evaluate(inputObjects, queryParameter);
if (result_1 == null || result_2 == null)
return false;
return result_1.equals(result_2);
}
public void setOperator(String operator) {
this.operator = operator;
}
public void addOperand(IObjectExpression operand) {
operands.add(operand);
operand.setParent(this);
}
@Override
public String toString() {
return "ComparisonExpression [operator=" + operator + ", operands=" + operands + "]";
}
}