Skip to content

Commit

Permalink
Merge pull request #2307 from GDLMadushanka/revertBigDecimalChange
Browse files Browse the repository at this point in the history
Revert usage of Bigdecimal
  • Loading branch information
GDLMadushanka authored Jan 27, 2025
2 parents e3afd33 + 676a136 commit 28ce3ef
Show file tree
Hide file tree
Showing 11 changed files with 49 additions and 73 deletions.
Binary file added modules/core/jacoco.exec
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import org.apache.synapse.core.axis2.Axis2MessageContext;

import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import javax.xml.namespace.QName;

public class Utils {
Expand Down Expand Up @@ -185,7 +184,6 @@ private static Object convertExpressionResult(Object evaluatedValue, String type
if (!(evaluatedValue instanceof Double)) {
handleDataTypeException("DOUBLE", expression, log);
}
evaluatedValue = BigDecimal.valueOf((Double) evaluatedValue);
break;
case INTEGER:
if (!(evaluatedValue instanceof Integer)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ public ExpressionResult evaluate(EvaluationContext context, boolean isObjectValu
case NOT_EQUALS:
return handleNotEquality(leftValue, rightValue);
case LESS_THAN:
return handleComparison(leftValue, rightValue, (a, b) -> a.compareTo(b)<0);
return handleComparison(leftValue, rightValue, (a, b) -> a < b);
case LESS_THAN_OR_EQUAL:
return handleComparison(leftValue, rightValue, (a, b) -> a.compareTo(b)<=0);
return handleComparison(leftValue, rightValue, (a, b) -> a <= b);
case GREATER_THAN:
return handleComparison(leftValue, rightValue, (a, b) -> a.compareTo(b)>0);
return handleComparison(leftValue, rightValue, (a, b) -> a > b);
case GREATER_THAN_OR_EQUAL:
return handleComparison(leftValue, rightValue, (a, b) -> a.compareTo(b)>=0);
return handleComparison(leftValue, rightValue, (a, b) -> a >= b);
case AND:
case AND_SYMBOL:
case OR:
Expand All @@ -113,7 +113,7 @@ public ExpressionResult evaluate(EvaluationContext context, boolean isObjectValu
}

private ExpressionResult handleComparison(ExpressionResult leftValue, ExpressionResult rightValue,
BiFunction<BigDecimal, BigDecimal, Boolean> comparison) {
BiFunction<Double, Double, Boolean> comparison) {
if ((leftValue.isDouble() || leftValue.isInteger()) && (rightValue.isDouble() || rightValue.isInteger())) {
return new ExpressionResult(comparison.apply(leftValue.asDouble(), rightValue.asDouble()));
}
Expand Down Expand Up @@ -152,7 +152,10 @@ private ExpressionResult handleLogical(ExpressionResult leftValue, ExpressionRes
private ExpressionResult handleAddition(ExpressionResult leftValue, ExpressionResult rightValue) {
if (leftValue.isNumeric() && rightValue.isNumeric()) {
if (leftValue.isDouble() || rightValue.isDouble()) {
return new ExpressionResult(leftValue.asDouble().add(rightValue.asDouble()));
BigDecimal left = new BigDecimal(leftValue.asString());
BigDecimal right = new BigDecimal(rightValue.asString());
BigDecimal sum = left.add(right);
return new ExpressionResult(sum.doubleValue());
} else if (leftValue.isLong() || rightValue.isLong()) {
return new ExpressionResult(leftValue.asLong() + rightValue.asLong());
} else {
Expand Down Expand Up @@ -184,8 +187,8 @@ private ExpressionResult handleArithmetic(ExpressionResult leftValue, Expression

// Promote to the highest precision type
if (leftIsDouble || rightIsDouble) {
BigDecimal left = leftValue.asDouble();
BigDecimal right = rightValue.asDouble();
double left = leftValue.asDouble();
double right = rightValue.asDouble();
return performDoubleOperation(left, right, operator);
} else if (leftIsLong || rightIsLong) {
long left = leftValue.asLong();
Expand All @@ -199,25 +202,27 @@ private ExpressionResult handleArithmetic(ExpressionResult leftValue, Expression
}
}

private ExpressionResult performDoubleOperation(BigDecimal left, BigDecimal right, Operator operator) {
private ExpressionResult performDoubleOperation(double left, double right, Operator operator) {
BigDecimal left1 = new BigDecimal(String.valueOf(left));
BigDecimal right1 = new BigDecimal(String.valueOf(right));
switch (operator) {
case SUBTRACT:
BigDecimal sum = left.subtract(right);
BigDecimal sum = left1.subtract(right1);
return new ExpressionResult(sum.doubleValue());
case MULTIPLY:
BigDecimal product = left.multiply(right);
return new ExpressionResult(product);
BigDecimal product = left1.multiply(right1);
return new ExpressionResult(product.doubleValue());
case DIVIDE:
if (right.compareTo(BigDecimal.ZERO) == 0) {
if (right == 0) {
throw new EvaluationException("Division by zero");
}
BigDecimal quotient = left.divide(right, BigDecimal.ROUND_HALF_UP);
BigDecimal quotient = left1.divide(right1, BigDecimal.ROUND_HALF_UP);
return new ExpressionResult(quotient.doubleValue());
case MODULO:
if (right.compareTo(BigDecimal.ZERO) == 0) {
if (right == 0) {
throw new EvaluationException("Modulo by zero");
}
BigDecimal remainder = left.remainder(right);
BigDecimal remainder = left1.remainder(right1);
return new ExpressionResult(remainder.doubleValue());
default:
throw new EvaluationException("Unsupported operator: " + operator + " between "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@
import com.google.gson.internal.LazilyParsedNumber;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axis2.databinding.types.xsd._double;
import org.apache.synapse.util.synapse.expression.exception.EvaluationException;

import java.math.BigDecimal;
import java.util.List;

/**
Expand Down Expand Up @@ -73,7 +70,7 @@ public ExpressionResult(long value) {
this.value = value;
}

public ExpressionResult(BigDecimal value) {
public ExpressionResult(double value) {
this.value = value;
}

Expand Down Expand Up @@ -109,9 +106,7 @@ public String asString() {

// Method to get value as int
public int asInt() {
if (value instanceof Integer) {
return (Integer) value;
} else if (value instanceof Number) {
if (value instanceof Number) {
return ((Number) value).intValue();
} else if (value instanceof JsonPrimitive && ((JsonPrimitive) value).isNumber()) {
return ((JsonPrimitive) value).getAsInt();
Expand All @@ -120,13 +115,11 @@ public int asInt() {
}

// Method to get value as double
public BigDecimal asDouble() {
if (value instanceof BigDecimal) {
return (BigDecimal) value;
} else if (value instanceof Number) {
return new BigDecimal(value.toString());
public double asDouble() {
if (value instanceof Number) {
return ((Number) value).doubleValue();
} else if (value instanceof JsonPrimitive && ((JsonPrimitive) value).isNumber()) {
return new BigDecimal(((JsonPrimitive) value).getAsString());
return ((JsonPrimitive) value).getAsDouble();
}
throw new EvaluationException("Value : " + value + " cannot be converted to double");
}
Expand Down Expand Up @@ -198,8 +191,7 @@ public boolean isLong() {
}

public boolean isDouble() {
return value instanceof BigDecimal || value instanceof Double ||
(value instanceof JsonPrimitive && isDouble((JsonPrimitive) value));
return value instanceof Double || (value instanceof JsonPrimitive && isDouble((JsonPrimitive) value));
}

public boolean isBoolean() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ private ExpressionResult tryParseNumber(String value) {
return new ExpressionResult(Long.parseLong(value));
} catch (NumberFormatException e2) {
try {
Double.parseDouble(value);
// if double stored as big decimal, for accurate calculations
return new ExpressionResult(new BigDecimal(value));
return new ExpressionResult(Double.parseDouble(value));
} catch (NumberFormatException e3) {
return new ExpressionResult(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import com.google.gson.JsonElement;
import org.apache.synapse.util.synapse.expression.context.EvaluationContext;

import java.math.BigDecimal;

/**
* Represents a leaf node in the AST that holds a literal value.
*/
Expand Down Expand Up @@ -77,9 +75,7 @@ private ExpressionResult parseNumber(String value) {
return new ExpressionResult(Long.parseLong(value));
} catch (NumberFormatException e2) {
try {
Double.parseDouble(value);
// if double stored as big decimal, for accurate calculations
return new ExpressionResult(new BigDecimal(value));
return new ExpressionResult(Double.parseDouble(value));
} catch (NumberFormatException e3) {
throw new IllegalArgumentException("Value " + value + " is not a number");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,11 @@
*/
package org.apache.synapse.util.synapse.expression.ast;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonPrimitive;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.PathNotFoundException;
import com.jayway.jsonpath.spi.json.GsonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.GsonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import org.apache.axiom.om.OMNode;
import org.apache.commons.lang3.StringUtils;
import org.apache.synapse.util.synapse.expression.constants.ExpressionConstants;
Expand All @@ -38,21 +31,19 @@
import org.jaxen.JaxenException;

import java.io.IOException;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
* Represents a node in the AST that accesses a value in the payload or variable.
* Resolve placeholders in the expression and evaluate the expression using JSONPath.
*/
public class PayloadAccessNode implements ExpressionNode {

private String expression;
private final String unProcessedExpression;
private final Map<String, ExpressionNode> arguments;

Expand All @@ -73,14 +64,12 @@ public PayloadAccessNode(String expression, Map<String, ExpressionNode> argument
this.arguments = arguments;
this.type = type;
this.predefinedFunctionNode = predefinedFunctionNode;

}

@Override
public ExpressionResult evaluate(EvaluationContext context, boolean isObjectValue) throws EvaluationException {
// Take a copy of the expression to avoid modifying the original expression
String expression = unProcessedExpression;

if (expression.startsWith(ExpressionConstants.PAYLOAD)) {
expression = ExpressionConstants.PAYLOAD_$ + expression.substring(ExpressionConstants.PAYLOAD.length());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ private ExpressionResult handleAbsFunction(ExpressionResult result) {
if (result.isInteger()) {
return new ExpressionResult(Math.abs(result.asInt()));
} else if (result.isDouble()) {
return new ExpressionResult(result.asDouble().abs());
return new ExpressionResult(Math.abs(result.asDouble()));
}
throw new EvaluationException("Invalid argument provided for abs function");
}
Expand All @@ -260,7 +260,7 @@ private ExpressionResult handleCeilFunction(ExpressionResult result) {
if (result.isInteger()) {
return new ExpressionResult(result.asInt());
} else if (result.isDouble()) {
return new ExpressionResult(result.asDouble().setScale(0, RoundingMode.CEILING));
return new ExpressionResult(Math.ceil(result.asDouble()));
}
throw new EvaluationException("Invalid argument provided for ceil function");
}
Expand All @@ -269,14 +269,14 @@ private ExpressionResult handleFloorFunction(ExpressionResult result) {
if (result.isInteger()) {
return new ExpressionResult(result.asInt());
} else if (result.isDouble()) {
return new ExpressionResult(result.asDouble().setScale(0, RoundingMode.FLOOR));
return new ExpressionResult(Math.floor(result.asDouble()));
}
throw new EvaluationException("Invalid argument provided for floor function");
}

private ExpressionResult handleRoundFunction(ExpressionResult result) {
if (result.isDouble()) {
return new ExpressionResult((int) Math.round(result.asDouble().doubleValue()));
return new ExpressionResult((int) Math.round(result.asDouble()));
} else if (result.isInteger()) {
return new ExpressionResult(result.asInt());
}
Expand All @@ -285,7 +285,7 @@ private ExpressionResult handleRoundFunction(ExpressionResult result) {

private ExpressionResult handleRoundFunction(ExpressionResult result, ExpressionResult decimalPlaces) {
if (result.isDouble() && decimalPlaces.isInteger() && decimalPlaces.asInt() > 0) {
return new ExpressionResult(ExpressionUtils.round(result.asDouble().doubleValue(), decimalPlaces.asInt()));
return new ExpressionResult(ExpressionUtils.round(result.asDouble(), decimalPlaces.asInt()));
} else if (result.isInteger() || result.isLong()) {
return result;
}
Expand All @@ -296,7 +296,7 @@ private ExpressionResult handleSqrtFunction(ExpressionResult result) {
if (result.isInteger()) {
return new ExpressionResult(Math.sqrt(result.asInt()));
} else if (result.isDouble()) {
return new ExpressionResult(Math.sqrt(result.asDouble().doubleValue()));
return new ExpressionResult(Math.sqrt(result.asDouble()));
}
throw new EvaluationException("Invalid argument provided for sqrt function");
}
Expand Down Expand Up @@ -504,7 +504,7 @@ private ExpressionResult handleCharAtFunction(ExpressionResult source, Expressio

private ExpressionResult handlePowFunction(ExpressionResult source, ExpressionResult argument1) {
if ((source.isDouble() || source.isInteger()) && (argument1.isDouble() || argument1.isInteger())) {
return new ExpressionResult(Math.pow(source.asDouble().doubleValue(), argument1.asDouble().doubleValue()));
return new ExpressionResult(Math.pow(source.asDouble(), argument1.asDouble()));
}
throw new EvaluationException("Invalid argument provided for pow function. source: " + source.asString()
+ ", argument1: " + argument1.asString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

import org.apache.synapse.util.synapse.expression.context.EvaluationContext;

import java.math.BigDecimal;

/**
* Represents a node in the AST that holds a signed expression. ex: ( -vars.num1 )
*/
Expand All @@ -43,7 +41,7 @@ public ExpressionResult evaluate(EvaluationContext context, boolean isObjectValu
if (result.isInteger()) {
return new ExpressionResult(-result.asInt());
} else if (result.isDouble()) {
return new ExpressionResult(result.asDouble().multiply(BigDecimal.valueOf(-1)));
return new ExpressionResult(-result.asDouble());
}
throw new IllegalStateException("Cannot negate a non-numeric value : " + result.asString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,19 @@ public void testAbs() {

@Test
public void testFloor() {
Assert.assertEquals("-6", TestUtils.evaluateExpression("floor(-5.4)"));
Assert.assertEquals("5", TestUtils.evaluateExpression("floor(5.9)"));
Assert.assertEquals("-3", TestUtils.evaluateExpressionWithPayloadAndVariables("floor(vars.num3)", 0, 1));
Assert.assertEquals("2", TestUtils.evaluateExpressionWithPayloadAndVariables("floor(-1 * vars.num3)", 0, 1));
Assert.assertEquals("-6.0", TestUtils.evaluateExpression("floor(-5.4)"));
Assert.assertEquals("5.0", TestUtils.evaluateExpression("floor(5.9)"));
Assert.assertEquals("-3.0", TestUtils.evaluateExpressionWithPayloadAndVariables("floor(vars.num3)", 0, 1));
Assert.assertEquals("2.0", TestUtils.evaluateExpressionWithPayloadAndVariables("floor(-1 * vars.num3)", 0, 1));
Assert.assertEquals("", TestUtils.evaluateExpressionWithPayload("floor(payload.cars)", 1));
}

@Test
public void testCeil() {
Assert.assertEquals("-5", TestUtils.evaluateExpression("ceil(-5.4)"));
Assert.assertEquals("6", TestUtils.evaluateExpression("ceil(5.9)"));
Assert.assertEquals("-2", TestUtils.evaluateExpressionWithPayloadAndVariables("ceil(vars.num3)", 0, 1));
Assert.assertEquals("3", TestUtils.evaluateExpressionWithPayloadAndVariables("ceil(-1 * vars.num3)", 0, 1));
Assert.assertEquals("-5.0", TestUtils.evaluateExpression("ceil(-5.4)"));
Assert.assertEquals("6.0", TestUtils.evaluateExpression("ceil(5.9)"));
Assert.assertEquals("-2.0", TestUtils.evaluateExpressionWithPayloadAndVariables("ceil(vars.num3)", 0, 1));
Assert.assertEquals("3.0", TestUtils.evaluateExpressionWithPayloadAndVariables("ceil(-1 * vars.num3)", 0, 1));
Assert.assertEquals("", TestUtils.evaluateExpressionWithPayload("ceil(payload.cars)", 1));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void testSubtract() {

@Test
public void testMultiply() {
Assert.assertEquals("75.600", TestUtils.evaluateExpression("72.0 * 1.05"));
Assert.assertEquals("74.31444", TestUtils.evaluateExpression("72.0 * 1.032145"));
Assert.assertEquals("80.8201", TestUtils.evaluateExpression("8.99 * 8.99"));
Assert.assertEquals("26.25", TestUtils.evaluateExpression("25 * 1.05"));
Assert.assertEquals("25.025", TestUtils.evaluateExpression("25 * 1.001"));
Expand Down

0 comments on commit 28ce3ef

Please sign in to comment.