diff --git a/jolt-core/src/main/java/com/bazaarvoice/jolt/Modifier.java b/jolt-core/src/main/java/com/bazaarvoice/jolt/Modifier.java index e334bc72..f4ae3258 100644 --- a/jolt-core/src/main/java/com/bazaarvoice/jolt/Modifier.java +++ b/jolt-core/src/main/java/com/bazaarvoice/jolt/Modifier.java @@ -63,7 +63,7 @@ public abstract class Modifier implements SpecDriven, ContextualTransform { STOCK_FUNCTIONS.put( "longSubtract", new Math.longSubtract() ); STOCK_FUNCTIONS.put( "divide", new Math.divide() ); STOCK_FUNCTIONS.put( "divideAndRound", new Math.divideAndRound() ); - + STOCK_FUNCTIONS.put( "multiply", new Math.multiply() ); STOCK_FUNCTIONS.put( "toInteger", new Objects.toInteger() ); STOCK_FUNCTIONS.put( "toDouble", new Objects.toDouble() ); diff --git a/jolt-core/src/main/java/com/bazaarvoice/jolt/modifier/function/Math.java b/jolt-core/src/main/java/com/bazaarvoice/jolt/modifier/function/Math.java index adec651d..70ba44a1 100644 --- a/jolt-core/src/main/java/com/bazaarvoice/jolt/modifier/function/Math.java +++ b/jolt-core/src/main/java/com/bazaarvoice/jolt/modifier/function/Math.java @@ -324,6 +324,32 @@ public static Optional divideAndRound(List argList, int digitsAf return Optional.empty(); } + + public static Optional multiply(List argList) { + + if ( argList == null || argList.size() != 2 ) { + return Optional.empty(); + } + + Optional numerator = Objects.toNumber(argList.get(0)); + Optional denominator = Objects.toNumber(argList.get(1)); + + if(numerator.isPresent() && denominator.isPresent()) { + + long drLongValue = denominator.get().longValue(); + if(drLongValue == 0) { + return Optional.empty(); + } + + long nrLongValue = numerator.get().longValue(); +// long result = nrLongValue * drLongValue; + long result = java.lang.Math.multiplyExact(nrLongValue, drLongValue); + return Optional.of((int)result); + } + + return Optional.empty(); + } + @SuppressWarnings( "unchecked" ) public static final class max extends Function.BaseFunction { @@ -445,4 +471,14 @@ protected Optional applyList( final List argLongList ) { return (Optional) longSubtract(argLongList); } } + + @SuppressWarnings( "unchecked" ) + public static final class multiply extends Function.ListFunction { + + @Override + protected Optional applyList(List argList) { + return (Optional)multiply(argList); + } + + } } diff --git a/jolt-core/src/test/java/com/bazaarvoice/jolt/modifier/function/MathTest.java b/jolt-core/src/test/java/com/bazaarvoice/jolt/modifier/function/MathTest.java index 1e7c10b8..58e79db3 100644 --- a/jolt-core/src/test/java/com/bazaarvoice/jolt/modifier/function/MathTest.java +++ b/jolt-core/src/test/java/com/bazaarvoice/jolt/modifier/function/MathTest.java @@ -53,6 +53,8 @@ public Iterator getTestCases() { Function DIV_OF = new Math.divide(); Function DIV_AND_ROUND_OF = new Math.divideAndRound(); + + Function MULTIPLY_OF = new Math.multiply(); testCases.add( new Object[] { "max-empty-array", MAX_OF, new Object[] {}, Optional.empty() } ); testCases.add( new Object[] { "max-empty-list", MAX_OF, new ArrayList( ), Optional.empty() } ); @@ -275,7 +277,9 @@ public Iterator getTestCases() { testCases.add( new Object[] { "divAndRound-trailing-precision-array", DIV_AND_ROUND_OF, Arrays.asList(3, 5.0, 2), Optional.of(2.500)}); testCases.add( new Object[] { "divAndRound-no-precision-array", DIV_AND_ROUND_OF, Arrays.asList(0, 5.0, 2), Optional.of(3.0)}); // Round up as >= 0.5 testCases.add( new Object[] { "divAndRound-no-precision-array", DIV_AND_ROUND_OF, Arrays.asList(0, 4.8, 2), Optional.of(2.0)}); // Round down as < 0.5 - + + testCases.add( new Object[] { "multiply-combo-array", MULTIPLY_OF, Arrays.asList(30, 2), Optional.of(60)}); + return testCases.iterator(); } diff --git a/jolt-core/src/test/resources/json/modifier/functions/mathTests.json b/jolt-core/src/test/resources/json/modifier/functions/mathTests.json index 33b988f7..4f2df7ca 100644 --- a/jolt-core/src/test/resources/json/modifier/functions/mathTests.json +++ b/jolt-core/src/test/resources/json/modifier/functions/mathTests.json @@ -61,7 +61,8 @@ "roundedDiv": "=divideAndRound(4, @(1,nr),@(1,dr))", // Round the result to the 4 decimal points // "badArgs1" : "=divide(1,2,3)", // too many params - "badArgs2" : "=divide(1)" // not enough params + "badArgs2" : "=divide(1)", // not enough params + "multiply": "=multiply(@(1,nr),@(1,dr))" }, "data5": { "happyInt": "=intSubtract(@(1,aInt),@(1,bInt))", @@ -114,7 +115,8 @@ "explicit2": 4.0, "value": [5, 2], "nr": 51, - "dr": 13 + "dr": 13, + "multiply":663 }, "data5": { // og data