Repository: olingo-odata4 Updated Branches: refs/heads/master 4a51d1642 -> 32ff14fe7
[OLINGO-1073] Collections with derived complex types wrong odata.type Signed-off-by: Christian Amend <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/32ff14fe Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/32ff14fe Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/32ff14fe Branch: refs/heads/master Commit: 32ff14fe788b5dbd80ffd61c1e83e460427bae9e Parents: 4a51d16 Author: i050510 <[email protected]> Authored: Fri May 5 10:20:56 2017 +0530 Committer: Christian Amend <[email protected]> Committed: Tue May 9 14:37:42 2017 +0200 ---------------------------------------------------------------------- .../olingo/fit/tecsvc/client/BasicITCase.java | 4 +- .../OdataTypesInBaseAndDerivedTypes.json | 4 +- .../core/serialization/AtomDeserializer.java | 18 +- .../core/serialization/AtomSerializer.java | 8 +- .../core/serialization/JsonDeserializer.java | 13 + .../core/serialization/JsonSerializer.java | 4 +- .../core/serialization/ODataBinderImpl.java | 14 +- .../org/apache/olingo/client/core/AtomTest.java | 209 +++++++++++++++++ .../org/apache/olingo/client/core/JSONTest.java | 235 +++++++++++++++++++ .../apache/olingo/client/core/olingo1073.json | 17 ++ .../apache/olingo/client/core/olingo1073_1.json | 66 ++++++ .../apache/olingo/client/core/olingo1073_1.xml | 65 +++++ .../apache/olingo/client/core/olingo1073_2.json | 87 +++++++ .../apache/olingo/client/core/olingo1073_2.xml | 78 ++++++ .../olingo/commons/api/data/ComplexValue.java | 18 ++ 15 files changed, 828 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java index 1e5cce3..3d33ee9 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java @@ -1598,9 +1598,9 @@ public class BasicITCase extends AbstractParamTecSvcITCase { getProperties().size()); assertEquals(1, entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet().getEntities().get(1). getProperties().size()); - assertEquals("olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet(). + assertEquals("#olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet(). getEntities().get(0).getTypeName().toString()); - assertEquals("olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet(). + assertEquals("#olingo.odata.test1.ETBase", entity.getNavigationLinks().get(0).asInlineEntitySet().getEntitySet(). getEntities().get(1).getTypeName().toString()); assertEquals("olingo.odata.test1.ETAllPrim", entity.getTypeName().toString()); } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json ---------------------------------------------------------------------- diff --git a/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json b/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json index 88ae6b5..d64d26c 100644 --- a/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json +++ b/fit/src/test/resources/OdataTypesInBaseAndDerivedTypes.json @@ -20,13 +20,13 @@ "[email protected]": "#Collection(olingo.odata.test1.ETTwoPrim)", "NavPropertyETTwoPrimMany": [ { - "@odata.type": "olingo.odata.test1.ETBase", + "@odata.type": "#olingo.odata.test1.ETBase", "PropertyInt16": -365, "PropertyString": "Test String2", "AdditionalPropertyString_5": "ABC" }, { - "@odata.type": "olingo.odata.test1.ETBase", + "@odata.type": "#olingo.odata.test1.ETBase", "AdditionalPropertyString_5": "ABC" } ] http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java index 0fa1736..6930f87 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomDeserializer.java @@ -94,7 +94,7 @@ public class AtomDeserializer implements ODataDeserializer { protected static final XMLInputFactory FACTORY = new InputFactoryImpl(); private final AtomGeoValueDeserializer geoDeserializer; - + protected XMLEventReader getReader(final InputStream input) throws XMLStreamException { FACTORY.setProperty("javax.xml.stream.isSupportingExternalEntities", false); FACTORY.setProperty("javax.xml.stream.isReplacingEntityReferences", false); @@ -219,6 +219,13 @@ public class AtomDeserializer implements ODataDeserializer { case COMPLEX: final Object complexValue = fromComplexOrEnum(reader, event.asStartElement()); valueType = ValueType.COLLECTION_COMPLEX; + final Attribute typeAttr = event.asStartElement().getAttributeByName(typeQName); + final String typeAttrValue = typeAttr == null ? null : typeAttr.getValue(); + final EdmTypeInfo typeInfoEle = StringUtils.isBlank(typeAttrValue) ? null : + new EdmTypeInfo.Builder().setTypeExpression(typeAttrValue).build(); + if (typeInfoEle != null) { + ((ComplexValue)complexValue).setTypeName(typeInfoEle.external()); + } values.add(complexValue); break; @@ -287,7 +294,7 @@ public class AtomDeserializer implements ODataDeserializer { throws XMLStreamException, EdmPrimitiveTypeException { final Property property = new Property(); - + if (propertyValueQName.equals(start.getName())) { // retrieve name from context final Attribute context = start.getAttributeByName(contextQName); @@ -297,9 +304,8 @@ public class AtomDeserializer implements ODataDeserializer { } else { property.setName(start.getName().getLocalPart()); } - valuable(property, reader, start); - + return property; } @@ -330,6 +336,10 @@ public class AtomDeserializer implements ODataDeserializer { case COMPLEX: final Object complexValue = fromComplexOrEnum(reader, start); + if (typeInfo != null && complexValue instanceof ComplexValue && + start.getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM)) == null) { + ((ComplexValue)complexValue).setTypeName(typeInfo.external()); + } valuable.setValue(complexValue instanceof ComplexValue ? ValueType.COMPLEX : ValueType.ENUM, complexValue); break; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java index ad4a14e..0b8dce7 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/AtomSerializer.java @@ -127,6 +127,12 @@ public class AtomSerializer implements ODataSerializer { collection(writer, valueType.getBaseType(), kind, (List<?>) value); break; case COMPLEX: + if (((ComplexValue) value).getTypeName() != null) { + EdmTypeInfo typeInfo = new EdmTypeInfo.Builder(). + setTypeExpression(((ComplexValue) value).getTypeName()).build(); + writer.writeAttribute(Constants.PREFIX_METADATA, Constants.NS_METADATA, + Constants.ATTR_TYPE, typeInfo.external()); + } for (Property property : ((ComplexValue) value).getValue()) { property(writer, property, false); } @@ -148,7 +154,7 @@ public class AtomSerializer implements ODataSerializer { } EdmTypeInfo typeInfo = null; - if (property.getType() != null) { + if (property.getType() != null && !property.getValueType().name().equalsIgnoreCase("COMPLEX")) { typeInfo = new EdmTypeInfo.Builder().setTypeExpression(property.getType()).build(); if (!EdmPrimitiveTypeKind.String.getFullQualifiedName().toString().equals(typeInfo.internal())) { writer.writeAttribute(Constants.PREFIX_METADATA, Constants.NS_METADATA, http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java index 3e06443..ec896bb 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonDeserializer.java @@ -333,7 +333,17 @@ public class JsonDeserializer implements ODataDeserializer { values.add(child.asText()); } } else if (child.isContainerNode()) { + EdmTypeInfo childType = null; + if (child.has(Constants.JSON_TYPE)) { + String typeName = child.get(Constants.JSON_TYPE).asText(); + childType = typeName == null ? null + : new EdmTypeInfo.Builder().setTypeExpression(typeName).build(); + ((ObjectNode) child).remove(Constants.JSON_TYPE); + } final Object value = fromComplex((ObjectNode) child, codec); + if (childType != null) { + ((ComplexValue)value).setTypeName(childType.external()); + } valueType = ValueType.COLLECTION_COMPLEX; values.add(value); } @@ -368,6 +378,9 @@ public class JsonDeserializer implements ODataDeserializer { ((ObjectNode) node).remove(Constants.JSON_TYPE); } final Object value = fromComplex((ObjectNode) node, codec); + if (value instanceof ComplexValue) { + ((ComplexValue)value).setTypeName(valuable.getType()); + } valuable.setValue(ValueType.COMPLEX, value); break; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/JsonSerializer.java ---------------------------------------------------------------------- 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 44a51d9..90aba4f 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 @@ -241,7 +241,7 @@ public class JsonSerializer implements ODataSerializer { final ValueType valueType, final List<?> value) throws IOException, EdmPrimitiveTypeException { - final EdmTypeInfo itemTypeInfo = typeInfo == null ? + EdmTypeInfo itemTypeInfo = typeInfo == null ? null : new EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build(); @@ -265,6 +265,8 @@ public class JsonSerializer implements ODataSerializer { case COLLECTION_COMPLEX: final ComplexValue complexItem2 = (ComplexValue) item; + itemTypeInfo = complexItem2.getTypeName() == null ? + itemTypeInfo : new EdmTypeInfo.Builder().setTypeExpression(complexItem2.getTypeName()).build(); complexValue(jgen, itemTypeInfo, complexItem2.getValue(), complexItem2); break; http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataBinderImpl.java ---------------------------------------------------------------------- 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 77764a5..deb58fa 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 @@ -350,6 +350,7 @@ public class ODataBinderImpl implements ODataBinder { lcValueResource.getValue().addAll(complexProperties); annotations(value.asComplex(), lcValueResource); links(value.asComplex(), lcValueResource); + lcValueResource.setTypeName(value.asComplex().getTypeName()); valueResource = lcValueResource; } else if (value.isCollection()) { @@ -581,7 +582,11 @@ public class ODataBinderImpl implements ODataBinder { EntityCollection inlineEntitySet = new EntityCollection(); for (final Object inlined : property.asCollection()) { Entity inlineEntity = new Entity(); - inlineEntity.setType(propertyTypeName); + if (inlined instanceof ComplexValue && ((ComplexValue) inlined).getTypeName() != null) { + inlineEntity.setType(((ComplexValue) inlined).getTypeName()); + } else { + inlineEntity.setType(propertyTypeName); + } inlineEntity.getProperties().addAll(((ComplexValue) inlined).getValue()); copyAnnotations(inlineEntity, (ComplexValue) inlined); inlineEntitySet.getEntities().add(inlineEntity); @@ -815,7 +820,7 @@ public class ODataBinderImpl implements ODataBinder { return property; } - protected ClientValue getODataValue(final FullQualifiedName type, + protected ClientValue getODataValue(FullQualifiedName type, final Valuable valuable, final URI contextURL, final String metadataETag) { // fixes enum values treated as primitive when no type information is available @@ -834,6 +839,11 @@ public class ODataBinderImpl implements ODataBinder { for (Object _value : valuable.asCollection()) { final Property fake = new Property(); fake.setValue(valuable.getValueType().getBaseType(), _value); + String typeName = null; + if (_value instanceof ComplexValue) { + typeName = ((ComplexValue) _value).getTypeName(); + type = typeName == null? type : new FullQualifiedName(typeName); + } value.asCollection().add(getODataValue(type, fake, contextURL, metadataETag)); } } else if (valuable.isEnum()) { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java index ba20144..8f70768 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/AtomTest.java @@ -18,10 +18,14 @@ */ package org.apache.olingo.client.core; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.io.StringWriter; +import java.net.URI; import javax.xml.transform.Source; import javax.xml.transform.Transformer; @@ -30,8 +34,18 @@ import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.apache.commons.io.IOUtils; +import org.apache.olingo.client.api.data.ResWrap; +import org.apache.olingo.client.api.domain.ClientCollectionValue; +import org.apache.olingo.client.api.domain.ClientComplexValue; +import org.apache.olingo.client.api.domain.ClientEntity; +import org.apache.olingo.client.api.domain.ClientValue; +import org.apache.olingo.client.core.serialization.AtomDeserializer; +import org.apache.olingo.commons.api.data.ComplexValue; +import org.apache.olingo.commons.api.data.Entity; +import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ContentType; import org.custommonkey.xmlunit.Diff; +import org.junit.Test; public class AtomTest extends JSONTest { @@ -72,4 +86,199 @@ public class AtomTest extends JSONTest { // no test } + @Test + public void issue1OLINGO1073() throws Exception { + final ClientEntity message = client.getObjectFactory(). + newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person")); + + final ClientComplexValue cityComplexType = getCityComplexType(); + + final ClientComplexValue locationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln."))); + locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue eventLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation"); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue airportLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation"); + airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123."))); + airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory(). + newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + collectionAddressInfo.add(locationComplexType); + collectionAddressInfo.add(eventLocationComplexType); + collectionAddressInfo.add(airportLocationComplexType); + + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte"))); + + final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory(). + newCollectionValue("String"); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue)); + + message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo)); + message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", + client.getObjectFactory().newEnumValue( + "Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747")))); + message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + message.setETag("W/\"08D491CCBE417AAB\""); + message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + + String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.APPLICATION_ATOM_XML)); + actual = actual.substring(actual.indexOf("<entry")); + assertNotNull(actual); + String expected = IOUtils.toString(getClass().getResourceAsStream("olingo1073_1.xml")); + expected = expected.substring(expected.indexOf("<entry")); + expected = expected.trim().replace("\n", "").replace("\r", "").replace("\t", ""); + assertEquals(expected, actual); + } + + + /** + * @return ClientComplexValue + */ + private ClientComplexValue getCityComplexType() { + final ClientComplexValue cityComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.City"); + cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("CountryRegion", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("United States"))); + cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Name", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Boise"))); + cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Region", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("ID"))); + return cityComplexType; + } + + @Test + public void issue2OLINGO1073() throws Exception { + final ClientEntity message = client.getObjectFactory(). + newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person")); + + final ClientComplexValue cityComplexType = getCityComplexType(); + + final ClientComplexValue locationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln."))); + locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue eventLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation"); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue airportLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation"); + airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123."))); + airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory(). + newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + collectionAddressInfo.add(locationComplexType); + collectionAddressInfo.add(eventLocationComplexType); + collectionAddressInfo.add(airportLocationComplexType); + + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte"))); + + final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory(). + newCollectionValue("String"); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue)); + + message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo)); + message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", + client.getObjectFactory().newEnumValue( + "Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747")))); + message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + message.setETag("W/\"08D491CCBE417AAB\""); + message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + + InputStream inputStream = client.getWriter().writeEntity(message, ContentType.APPLICATION_ATOM_XML); + ResWrap<Entity> entity = new AtomDeserializer().toEntity(inputStream); + assertNotNull(entity); + assertEquals(7, entity.getPayload().getProperties().size()); + assertEquals(3, entity.getPayload().getProperty("AddressInfo").asCollection().size()); + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", + ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(0)).getTypeName()); + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", + ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(1)).getTypeName()); + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", + ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(2)).getTypeName()); + assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", + entity.getPayload().getProperty("AddressInfo").getType()); + } + + @Test + public void issue3OLINGO1073_WithAnnotations() throws Exception { + InputStream inputStream = getClass().getResourceAsStream( + "olingo1073_2" + "." + getSuffix(ContentType.APPLICATION_ATOM_XML)); + ClientEntity entity = client.getReader().readEntity(inputStream, ContentType.APPLICATION_ATOM_XML); + assertNotNull(entity); + assertEquals(7, entity.getProperties().size()); + assertEquals(1, entity.getAnnotations().size()); + assertEquals("com.contoso.PersonalInfo.PhoneNumbers", entity.getAnnotations().get(0).getTerm()); + assertEquals(2, entity.getAnnotations().get(0).getCollectionValue().size()); + + assertEquals("com.contoso.display.style", entity.getProperty("LastName"). + getAnnotations().get(0).getTerm()); + assertEquals(2, entity.getProperty("LastName"). + getAnnotations().get(0).getComplexValue().asComplex().asJavaMap().size()); + + assertEquals(3, entity.getProperty("AddressInfo").getCollectionValue().asCollection().size()); + assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", + entity.getProperty("AddressInfo").getCollectionValue().asCollection().getTypeName()); + assertEquals(true, entity.getProperty("AddressInfo").getCollectionValue().isCollection()); + ClientCollectionValue<ClientValue> collectionValue = entity.getProperty("AddressInfo"). + getCollectionValue().asCollection(); + int i = 0; + for (ClientValue _value : collectionValue) { + if (i == 0) { + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", _value.getTypeName()); + assertEquals(2, _value.asComplex().asJavaMap().size()); + assertEquals("Microsoft.OData.SampleService.Models.TripPin.City", + _value.asComplex().get("City").getComplexValue().getTypeName()); + } else if (i == 1) { + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", _value.getTypeName()); + assertEquals(3, _value.asComplex().asJavaMap().size()); + } else if (i == 2) { + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", _value.getTypeName()); + assertEquals(3, _value.asComplex().asJavaMap().size()); + } + i++; + } + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java index a276c4f..caef339 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/JSONTest.java @@ -23,19 +23,25 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; +import java.io.InputStream; import java.io.StringWriter; +import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; +import org.apache.olingo.client.api.data.ResWrap; import org.apache.olingo.client.api.domain.ClientCollectionValue; import org.apache.olingo.client.api.domain.ClientComplexValue; import org.apache.olingo.client.api.domain.ClientEntity; import org.apache.olingo.client.api.domain.ClientValue; +import org.apache.olingo.client.core.serialization.JsonDeserializer; import org.apache.olingo.commons.api.Constants; +import org.apache.olingo.commons.api.data.ComplexValue; import org.apache.olingo.commons.api.data.Delta; +import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ContentType; @@ -247,4 +253,233 @@ public class JSONTest extends AbstractTest { final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new ByteArrayInputStream(actual.getBytes())); assertEquals(expected, actualNode); } + + @Test + public void issue1OLINGO1073() throws Exception { + final ClientEntity message = client.getObjectFactory(). + newEntity(new FullQualifiedName("Microsoft.Exchange.Services.OData.Model.Entity")); + + final ClientComplexValue complType1 = client.getObjectFactory(). + newComplexValue("Microsoft.Exchange.Services.OData.Model.ComplexType1"); + complType1.add(client.getObjectFactory().newPrimitiveProperty("Name1", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client"))); + complType1.add(client.getObjectFactory().newPrimitiveProperty("Address1", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]"))); + + final ClientComplexValue complType2 = client.getObjectFactory(). + newComplexValue("Microsoft.Exchange.Services.OData.Model.ComplexType2"); + complType2.add(client.getObjectFactory().newPrimitiveProperty("Name2", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client"))); + complType2.add(client.getObjectFactory().newPrimitiveProperty("Address2", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]"))); + final ClientCollectionValue<ClientValue> toRecipients = client.getObjectFactory(). + newCollectionValue("Microsoft.Exchange.Services.OData.Model.Recipient"); + toRecipients.add(complType1); + toRecipients.add(complType2); + message.getProperties().add(client.getObjectFactory().newCollectionProperty("ToRecipients", toRecipients)); + + + final String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.JSON)); + final JsonNode expected = + OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream("olingo1073.json")). + replace(Constants.JSON_NAVIGATION_LINK, Constants.JSON_BIND_LINK_SUFFIX)); + final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new ByteArrayInputStream(actual.getBytes())); + assertEquals(expected, actualNode); + } + + @Test + public void issue2OLINGO1073() throws Exception { + final ClientEntity message = client.getObjectFactory(). + newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person")); + + final ClientComplexValue cityComplexType = getCityComplexType(); + + final ClientComplexValue locationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln."))); + locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue eventLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation"); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue airportLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation"); + airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123."))); + airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory(). + newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + collectionAddressInfo.add(locationComplexType); + collectionAddressInfo.add(eventLocationComplexType); + collectionAddressInfo.add(airportLocationComplexType); + + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte"))); + + final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory(). + newCollectionValue("String"); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue)); + + message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo)); + message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", + client.getObjectFactory().newEnumValue("Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747")))); + message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + message.setETag("W/\"08D491CCBE417AAB\""); + message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + + final String actual = IOUtils.toString(client.getWriter().writeEntity(message, ContentType.JSON)); + final JsonNode expected = + OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream("olingo1073_1.json")). + replace(Constants.JSON_NAVIGATION_LINK, Constants.JSON_BIND_LINK_SUFFIX)); + final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new ByteArrayInputStream(actual.getBytes())); + assertEquals(expected, actualNode); + } + + + /** + * @return ClientComplexValue + */ + private ClientComplexValue getCityComplexType() { + final ClientComplexValue cityComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.City"); + cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("CountryRegion", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("United States"))); + cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Name", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Boise"))); + cityComplexType.add(client.getObjectFactory().newPrimitiveProperty("Region", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("ID"))); + return cityComplexType; + } + + @Test + public void issue3OLINGO1073() throws Exception { + final ClientEntity message = client.getObjectFactory(). + newEntity(new FullQualifiedName("Microsoft.OData.SampleService.Models.TripPin.Person")); + + final ClientComplexValue cityComplexType = getCityComplexType(); + + final ClientComplexValue locationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + locationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln."))); + locationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue eventLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.EventLocation"); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("BuildingInfo", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln12."))); + eventLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientComplexValue airportLocationComplexType = client.getObjectFactory(). + newComplexValue("Microsoft.OData.SampleService.Models.TripPin.AirportLocation"); + airportLocationComplexType.add(client.getObjectFactory().newPrimitiveProperty("Address", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("187 Suffolk Ln123."))); + airportLocationComplexType.add(client.getObjectFactory().newComplexProperty("City",cityComplexType)); + + final ClientCollectionValue<ClientValue> collectionAddressInfo = client.getObjectFactory(). + newCollectionValue("Microsoft.OData.SampleService.Models.TripPin.Location"); + collectionAddressInfo.add(locationComplexType); + collectionAddressInfo.add(eventLocationComplexType); + collectionAddressInfo.add(airportLocationComplexType); + + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("UserName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("russellwhyte"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("FirstName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Russell"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("LastName", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Whyte"))); + + final ClientCollectionValue<ClientValue> emailCollectionValue = client.getObjectFactory(). + newCollectionValue("String"); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + emailCollectionValue.add(client.getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")); + message.getProperties().add(client.getObjectFactory().newCollectionProperty("Emails", emailCollectionValue)); + + message.getProperties().add(client.getObjectFactory().newCollectionProperty("AddressInfo", collectionAddressInfo)); + message.getProperties().add(client.getObjectFactory().newEnumProperty("Gender", + client.getObjectFactory().newEnumValue( + "Microsoft.OData.SampleService.Models.TripPin.PersonGender", "Male"))); + message.getProperties().add(client.getObjectFactory().newPrimitiveProperty("Concurrency", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt64(Long.valueOf("636293755917400747")))); + message.setId(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + message.setETag("W/\"08D491CCBE417AAB\""); + message.setEditLink(URI.create("http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/" + + "TripPinServiceRW/People('russellwhyte')")); + + InputStream inputStream = client.getWriter().writeEntity(message, ContentType.APPLICATION_JSON); + ResWrap<Entity> entity = new JsonDeserializer(true).toEntity(inputStream); + assertNotNull(entity); + assertEquals(7, entity.getPayload().getProperties().size()); + assertEquals(3, entity.getPayload().getProperty("AddressInfo").asCollection().size()); + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", + ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(0)).getTypeName()); + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", + ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(1)).getTypeName()); + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", + ((ComplexValue)entity.getPayload().getProperty("AddressInfo").asCollection().get(2)).getTypeName()); + assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", + entity.getPayload().getProperty("AddressInfo").getType()); + } + + @Test + public void issue4OLINGO1073_WithAnnotations() throws Exception { + InputStream inputStream = getClass().getResourceAsStream( + "olingo1073_2" + "." + getSuffix(ContentType.APPLICATION_JSON)); + ClientEntity entity = client.getReader().readEntity(inputStream, ContentType.APPLICATION_JSON); + assertNotNull(entity); + assertEquals(7, entity.getProperties().size()); + assertEquals(1, entity.getAnnotations().size()); + assertEquals("com.contoso.PersonalInfo.PhoneNumbers", entity.getAnnotations().get(0).getTerm()); + assertEquals(2, entity.getAnnotations().get(0).getCollectionValue().size()); + + assertEquals("com.contoso.display.style", entity.getProperty("LastName"). + getAnnotations().get(0).getTerm()); + assertEquals(2, entity.getProperty("LastName"). + getAnnotations().get(0).getComplexValue().asComplex().asJavaMap().size()); + + assertEquals(3, entity.getProperty("AddressInfo").getCollectionValue().asCollection().size()); + assertEquals("Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", + entity.getProperty("AddressInfo").getCollectionValue().asCollection().getTypeName()); + assertEquals(true, entity.getProperty("AddressInfo").getCollectionValue().isCollection()); + ClientCollectionValue<ClientValue> collectionValue = entity.getProperty("AddressInfo"). + getCollectionValue().asCollection(); + int i = 0; + for (ClientValue _value : collectionValue) { + if (i == 0) { + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.Location", _value.getTypeName()); + assertEquals(2, _value.asComplex().asJavaMap().size()); + assertEquals("Microsoft.OData.SampleService.Models.TripPin.City", + _value.asComplex().get("City").getComplexValue().getTypeName()); + } else if (i == 1) { + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.EventLocation", _value.getTypeName()); + assertEquals(3, _value.asComplex().asJavaMap().size()); + assertEquals("com.contoso.display.style", _value.asComplex().get("Address").getAnnotations().get(0).getTerm()); + assertEquals(2, _value.asComplex().get("Address").getAnnotations().get(0).getComplexValue().asJavaMap().size()); + } else if (i == 2) { + assertEquals("#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", _value.getTypeName()); + assertEquals(3, _value.asComplex().asJavaMap().size()); + } + i++; + } + } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json new file mode 100644 index 0000000..0a52548 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073.json @@ -0,0 +1,17 @@ +{ + "@odata.type": "#Microsoft.Exchange.Services.OData.Model.Entity", + "[email protected]": "#Collection(Microsoft.Exchange.Services.OData.Model.Recipient)", + "ToRecipients": [{ + "@odata.type": "#Microsoft.Exchange.Services.OData.Model.ComplexType1", + "[email protected]": "String", + "Name1": "challen_olingo_client", + "[email protected]": "String", + "Address1": "[email protected]" + }, { + "@odata.type": "#Microsoft.Exchange.Services.OData.Model.ComplexType2", + "[email protected]": "String", + "Name2": "challen_olingo_client", + "[email protected]": "String", + "Address2": "[email protected]" + }] +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json new file mode 100644 index 0000000..86cdab5 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.json @@ -0,0 +1,66 @@ +{ + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Person", + "@odata.id": "http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')", + "[email protected]": "String", + "UserName": "russellwhyte", + "[email protected]": "String", + "FirstName": "Russell", + "[email protected]": "String", + "LastName": "Whyte", + "[email protected]": "#Collection(String)", + "Emails": [ + "[email protected]", + "[email protected]" + ], + "[email protected]": "#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", + "AddressInfo": [ + { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Location", + "[email protected]": "String", + "Address": "187 Suffolk Ln.", + "City": { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City", + "[email protected]": "String", + "CountryRegion": "United States", + "[email protected]": "String", + "Name": "Boise", + "[email protected]": "String", + "Region": "ID" + } + }, + { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.EventLocation", + "[email protected]": "String", + "BuildingInfo": "187 Suffolk Ln12.", + "[email protected]": "String", + "Address": "187 Suffolk Ln12.", + "City": { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City", + "[email protected]": "String", + "CountryRegion": "United States", + "[email protected]": "String", + "Name": "Boise", + "[email protected]": "String", + "Region": "ID" + } + }, + { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", + "[email protected]": "String", + "Address": "187 Suffolk Ln123.", + "City": { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City", + "[email protected]": "String", + "CountryRegion": "United States", + "[email protected]": "String", + "Name": "Boise", + "[email protected]": "String", + "Region": "ID" + } + } + ], + "[email protected]": "#Microsoft.OData.SampleService.Models.TripPin.PersonGender", + "Gender": "Male", + "[email protected]": "Int64", + "Concurrency": 636293755917400747 +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml new file mode 100644 index 0000000..c71b0de --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_1.xml @@ -0,0 +1,65 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<entry xmlns="http://www.w3.org/2005/Atom" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:gml="http://www.opengis.net/gml" xmlns:georss="http://www.georss.org/georss"> + <id>http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')</id> + <category scheme="http://docs.oasis-open.org/odata/ns/scheme" term="#Microsoft.OData.SampleService.Models.TripPin.Person"/> + <content type="application/xml"> + <m:properties> + <d:UserName>russellwhyte</d:UserName> + <d:FirstName>Russell</d:FirstName> + <d:LastName>Whyte</d:LastName> + <d:Emails m:type="#Collection(String)"> + <m:element>[email protected]</m:element> + <m:element>[email protected]</m:element> + </d:Emails> + <d:AddressInfo m:type="#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)"> + <m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.Location"> + <d:Address>187 Suffolk Ln.</d:Address> + <d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City"> + <d:CountryRegion>United States</d:CountryRegion> + <d:Name>Boise</d:Name> + <d:Region>ID</d:Region> + </d:City> + </m:element> + <m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.EventLocation"> + <d:BuildingInfo>187 Suffolk Ln12.</d:BuildingInfo> + <d:Address>187 Suffolk Ln12.</d:Address> + <d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City"> + <d:CountryRegion>United States</d:CountryRegion> + <d:Name>Boise</d:Name> + <d:Region>ID</d:Region> + </d:City> + </m:element> + <m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.AirportLocation"> + <d:Address>187 Suffolk Ln123.</d:Address> + <d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City"> + <d:CountryRegion>United States</d:CountryRegion> + <d:Name>Boise</d:Name> + <d:Region>ID</d:Region> + </d:City> + </m:element> + </d:AddressInfo> + <d:Gender m:type="#Microsoft.OData.SampleService.Models.TripPin.PersonGender">Male</d:Gender> + <d:Concurrency m:type="Int64">636293755917400747</d:Concurrency> + </m:properties> + </content> +</entry> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json new file mode 100644 index 0000000..52c76e3 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.json @@ -0,0 +1,87 @@ +{ + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Person", + "@odata.id": "http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')", + "@com.contoso.PersonalInfo.PhoneNumbers": ["(203)555-1718", "(203)555-1719"], + "[email protected]": "String", + "UserName": "russellwhyte", + "[email protected]": "String", + "FirstName": "Russell", + "[email protected]": { + "@odata.type": "#com.contoso.display.styleType", + "title": true, + "order": 1 + }, + "[email protected]": "String", + "LastName": "Whyte", + "[email protected]": "#Collection(String)", + "Emails": [ + "[email protected]", + "[email protected]" + ], + "[email protected]": "#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)", + "AddressInfo": [ + { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.Location", + "[email protected]": "String", + "Address": "187 Suffolk Ln.", + "City": { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City", + "[email protected]": "String", + "CountryRegion": "United States", + "[email protected]": "String", + "Name": "Boise", + "[email protected]": "String", + "Region": "ID" + } + }, + { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.EventLocation", + "[email protected]": "String", + "BuildingInfo": "187 Suffolk Ln12.", + "[email protected]": { + "@odata.type": "#com.contoso.display.styleType", + "Addrtitle": true, + "Addrorder": 1 + }, + "Address": "187 Suffolk Ln12.", + "City": { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City", + "[email protected]": "String", + "CountryRegion": "United States", + "[email protected]": "String", + "Name": "Boise", + "[email protected]": "String", + "Region": "ID" + } + }, + { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.AirportLocation", + "[email protected]": "String", + "Address": "187 Suffolk Ln123.", + "City": { + "@odata.type": "#Microsoft.OData.SampleService.Models.TripPin.City", + "[email protected]": "String", + "CountryRegion": "United States", + "[email protected]": "String", + "Name": "Boise", + "[email protected]": "String", + "Region": "ID" + }, + "[email protected]": "#GeographyPoint", + "Home": { + "type": "Point", + "coordinates": [23.1, 32.1], + "crs": { + "type": "name", + "properties": { + "name": "EPSG:4326" + } + } + } + } + ], + "[email protected]": "#Microsoft.OData.SampleService.Models.TripPin.PersonGender", + "Gender": "Male", + "[email protected]": "Int64", + "Concurrency": 636293755917400747 +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml ---------------------------------------------------------------------- diff --git a/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml new file mode 100644 index 0000000..b996ac8 --- /dev/null +++ b/lib/client-core/src/test/resources/org/apache/olingo/client/core/olingo1073_2.xml @@ -0,0 +1,78 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<entry xmlns="http://www.w3.org/2005/Atom" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:m="http://docs.oasis-open.org/odata/ns/metadata" xmlns:d="http://docs.oasis-open.org/odata/ns/data" xmlns:gml="http://www.opengis.net/gml" xmlns:georss="http://www.georss.org/georss"> + <id>http://services.odata.org/V4/(S(fe5rsnxo3fkkkk2bvmh1nl1y))/TripPinServiceRW/People('russellwhyte')</id> + <category scheme="http://docs.oasis-open.org/odata/ns/scheme" term="#Microsoft.OData.SampleService.Models.TripPin.Person"/> + <content type="application/xml"> + <m:properties> + <d:UserName>russellwhyte</d:UserName> + <d:FirstName>Russell</d:FirstName> + <d:LastName>Whyte</d:LastName> + <m:annotation term="com.contoso.display.style" target="LastName" m:type="#com.contoso.display.styleType"> + <d:title m:type="Boolean">true</d:title> + <d:order m:type="Int32">1</d:order> + </m:annotation> + <d:Emails m:type="#Collection(String)"> + <m:element>[email protected]</m:element> + <m:element>[email protected]</m:element> + </d:Emails> + <d:AddressInfo m:type="#Collection(Microsoft.OData.SampleService.Models.TripPin.Location)"> + <m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.Location"> + <d:Address>187 Suffolk Ln.</d:Address> + <d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City"> + <d:CountryRegion>United States</d:CountryRegion> + <d:Name>Boise</d:Name> + <d:Region>ID</d:Region> + </d:City> + </m:element> + <m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.EventLocation"> + <d:BuildingInfo>187 Suffolk Ln12.</d:BuildingInfo> + <d:Address>187 Suffolk Ln12.</d:Address> + <d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City"> + <d:CountryRegion>United States</d:CountryRegion> + <d:Name>Boise</d:Name> + <d:Region>ID</d:Region> + </d:City> + </m:element> + <m:element m:type="#Microsoft.OData.SampleService.Models.TripPin.AirportLocation"> + <d:Address>187 Suffolk Ln123.</d:Address> + <d:City m:type="#Microsoft.OData.SampleService.Models.TripPin.City"> + <d:CountryRegion>United States</d:CountryRegion> + <d:Name>Boise</d:Name> + <d:Region>ID</d:Region> + </d:City> + <d:Home m:type="GeographyPoint"> + <gml:Point gml:srsName="http://www.opengis.net/def/crs/EPSG/0/4326"> + <gml:pos>32.1 23.1</gml:pos> + </gml:Point> + </d:Home> + </m:element> + </d:AddressInfo> + <d:Gender m:type="#Microsoft.OData.SampleService.Models.TripPin.PersonGender">Male</d:Gender> + <d:Concurrency m:type="Int64">636293755917400747</d:Concurrency> + </m:properties> + </content> + <m:annotation term="com.contoso.PersonalInfo.PhoneNumbers" m:type="#Collection(String)"> + <m:element>(203)555-1718</m:element> + <m:element>(203)555-1719</m:element> + </m:annotation> +</entry> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/32ff14fe/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java index 0054777..523c938 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/ComplexValue.java @@ -27,6 +27,8 @@ import java.util.List; public class ComplexValue extends Linked { private final List<Property> value = new ArrayList<Property>(); + + private String typeName; /** * Get list of all values for this ComplexValue. @@ -53,4 +55,20 @@ public class ComplexValue extends Linked { public String toString() { return value.toString(); } + + /** + * Get string representation of type (can be null if not set). + * @return string representation of type (can be null if not set) + */ + public String getTypeName() { + return typeName; + } + + /** + * Set string representation of type. + * @param type string representation of type + */ + public void setTypeName(final String typeName) { + this.typeName = typeName; + } }
