diff --git a/.classpath b/.classpath index ffc75cb..f2e3c82 100644 --- a/.classpath +++ b/.classpath @@ -37,14 +37,6 @@ - - - - - - - - @@ -56,14 +48,5 @@ - - - - - - - - - diff --git a/README.md b/README.md index c9cfd8b..0735609 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The easiest way to use this library is to include it as a dependency in your Mav com.ibm.jsonata4java JSONata4Java - 2.4.8 + 2.4.9 ``` @@ -53,8 +53,8 @@ Note: to build and deploy the jars to Maven Central you need to use a command li `mvn clean install deploy -Prelease` Once you have run the launcher, you can find the jar files in the /target directory. There are two: -* **JSONata4Java-2.4.8-jar-with-dependencies.jar** (thinks includes dependent jar files) -* **JSONata4Java-2.4.8.jar** (only the JSONata4Java code) +* **JSONata4Java-2.4.9-jar-with-dependencies.jar** (thinks includes dependent jar files) +* **JSONata4Java-2.4.9.jar** (only the JSONata4Java code) The com.api.jsonata4java.Tester program enables you to enter an expression and run it against the same JSON as is used at the https://try.jsonata.org site. You can also @@ -72,10 +72,11 @@ methods are not thread-safe. Issue 260 to add support for timeoutMS and maxDepth to the evaluate methods in Expression. -### New Feature for Version 2.4.8 ### -A new function for $fromMillisZoned has been added to allow passing a Timezone string as the 3rd parameter. +### New Feature for Version 2.4.9 ### +The $number function was updated to allow strings with 0x, 0o, 0b prefixes for hexadecimal, octal, and binary conversions. The value returned can handle long values. ### New Feature for Version 2.4 ### +A new function for $fromMillisZoned has been added to allow passing a Timezone string as the 3rd parameter. We support now a simple version of JSONata's Order-by operator (see https://docs.jsonata.org/path-operators#---order-by). ### New Features for Version 2 ### diff --git a/pom.xml b/pom.xml index 791ed72..ce04651 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ 4.0.0 com.ibm.jsonata4java JSONata4Java - 2.4.8 + 2.4.9 JSONata4Java Port of jsonata.js to Java to enable rules for JSON content https://github.com/IBM/JSONata4Java @@ -95,7 +95,7 @@ org.springframework spring-context - 5.3.24 + 5.3.34 test @@ -106,24 +106,24 @@ com.fasterxml.jackson.core jackson-databind - 2.16.1 + 2.17.0 com.fasterxml.woodstox woodstox-core - 6.6.0 + 6.6.2 com.fasterxml.jackson.dataformat jackson-dataformat-xml - 2.16.1 + 2.17.0 org.apache.commons commons-text - 1.11.0 + 1.12.0 diff --git a/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java b/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java index 17c5ef6..fd8b827 100644 --- a/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java +++ b/src/main/java/com/api/jsonata4java/expressions/utils/NumberUtils.java @@ -1,6 +1,6 @@ /** * (c) Copyright 2018, 2019 IBM Corporation - * 1 New Orchard Road, + * 1 New Orchard Road, * Armonk, New York, 10504-1722 * United States * +1 914 499 1900 @@ -19,10 +19,10 @@ * limitations under the License. * */ - package com.api.jsonata4java.expressions.utils; import java.io.Serializable; + import com.api.jsonata4java.expressions.EvaluateRuntimeException; import com.fasterxml.jackson.databind.node.DoubleNode; import com.fasterxml.jackson.databind.node.LongNode; @@ -36,20 +36,19 @@ public class NumberUtils implements Serializable { * The convertNumberToValueNode method converts the string passed in to a * suitable subclass of ValueNode depending on whether it is an integer or * decimal. - * - * For consistency with the JavaScript implementation of JSONata, we limit the - * size of the numbers that we handle to be within the range Double.MAX_VALUE - * and -Double.MAX_VALUE. If we did not do this we would need to implement a lot - * of extra code to handle BigInteger and BigDecimal. - * - * @param number - * The string representation of the number to convert - * @return ValueNode The ValueNode representation of the number contained in the - * input string - * @throws EvaluateRuntimeException - * If the number represented by the string is - * outside of the valid range or if the string - * does not contain a valid number. + * + * For consistency with the JavaScript implementation of JSONata, we limit + * the size of the numbers that we handle to be within the range + * Double.MAX_VALUE and -Double.MAX_VALUE. If we did not do this we would + * need to implement a lot of extra code to handle BigInteger and + * BigDecimal. + * + * @param number The string representation of the number to convert + * @return ValueNode The ValueNode representation of the number contained in + * the input string + * @throws EvaluateRuntimeException If the number represented by the string + * is outside of the valid range or if the string does not contain a valid + * number. */ public static final ValueNode convertNumberToValueNode(String number) { @@ -63,7 +62,7 @@ public static final ValueNode convertNumberToValueNode(String number) { // Check to see if the converted number is within the acceptable range if (!doubleValue.isInfinite() && !doubleValue.isNaN()) { if ((doubleValue >= 0.0d && doubleValue <= Double.valueOf(Long.MAX_VALUE)) - || (doubleValue < 0.0d && doubleValue >= Double.valueOf(Long.MIN_VALUE))) { + || (doubleValue < 0.0d && doubleValue >= Double.valueOf(Long.MIN_VALUE))) { if (doubleValue - doubleValue.longValue() == 0.0d) { result = new LongNode((long) doubleValue.doubleValue()); } else { @@ -77,10 +76,45 @@ public static final ValueNode convertNumberToValueNode(String number) { throw new EvaluateRuntimeException(msg); } } catch (NumberFormatException e2) { + // try conversion for other values + result = convertToNumber(number); + } + + return result; + } + + /** + * Attempts to convert a String based number representation using prefixes + * like 0x (hex), 0o (octal), 0b (binary) + * + * @param number + * @return + */ + public static ValueNode convertToNumber(String number) { + if (number == null) { + final String msg = String.format(Constants.ERR_MSG_UNABLE_TO_CAST_VALUE_TO_NUMBER, number); + throw new EvaluateRuntimeException(msg); + } + number = number.trim().toLowerCase(); + ValueNode result = null; + try { + if (number.startsWith("0x")) { + // Hexadecimal number + result = new LongNode(Long.parseLong(number.substring(2), 16)); + } else if (number.startsWith("0o")) { + // Octal number + result = new LongNode(Long.parseLong(number.substring(2), 8)); + } else if (number.startsWith("0b")) { + // Binary number + result = new LongNode(Long.parseLong(number.substring(2), 2)); + } else { + // Decimal number or invalid format + result = new LongNode(Long.parseLong(number)); + } + } catch (Exception e) { final String msg = String.format(Constants.ERR_MSG_UNABLE_TO_CAST_VALUE_TO_NUMBER, number); throw new EvaluateRuntimeException(msg); } - return result; } } diff --git a/tester.sh b/tester.sh index f62f6c5..5f7d8ee 100755 --- a/tester.sh +++ b/tester.sh @@ -1,2 +1,2 @@ #! /bin/bash -java -cp target/JSONata4Java-2.4.8-jar-with-dependencies.jar com.api.jsonata4java.Tester $1 +java -cp target/JSONata4Java-2.4.9-jar-with-dependencies.jar com.api.jsonata4java.Tester $1 diff --git a/testerui.cmd b/testerui.cmd index 0193db8..d90f151 100644 --- a/testerui.cmd +++ b/testerui.cmd @@ -1 +1 @@ -java -cp target/JSONata4Java-2.4.8-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI +java -cp target/JSONata4Java-2.4.9-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI diff --git a/testerui.sh b/testerui.sh index 3bd3775..7858210 100755 --- a/testerui.sh +++ b/testerui.sh @@ -1,2 +1,2 @@ #! /bin/bash -java -cp target/JSONata4Java-2.4.8-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI +java -cp target/JSONata4Java-2.4.9-jar-with-dependencies.jar com.api.jsonata4java.testerui.TesterUI