Add lossless narrowing convertion (#379)
diff --git a/src/main/java/com/networknt/schema/SchemaValidatorsConfig.java b/src/main/java/com/networknt/schema/SchemaValidatorsConfig.java
index 9f91d1a..2fa9899 100644
--- a/src/main/java/com/networknt/schema/SchemaValidatorsConfig.java
+++ b/src/main/java/com/networknt/schema/SchemaValidatorsConfig.java
@@ -43,6 +43,11 @@
private boolean javaSemantics;
/**
+ * When set to true, can interpret round doubles as integers
+ */
+ private boolean losslessNarrowing;
+
+ /**
* Map of public, normally internet accessible schema URLs to alternate locations; this allows for offline
* validation of schemas that refer to public URLs. This is merged with any mappings the {@link JsonSchemaFactory}
* may have been built with.
@@ -192,5 +197,12 @@
public void setCollectorContext(CollectorContext collectorContext) {
this.collectorContext = collectorContext;
}
-
+
+ public boolean isLosslessNarrowing() {
+ return losslessNarrowing;
+ }
+
+ public void setLosslessNarrowing(boolean losslessNarrowing) {
+ this.losslessNarrowing = losslessNarrowing;
+ }
}
diff --git a/src/main/java/com/networknt/schema/TypeFactory.java b/src/main/java/com/networknt/schema/TypeFactory.java
index e3a9645..3e0693d 100644
--- a/src/main/java/com/networknt/schema/TypeFactory.java
+++ b/src/main/java/com/networknt/schema/TypeFactory.java
@@ -74,6 +74,8 @@
if (node.isNumber())
if (config.isJavaSemantics() && node.canConvertToLong() && (node.asText().indexOf('.') == -1))
return JsonType.INTEGER;
+ else if (config.isLosslessNarrowing() && node.asText().endsWith(".0"))
+ return JsonType.INTEGER;
else
return JsonType.NUMBER;
if (node.isBoolean())
diff --git a/src/test/java/com/networknt/schema/TypeFactoryTest.java b/src/test/java/com/networknt/schema/TypeFactoryTest.java
index 01f15ca..a1ab4d5 100755
--- a/src/test/java/com/networknt/schema/TypeFactoryTest.java
+++ b/src/test/java/com/networknt/schema/TypeFactoryTest.java
@@ -50,4 +50,24 @@
getValueNodeType(DecimalNode.valueOf(new BigDecimal(validValue)), schemaValidatorsConfig));
}
}
+
+ @Test
+ public void testWithLosslessNarrowing() {
+ schemaValidatorsConfig.setLosslessNarrowing(true);
+ assertSame(validValue, JsonType.INTEGER,
+ getValueNodeType(DecimalNode.valueOf(new BigDecimal("1.0")), schemaValidatorsConfig));
+
+ assertSame(validValue, JsonType.NUMBER,
+ getValueNodeType(DecimalNode.valueOf(new BigDecimal("1.5")), schemaValidatorsConfig));
+ }
+
+ @Test
+ public void testWithoutLosslessNarrowing() {
+ schemaValidatorsConfig.setLosslessNarrowing(false);
+ assertSame(validValue, JsonType.NUMBER,
+ getValueNodeType(DecimalNode.valueOf(new BigDecimal("1.0")), schemaValidatorsConfig));
+
+ assertSame(validValue, JsonType.NUMBER,
+ getValueNodeType(DecimalNode.valueOf(new BigDecimal("1.5")), schemaValidatorsConfig));
+ }
}