From 58f9ead7f97e07798ce5f4eadd4c1c702cec3999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20M=C3=ADguez=20Garc=C3=ADa?= Date: Wed, 29 Jan 2025 10:19:59 +0100 Subject: [PATCH] [OLINGO-1501] Fix error when OData client receives EdmDateTime or EdmDateTimeOffset values with precision greater than milliseconds --- .../olingo/odata2/core/edm/EdmDateTime.java | 10 ++-- .../odata2/core/edm/EdmDateTimeOffset.java | 2 +- .../odata2/core/edm/EdmSimpleTypeTest.java | 11 ++--- .../ep/consumer/JsonEntryConsumerTest.java | 8 ++-- .../ep/consumer/JsonPropertyConsumerTest.java | 9 ++-- .../ep/consumer/XmlEntityConsumerTest.java | 48 ++++++++----------- .../ep/consumer/XmlPropertyConsumerTest.java | 3 +- 7 files changed, 37 insertions(+), 54 deletions(-) diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java index fdd070230..718a8e618 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTime.java @@ -47,7 +47,7 @@ public static EdmDateTime getInstance() { @Override public Class getDefaultType() { - return Calendar.class; + return Timestamp.class; } @Override @@ -73,6 +73,8 @@ protected T internalValueOfString(final String value, final EdmLiteralKind l dateTimeValue.clear(); dateTimeValue.setTimeInMillis(millis); return returnType.cast(dateTimeValue); + } else if (returnType.isAssignableFrom(Timestamp.class)) { + return returnType.cast(new Timestamp(millis)); } else { throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType)); } @@ -170,11 +172,7 @@ protected String internalValueToString(final T value, final EdmLiteralKind l } if (literalKind == EdmLiteralKind.JSON) { - if (value instanceof Timestamp && ((Timestamp) value).getNanos() % (1000 * 1000) != 0) { - throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value)); - } else { - return "/Date(" + timeInMillis + ")/"; - } + return "/Date(" + timeInMillis + ")/"; } Calendar dateTimeValue = Calendar.getInstance(TimeZone.getTimeZone("GMT")); diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java index 86378a745..9672e0185 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/edm/EdmDateTimeOffset.java @@ -52,7 +52,7 @@ public static EdmDateTimeOffset getInstance() { @Override public Class getDefaultType() { - return Calendar.class; + return Timestamp.class; } @Override diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java index 602d70bc4..0381267a3 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/edm/EdmSimpleTypeTest.java @@ -436,8 +436,8 @@ public void defaultType() throws Exception { assertEquals(byte[].class, EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance().getDefaultType()); assertEquals(Boolean.class, EdmSimpleTypeKind.Boolean.getEdmSimpleTypeInstance().getDefaultType()); assertEquals(Short.class, EdmSimpleTypeKind.Byte.getEdmSimpleTypeInstance().getDefaultType()); - assertEquals(Calendar.class, EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance().getDefaultType()); - assertEquals(Calendar.class, EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance().getDefaultType()); + assertEquals(Timestamp.class, EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance().getDefaultType()); + assertEquals(Timestamp.class, EdmSimpleTypeKind.DateTimeOffset.getEdmSimpleTypeInstance().getDefaultType()); assertEquals(BigDecimal.class, EdmSimpleTypeKind.Decimal.getEdmSimpleTypeInstance().getDefaultType()); assertEquals(Double.class, EdmSimpleTypeKind.Double.getEdmSimpleTypeInstance().getDefaultType()); assertEquals(UUID.class, EdmSimpleTypeKind.Guid.getEdmSimpleTypeInstance().getDefaultType()); @@ -596,8 +596,7 @@ public void valueToStringDateTime() throws Exception { getPrecisionScaleFacets(9, null))); expectErrorInValueToString(instance, timestamp, EdmLiteralKind.DEFAULT, getPrecisionScaleFacets(8, null), EdmSimpleTypeException.VALUE_FACETS_NOT_MATCHED); - expectErrorInValueToString(instance, timestamp, EdmLiteralKind.JSON, null, - EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT); + assertEquals("/Date(0)/", instance.valueToString(timestamp, EdmLiteralKind.JSON, null)); dateTime.add(Calendar.MILLISECOND, -100); expectErrorInValueToString(instance, dateTime, EdmLiteralKind.DEFAULT, getPrecisionScaleFacets(0, null), @@ -1190,8 +1189,6 @@ public void valueOfStringDateTime() throws Exception { getPrecisionScaleFacets(0, null), EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED); expectErrorInValueOfString(instance, "2012-02-29T23:32:02.98700", EdmLiteralKind.DEFAULT, getPrecisionScaleFacets(2, null), EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED); - expectErrorInValueOfString(instance, "2012-02-29T23:32:02.9876", EdmLiteralKind.DEFAULT, null, - EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT); expectErrorInValueOfString(instance, "2012-02-29T23:32:02.", EdmLiteralKind.DEFAULT, null, EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT); expectErrorInValueOfString(instance, "2012-02-29T23:32:02.0000000000", EdmLiteralKind.DEFAULT, null, @@ -1293,8 +1290,6 @@ public void valueOfStringDateTimeOffset() throws Exception { expectErrorInValueOfString(instance, "2012-02-29T23:32:02.9Z", EdmLiteralKind.DEFAULT, getPrecisionScaleFacets(0, null), EdmSimpleTypeException.LITERAL_FACETS_NOT_MATCHED); - expectErrorInValueOfString(instance, "2012-02-29T23:32:02.9876Z", EdmLiteralKind.DEFAULT, null, - EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT); expectErrorInValueOfString(instance, "datetime'2012-02-29T23:32:02'", EdmLiteralKind.URI, null, EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT); expectErrorInValueOfString(instance, "2012-02-29T23:32:02X", EdmLiteralKind.DEFAULT, null, diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java index 145f8f4a4..ffdff9620 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java @@ -25,10 +25,9 @@ import static org.junit.Assert.fail; import java.io.InputStream; -import java.util.Calendar; +import java.sql.Timestamp; import java.util.List; import java.util.Map; -import java.util.TimeZone; import org.apache.olingo.odata2.api.edm.EdmEntitySet; import org.apache.olingo.odata2.api.ep.EntityProviderException; @@ -184,9 +183,8 @@ public void readSimpleEmployeeEntry() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("Employees('1')/$value", properties.get("ImageUrl")); List associationUris = result.getMetadata().getAssociationUris("ne_Manager"); diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java index 6d73fcab6..bd5059cfc 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonPropertyConsumerTest.java @@ -30,6 +30,7 @@ import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; +import java.sql.Timestamp; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; @@ -126,15 +127,15 @@ public void allStringSimplePropertyKinds() throws Exception { JsonReader reader = prepareReader(simplePropertyJson); when(edmProperty.getType()).thenReturn(EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()); Map resultMap = execute(edmProperty, reader); - Calendar entryDate = (Calendar) resultMap.get("Name"); - assertEquals(Long.valueOf(915148800000l), Long.valueOf(entryDate.getTimeInMillis())); + Timestamp entryDate = (Timestamp) resultMap.get("Name"); + assertEquals(Long.valueOf(915148800000l), Long.valueOf(entryDate.getTime())); // DateTimeOffset simplePropertyJson = "{\"d\":{\"Name\":\"\\/Date(915148800000)\\/\"}}"; reader = prepareReader(simplePropertyJson); when(edmProperty.getType()).thenReturn(EdmSimpleTypeKind.DateTime.getEdmSimpleTypeInstance()); resultMap = execute(edmProperty, reader); - entryDate = (Calendar) resultMap.get("Name"); - assertEquals(Long.valueOf(915148800000l), Long.valueOf(entryDate.getTimeInMillis())); + entryDate = (Timestamp) resultMap.get("Name"); + assertEquals(Long.valueOf(915148800000l), Long.valueOf(entryDate.getTime())); // Decimal simplePropertyJson = "{\"d\":{\"Name\":\"123456789\"}}"; reader = prepareReader(simplePropertyJson); diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java index 207815ce4..736c15a7a 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java @@ -25,12 +25,11 @@ import static org.junit.Assert.assertTrue; import java.io.InputStream; -import java.util.Calendar; +import java.sql.Timestamp; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.TimeZone; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; @@ -1855,9 +1854,8 @@ public void testReadFeed() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("Employees('1')/$value", properties.get("ImageUrl")); } @@ -1901,9 +1899,8 @@ public void testReadFeedWithInlineCountAndNextLink() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("Employees('1')/$value", properties.get("ImageUrl")); } @@ -1936,9 +1933,8 @@ public void testReadEntry() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("/SAP/PUBLIC/BC/NWDEMO_MODEL/IMAGES/Employee_1.png", properties.get("ImageUrl")); } @@ -1972,9 +1968,8 @@ public void testReadEntryWithLargeProperty() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("/SAP/PUBLIC/BC/NWDEMO_MODEL/IMAGES/Employee_1.png", properties.get("ImageUrl")); } @@ -2011,9 +2006,8 @@ public void testReadEntryMissingKeyProperty() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("/SAP/PUBLIC/BC/NWDEMO_MODEL/IMAGES/Employee_1.png", properties.get("ImageUrl")); } @@ -2105,9 +2099,8 @@ public void testReadEntryWithMerge() throws Exception { assertEquals(2, city.size()); assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("/SAP/PUBLIC/BC/NWDEMO_MODEL/IMAGES/Employee_1.png", properties.get("ImageUrl")); } @@ -2178,9 +2171,8 @@ public void testReadEntryRequest() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("/SAP/PUBLIC/BC/NWDEMO_MODEL/IMAGES/Employee_1.png", properties.get("ImageUrl")); } @@ -2211,9 +2203,8 @@ public void testReadEntryRequestNullMapping() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("/SAP/PUBLIC/BC/NWDEMO_MODEL/IMAGES/Employee_1.png", properties.get("ImageUrl")); } @@ -2243,9 +2234,8 @@ public void testReadEntryRequestEmptyMapping() throws Exception { assertEquals("69124", city.get("PostalCode")); assertEquals("Heidelberg", city.get("CityName")); assertEquals(Integer.valueOf(52), properties.get("Age")); - Calendar entryDate = (Calendar) properties.get("EntryDate"); - assertEquals(915148800000L, entryDate.getTimeInMillis()); - assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + Timestamp entryDate = (Timestamp) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTime()); assertEquals("/SAP/PUBLIC/BC/NWDEMO_MODEL/IMAGES/Employee_1.png", properties.get("ImageUrl")); } diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java index 367eefda9..3de34bc73 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlPropertyConsumerTest.java @@ -27,6 +27,7 @@ import static org.mockito.Mockito.when; import java.math.BigDecimal; +import java.sql.Timestamp; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; @@ -172,7 +173,7 @@ public void readStringPropertyNullFalse() throws Exception { final Map resultMap = new XmlPropertyConsumer().readProperty(reader, property, null); - assertEquals(86400000L, ((Calendar) resultMap.get("EntryDate")).getTimeInMillis()); + assertEquals(86400000L, ((Timestamp) resultMap.get("EntryDate")).getTime()); } @Test(expected = EntityProviderException.class)