From 6a800beee37f10aa5c21087a2c213bd9a6996e10 Mon Sep 17 00:00:00 2001 From: mibo Date: Sun, 24 Sep 2023 07:14:21 +0200 Subject: [PATCH] [OLINGO-1568] Add handling of special case precision/scale --- .../core/domain/ClientPrimitiveValueImpl.java | 6 +++- .../core/serialization/JsonSerializer.java | 12 +++++--- .../client/core/PrimitiveValueTest.java | 13 +++++++++ .../serialization/JsonSerializerTest.java | 28 +++++++++++++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java index d421268638..04a6063d32 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/domain/ClientPrimitiveValueImpl.java @@ -206,12 +206,16 @@ public String toString() { return value.toString(); } else { try { - // TODO: set facets Integer precision = Constants.DEFAULT_PRECISION; Integer scale = Constants.DEFAULT_SCALE; if (typeKind.equals(EdmPrimitiveTypeKind.Decimal) && value instanceof BigDecimal) { precision = ((BigDecimal) value).precision(); scale = ((BigDecimal) value).scale(); + if (precision == 0) { + precision = null; + } else if (scale > precision) { + precision = scale; + } } return type.valueToString(value, null, null, precision, scale, null); } catch (EdmPrimitiveTypeException e) { diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java index f13e87284e..50f09c575b 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java @@ -296,16 +296,20 @@ protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo typeIn jgen.writeString(value.toString()); // This might not be valid OData. } } else { - // TODO: add facets - Integer precesion = Constants.DEFAULT_PRECISION; + Integer precision = Constants.DEFAULT_PRECISION; Integer scale = Constants.DEFAULT_SCALE; if(kind == EdmPrimitiveTypeKind.Decimal && value instanceof BigDecimal){ BigDecimal bigDecimal = (BigDecimal)value; - precesion = bigDecimal.precision(); + precision = bigDecimal.precision(); scale = bigDecimal.scale(); + if (precision == 0) { + precision = null; + } else if (scale > precision) { + precision = scale; + } } final String serialized = EdmPrimitiveTypeFactory.getInstance(kind) - .valueToString(value, null, null, precesion, scale, null); + .valueToString(value, null, null, precision, scale, null); if (isIEEE754Compatible && (kind == EdmPrimitiveTypeKind.Int64 || kind == EdmPrimitiveTypeKind.Decimal) || !NUMBER_TYPES.contains(kind)) { diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java index 3c31b551a5..bcd4ae5fd2 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/PrimitiveValueTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; +import java.math.BigDecimal; import java.util.Calendar; import org.apache.olingo.client.api.domain.ClientValue; @@ -64,4 +65,16 @@ public void Date() throws EdmPrimitiveTypeException { assertEquals("2013-01-10", value.asPrimitive().toString()); } + + @Test + public void testBigDecimalToStringConversion() throws EdmPrimitiveTypeException { + final ClientValue leadingZerosDecimalValue = client.getObjectFactory().newPrimitiveValueBuilder() + .setType(EdmPrimitiveTypeKind.Decimal).setValue(new BigDecimal("0.01")).build(); + final ClientValue arbitraryPrecisionDecimalValue = client.getObjectFactory().newPrimitiveValueBuilder() + .setType(EdmPrimitiveTypeKind.Decimal).setValue(new BigDecimal(0.01)).build(); + + assertEquals("0.01", leadingZerosDecimalValue.asPrimitive().toString()); + assertEquals("0.01000000000000000020816681711721685132943093776702880859375", + arbitraryPrecisionDecimalValue.asPrimitive().toString()); + } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/JsonSerializerTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/JsonSerializerTest.java index 99f026d4b5..057c1d85f2 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/JsonSerializerTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/serialization/JsonSerializerTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertThat; import java.io.StringWriter; +import java.math.BigDecimal; import org.apache.olingo.client.api.ODataClient; import org.apache.olingo.client.api.domain.ClientEntity; @@ -66,6 +67,33 @@ public void testClientEntityJSONWithNull() throws ODataSerializerException { JsonSerializer jsonSerializer = new JsonSerializer(false, ContentType.JSON_FULL_METADATA); + StringWriter writer = new StringWriter(); + jsonSerializer.write(writer, odataClient.getBinder().getEntity(clientEntity)); + assertThat(writer.toString(), is(expectedJson)); + } + @Test + public void testClientEntityJSONWithBigDecimal() throws ODataSerializerException { + String expectedJson = "{\"@odata.type\":\"#test.testClientEntity\"," + + "\"testLeadingZerosDecimal@odata.type\":\"Decimal\"," + + "\"testLeadingZerosDecimal\":0.01," + + "\"testArbitraryPrecisionDecimal@odata.type\":\"Decimal\"," + + "\"testArbitraryPrecisionDecimal\":0.01000000000000000020816681711721685132943093776702880859375}"; + + ODataClient odataClient = ODataClientFactory.getClient(); + ClientObjectFactory objFactory = odataClient.getObjectFactory(); + ClientEntity clientEntity = objFactory.newEntity(new FullQualifiedName("test", "testClientEntity")); + + clientEntity.getProperties().add( + objFactory.newPrimitiveProperty( + "testLeadingZerosDecimal", + objFactory.newPrimitiveValueBuilder().buildDecimal(new BigDecimal("0.01")))); + clientEntity.getProperties().add( + objFactory.newPrimitiveProperty( + "testArbitraryPrecisionDecimal", + objFactory.newPrimitiveValueBuilder().buildDecimal(new BigDecimal(0.01)))); + + JsonSerializer jsonSerializer = new JsonSerializer(false, ContentType.JSON_FULL_METADATA); + StringWriter writer = new StringWriter(); jsonSerializer.write(writer, odataClient.getBinder().getEntity(clientEntity)); assertThat(writer.toString(), is(expectedJson));