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;
+  }
 }

Reply via email to