diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java index 7d0b61c69..7d3566824 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java @@ -496,10 +496,10 @@ public class ODataBinderImpl implements ODataBinder { inlineEntitySet))); } - private EdmEntityType findEntityType( + private EdmType findEntityType( final String entitySetOrSingletonOrType, final EdmEntityContainer container) { - EdmEntityType type = null; + EdmType type = null; final String firstToken = StringUtils.substringBefore(entitySetOrSingletonOrType, "/"); EdmBindingTarget bindingTarget = container.getEntitySet(firstToken); @@ -514,9 +514,14 @@ public class ODataBinderImpl implements ODataBinder { final String[] splitted = entitySetOrSingletonOrType.split("/"); if (splitted.length > 1) { for (int i = 1; i < splitted.length && type != null; i++) { - final EdmNavigationProperty navProp = type.getNavigationProperty(splitted[i]); + final EdmNavigationProperty navProp = ((EdmStructuredType) type).getNavigationProperty(splitted[i]); if (navProp == null) { - type = null; + EdmProperty property = ((EdmStructuredType) type).getStructuralProperty(splitted[i]); + if (property != null) { + type = property.getType(); + } else { + type = null; + } } else { type = navProp.getType(); } @@ -548,17 +553,17 @@ public class ODataBinderImpl implements ODataBinder { for (EdmSchema schema : edm.getSchemas()) { final EdmEntityContainer container = schema.getEntityContainer(); if (container != null) { - final EdmEntityType entityType = findEntityType(contextURL.getEntitySetOrSingletonOrType(), container); + final EdmType structuredType = findEntityType(contextURL.getEntitySetOrSingletonOrType(), container); - if (entityType != null) { + if (structuredType != null) { if (contextURL.getNavOrPropertyPath() == null) { - type = entityType; + type = structuredType; } else { final EdmNavigationProperty navProp = - entityType.getNavigationProperty(contextURL.getNavOrPropertyPath()); + ((EdmStructuredType) structuredType).getNavigationProperty(contextURL.getNavOrPropertyPath()); type = navProp == null - ? entityType + ? structuredType : navProp.getType(); } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java index b968c5f9d..6ea256b0a 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntitySetTest.java @@ -26,16 +26,39 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; +import org.apache.olingo.client.api.EdmEnabledODataClient; import org.apache.olingo.client.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientEntitySet; import org.apache.olingo.client.api.serialization.ODataDeserializerException; import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.format.ContentType; import org.junit.Test; public class EntitySetTest extends AbstractTest { +private EdmEnabledODataClient getEdmEnabledClient1() { + return new EdmEnabledODataClientImpl(null, null, null) { + + private Edm edm; + + @Override + public Edm getEdm(final String metadataETag) { + return getCachedEdm(); + } + + @Override + public Edm getCachedEdm() { + if (edm == null) { + edm = getReader().readMetadata(getClass().getResourceAsStream("metadata_sample.xml")); + } + return edm; + } + + }; + } + private void read(final ContentType contentType) throws IOException, ODataDeserializerException { final InputStream input = getClass().getResourceAsStream("Customers." + getSuffix(contentType)); final ClientEntitySet entitySet = client.getBinder().getODataEntitySet( @@ -102,4 +125,32 @@ public class EntitySetTest extends AbstractTest { public void jsonRef() throws Exception { ref(ContentType.JSON); } + + @Test + public void testContainmentNav() throws Exception { + final InputStream input = getClass().getResourceAsStream("containmentNav1." + + getSuffix(ContentType.JSON_FULL_METADATA)); + final ClientEntitySet entity = getEdmEnabledClient1().getBinder(). + getODataEntitySet(client.getDeserializer( + ContentType.JSON_FULL_METADATA).toEntitySet(input)); + assertNotNull(entity); + assertEquals("olingo.odata.test1.ETTwoCont", + entity.getEntities().get(0).getTypeName().getFullQualifiedNameAsString()); + assertEquals("olingo.odata.test1.ETTwoCont", + entity.getEntities().get(1).getTypeName().getFullQualifiedNameAsString()); + } + + @Test + public void testContainmentNavOnSingleton() throws Exception { + final InputStream input = getClass().getResourceAsStream("containmentNav4." + + getSuffix(ContentType.JSON_FULL_METADATA)); + final ClientEntitySet entity = getEdmEnabledClient1().getBinder(). + getODataEntitySet(client.getDeserializer( + ContentType.JSON_FULL_METADATA).toEntitySet(input)); + assertNotNull(entity); + assertEquals("olingo.odata.test1.ETCont", + entity.getEntities().get(0).getTypeName().getFullQualifiedNameAsString()); + assertEquals("olingo.odata.test1.ETCont", + entity.getEntities().get(1).getTypeName().getFullQualifiedNameAsString()); + } } diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java index d80846b39..bc08918e6 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/EntityTest.java @@ -76,6 +76,27 @@ public class EntityTest extends AbstractTest { }; } + + private EdmEnabledODataClient getEdmEnabledClient1() { + return new EdmEnabledODataClientImpl(null, null, null) { + + private Edm edm; + + @Override + public Edm getEdm(final String metadataETag) { + return getCachedEdm(); + } + + @Override + public Edm getCachedEdm() { + if (edm == null) { + edm = getReader().readMetadata(getClass().getResourceAsStream("metadata_sample.xml")); + } + return edm; + } + + }; + } private void singleton(final ContentType contentType) throws Exception { final InputStream input = getClass().getResourceAsStream("VipCustomer." + getSuffix(contentType)); @@ -404,4 +425,34 @@ public class EntityTest extends AbstractTest { assertTrue(property.isPrimitive()); assertEquals(property.getValueType(), ValueType.PRIMITIVE); } + + @Test + public void testContainmentNav() throws Exception { + final InputStream input = getClass().getResourceAsStream( + "containmentNav." + getSuffix(ContentType.JSON_FULL_METADATA)); + final ClientEntity entity = getEdmEnabledClient1().getBinder().getODataEntity( + client.getDeserializer(ContentType.JSON_FULL_METADATA).toEntity(input)); + assertNotNull(entity); + assertEquals("olingo.odata.test1.ETCont", entity.getTypeName().getFullQualifiedNameAsString()); + } + + @Test + public void testContainmentNavOnComplexType() throws Exception { + final InputStream input = getClass().getResourceAsStream( + "containmentNav2." + getSuffix(ContentType.JSON_FULL_METADATA)); + final ClientEntity entity = getEdmEnabledClient1().getBinder().getODataEntity( + client.getDeserializer(ContentType.JSON_FULL_METADATA).toEntity(input)); + assertNotNull(entity); + assertEquals("olingo.odata.test1.ETCont", entity.getTypeName().getFullQualifiedNameAsString()); + } + + @Test + public void testContainmentNavOnSingleton() throws Exception { + final InputStream input = getClass().getResourceAsStream( + "containmentNav3." + getSuffix(ContentType.JSON_FULL_METADATA)); + final ClientEntity entity = getEdmEnabledClient1().getBinder().getODataEntity( + client.getDeserializer(ContentType.JSON_FULL_METADATA).toEntity(input)); + assertNotNull(entity); + assertEquals("olingo.odata.test1.ETCont", entity.getTypeName().getFullQualifiedNameAsString()); + } } diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav.json new file mode 100644 index 000000000..b86416310 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav.json @@ -0,0 +1,33 @@ +{ + "@odata.context": "../../$metadata#ESKeyNavCont(-32766)/NavPropertyETBaseContMany(-32768)/olingo.odata.test1.ETCont/$entity", + "@odata.metadataEtag": "W/\"c32f78fd-8c2d-44a1-a602-2c6527d44930\"", + "PropertyInt16@odata.type": "#Int16", + "PropertyInt16": -32768, + "PropertyString": "Second Resource - negative values", + "PropertyInt32@odata.type": "#Int32", + "PropertyInt32": -2147483648, + "PropertyInt64@odata.type": "#Int64", + "PropertyInt64": -9223372036854775808, + "PropertySingle@odata.type": "#Single", + "PropertySingle": -179000000, + "PropertyDouble": -179000, + "PropertyDecimal@odata.type": "#Decimal", + "PropertyDecimal": -34, + "PropertyBinary@odata.type": "#Binary", + "PropertyBinary": "ASNFZ4mrze8=", + "PropertyDate@odata.type": "#Date", + "PropertyDate": "2015-11-05", + "PropertyDateTimeOffset@odata.type": "#DateTimeOffset", + "PropertyDateTimeOffset": "2005-12-03T07:17:08Z", + "PropertyDuration@odata.type": "#Duration", + "PropertyDuration": "PT9S", + "PropertyGuid@odata.type": "#Guid", + "PropertyGuid": "76543201-23ab-cdef-0123-456789dddfff", + "PropertyTimeOfDay@odata.type": "#TimeOfDay", + "PropertyTimeOfDay": "23:49:14", + "PropertyBoolean": false, + "PropertyByte@odata.type": "#Byte", + "PropertyByte": 0, + "PropertySByte@odata.type": "#SByte", + "PropertySByte": -128 +} \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav1.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav1.json new file mode 100644 index 000000000..f752e0dfe --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav1.json @@ -0,0 +1,36 @@ +{ + "@odata.context": "../../$metadata#ESKeyNavCont(-32766)/NavPropertyETBaseContMany(0)/NavPropertyETBaseContTwoContMany", + "@odata.metadataEtag": "W/\"c32f78fd-8c2d-44a1-a602-2c6527d44930\"", + "value": [ + { + "PropertyInt16": -32768, + "PropertyString": "Second Resource - negative values", + "PropertyInt32": -2147483648, + "PropertyInt64": -9223372036854775808, + "PropertySingle": -179000000, + "PropertyDouble": -179000, + "PropertyDecimal": -34, + "PropertyBinary": "ASNFZ4mrze8=", + "PropertyDate": "2015-11-05", + "PropertyDateTimeOffset": "2005-12-03T07:17:08Z", + "PropertyDuration": "PT9S", + "PropertyGuid": "76543201-23ab-cdef-0123-456789dddfff", + "PropertyTimeOfDay": "23:49:14" + }, + { + "PropertyInt16": 0, + "PropertyString": "", + "PropertyInt32": 0, + "PropertyInt64": 0, + "PropertySingle": 0, + "PropertyDouble": 0, + "PropertyDecimal": 0, + "PropertyBinary": "", + "PropertyDate": "1970-01-01", + "PropertyDateTimeOffset": "2005-12-03T00:00:00Z", + "PropertyDuration": "PT0S", + "PropertyGuid": "76543201-23ab-cdef-0123-456789cccddd", + "PropertyTimeOfDay": "00:01:01" + } + ] +} \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav2.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav2.json new file mode 100644 index 000000000..bc7113b83 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav2.json @@ -0,0 +1,33 @@ +{ + "@odata.context": "../../$metadata#ESKeyNavCont(-32766)/PropertyCompNavCont/NavPropertyETTwoKeyNavETContOne/$entity", + "@odata.metadataEtag": "W/\"c32f78fd-8c2d-44a1-a602-2c6527d44930\"", + "PropertyInt16@odata.type": "#Int16", + "PropertyInt16": -32768, + "PropertyString": "Second Resource - negative values", + "PropertyInt32@odata.type": "#Int32", + "PropertyInt32": -2147483648, + "PropertyInt64@odata.type": "#Int64", + "PropertyInt64": -9223372036854775808, + "PropertySingle@odata.type": "#Single", + "PropertySingle": -179000000, + "PropertyDouble": -179000, + "PropertyDecimal@odata.type": "#Decimal", + "PropertyDecimal": -34, + "PropertyBinary@odata.type": "#Binary", + "PropertyBinary": "ASNFZ4mrze8=", + "PropertyDate@odata.type": "#Date", + "PropertyDate": "2015-11-05", + "PropertyDateTimeOffset@odata.type": "#DateTimeOffset", + "PropertyDateTimeOffset": "2005-12-03T07:17:08Z", + "PropertyDuration@odata.type": "#Duration", + "PropertyDuration": "PT9S", + "PropertyGuid@odata.type": "#Guid", + "PropertyGuid": "76543201-23ab-cdef-0123-456789dddfff", + "PropertyTimeOfDay@odata.type": "#TimeOfDay", + "PropertyTimeOfDay": "23:49:14", + "PropertyBoolean": false, + "PropertyByte@odata.type": "#Byte", + "PropertyByte": 0, + "PropertySByte@odata.type": "#SByte", + "PropertySByte": -128 +} \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav3.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav3.json new file mode 100644 index 000000000..bd17c0e4c --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav3.json @@ -0,0 +1,33 @@ +{ + "@odata.context": "../../$metadata#SI/PropertyCompNavCont/NavPropertyETTwoKeyNavETContOne/$entity", + "@odata.metadataEtag": "W/\"c32f78fd-8c2d-44a1-a602-2c6527d44930\"", + "PropertyInt16@odata.type": "#Int16", + "PropertyInt16": -32768, + "PropertyString": "Second Resource - negative values", + "PropertyInt32@odata.type": "#Int32", + "PropertyInt32": -2147483648, + "PropertyInt64@odata.type": "#Int64", + "PropertyInt64": -9223372036854775808, + "PropertySingle@odata.type": "#Single", + "PropertySingle": -179000000, + "PropertyDouble": -179000, + "PropertyDecimal@odata.type": "#Decimal", + "PropertyDecimal": -34, + "PropertyBinary@odata.type": "#Binary", + "PropertyBinary": "ASNFZ4mrze8=", + "PropertyDate@odata.type": "#Date", + "PropertyDate": "2015-11-05", + "PropertyDateTimeOffset@odata.type": "#DateTimeOffset", + "PropertyDateTimeOffset": "2005-12-03T07:17:08Z", + "PropertyDuration@odata.type": "#Duration", + "PropertyDuration": "PT9S", + "PropertyGuid@odata.type": "#Guid", + "PropertyGuid": "76543201-23ab-cdef-0123-456789dddfff", + "PropertyTimeOfDay@odata.type": "#TimeOfDay", + "PropertyTimeOfDay": "23:49:14", + "PropertyBoolean": false, + "PropertyByte@odata.type": "#Byte", + "PropertyByte": 0, + "PropertySByte@odata.type": "#SByte", + "PropertySByte": -128 +} \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav4.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav4.json new file mode 100644 index 000000000..d317ef1a6 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/containmentNav4.json @@ -0,0 +1,68 @@ +{ + "@odata.context": "../../$metadata#SI/NavPropertyETContMany", + "@odata.metadataEtag": "W/\"c32f78fd-8c2d-44a1-a602-2c6527d44930\"", + "value": [ + { + "PropertyInt16@odata.type": "#Int16", + "PropertyInt16": -32768, + "PropertyString": "Second Resource - negative values", + "PropertyInt32@odata.type": "#Int32", + "PropertyInt32": -2147483648, + "PropertyInt64@odata.type": "#Int64", + "PropertyInt64": -9223372036854775808, + "PropertySingle@odata.type": "#Single", + "PropertySingle": -179000000, + "PropertyDouble": -179000, + "PropertyDecimal@odata.type": "#Decimal", + "PropertyDecimal": -34, + "PropertyBinary@odata.type": "#Binary", + "PropertyBinary": "ASNFZ4mrze8=", + "PropertyDate@odata.type": "#Date", + "PropertyDate": "2015-11-05", + "PropertyDateTimeOffset@odata.type": "#DateTimeOffset", + "PropertyDateTimeOffset": "2005-12-03T07:17:08Z", + "PropertyDuration@odata.type": "#Duration", + "PropertyDuration": "PT9S", + "PropertyGuid@odata.type": "#Guid", + "PropertyGuid": "76543201-23ab-cdef-0123-456789dddfff", + "PropertyTimeOfDay@odata.type": "#TimeOfDay", + "PropertyTimeOfDay": "23:49:14", + "PropertyBoolean": false, + "PropertyByte@odata.type": "#Byte", + "PropertyByte": 0, + "PropertySByte@odata.type": "#SByte", + "PropertySByte": -128 + }, + { + "PropertyInt16@odata.type": "#Int16", + "PropertyInt16": -365, + "PropertyString": "Second Resource - negative values", + "PropertyInt32@odata.type": "#Int32", + "PropertyInt32": -2147483648, + "PropertyInt64@odata.type": "#Int64", + "PropertyInt64": -9223372036854775808, + "PropertySingle@odata.type": "#Single", + "PropertySingle": -179000000, + "PropertyDouble": -179000, + "PropertyDecimal@odata.type": "#Decimal", + "PropertyDecimal": -34, + "PropertyBinary@odata.type": "#Binary", + "PropertyBinary": "ASNFZ4mrze8=", + "PropertyDate@odata.type": "#Date", + "PropertyDate": "2015-11-05", + "PropertyDateTimeOffset@odata.type": "#DateTimeOffset", + "PropertyDateTimeOffset": "2005-12-03T07:17:08Z", + "PropertyDuration@odata.type": "#Duration", + "PropertyDuration": "PT9S", + "PropertyGuid@odata.type": "#Guid", + "PropertyGuid": "76543201-23ab-cdef-0123-456789dddfff", + "PropertyTimeOfDay@odata.type": "#TimeOfDay", + "PropertyTimeOfDay": "23:49:14", + "PropertyBoolean": false, + "PropertyByte@odata.type": "#Byte", + "PropertyByte": 0, + "PropertySByte@odata.type": "#SByte", + "PropertySByte": -128 + } + ] +} \ No newline at end of file diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/metadata_sample.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/metadata_sample.xml new file mode 100644 index 000000000..4be77abb5 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/metadata_sample.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Contains entities with containment navigation properties + + + + false + + + + + + + \ No newline at end of file