Repository: olingo-odata4
Updated Branches:
  refs/heads/master 36e6ed401 -> 17544d2d1


[OLINGO-390] As for 'plain' complex values, do not serialize the type 
information as for primitives (in JSON)


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/17544d2d
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/17544d2d
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/17544d2d

Branch: refs/heads/master
Commit: 17544d2d1c870987155ef1697bf4b625a8bbac5b
Parents: 36e6ed4
Author: Francesco Chicchiriccò <--global>
Authored: Wed Jul 30 09:53:30 2014 +0200
Committer: Francesco Chicchiriccò <--global>
Committed: Wed Jul 30 09:53:30 2014 +0200

----------------------------------------------------------------------
 .../fit/v4/JSONFormatConformanceTestITCase.java | 159 +++++++++----------
 .../apache/olingo/client/core/v4/AtomTest.java  |  10 +-
 .../apache/olingo/client/core/v4/JSONTest.java  |  51 +++++-
 .../apache/olingo/client/core/v4/olingo390.json |  18 +++
 .../serialization/JsonEntitySerializer.java     |  30 ++--
 .../core/serialization/JsonSerializer.java      | 141 ++++++++--------
 6 files changed, 243 insertions(+), 166 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/17544d2d/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
 
b/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
index 6df7be8..34d401a 100644
--- 
a/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
+++ 
b/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
@@ -18,6 +18,11 @@
  */
 package org.apache.olingo.fit.v4;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import org.apache.commons.io.IOUtils;
 import 
org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
 import 
org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
@@ -34,15 +39,9 @@ import 
org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.junit.Test;
-
 import java.math.BigDecimal;
 import java.net.URI;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
 /**
  * The test cases in this class are inspired by client conformance criteria 
defined in the <a
  * 
href="http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793094";>specs
@@ -62,8 +61,8 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
   @Test
   public void item1() throws EdmPrimitiveTypeException {
     final URI uri = edmClient.newURIBuilder().
-        appendEntitySetSegment("Accounts").appendKeySegment(102).
-        
appendNavigationSegment("MyPaymentInstruments").appendKeySegment(102902).build();
+            appendEntitySetSegment("Accounts").appendKeySegment(102).
+            
appendNavigationSegment("MyPaymentInstruments").appendKeySegment(102902).build();
     final ODataEntityRequest<ODataEntity> req = 
edmClient.getRetrieveRequestFactory().getEntityRequest(uri);
 
     // request format (via Accept header) is set to minimal by default
@@ -89,7 +88,7 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
   @Test
   public void item2() {
     final URI uri = edmClient.newURIBuilder(testStaticServiceRootURL).
-        appendEntitySetSegment("Accounts").appendKeySegment(102).build();
+            appendEntitySetSegment("Accounts").appendKeySegment(102).build();
     final ODataEntityRequest<ODataEntity> req = 
edmClient.getRetrieveRequestFactory().getEntityRequest(uri);
     req.setFormat(ODataFormat.JSON_FULL_METADATA);
 
@@ -119,34 +118,34 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
   @Test
   public void item3() throws Exception {
     final String fromSection71 = "{"
-        + "\"NullValue\": null,"
-        + "\"TrueValue\": true,"
-        + "\"FalseValue\": false,"
-        + "\"[email protected]\": \"Binary\","
-        + "\"BinaryValue\": \"T0RhdGE\","
-        + "\"IntegerValue\": -128,"
-        + "\"DoubleValue\": 3.1415926535897931,"
-        + "\"[email protected]\": \"Single\","
-        + "\"SingleValue\": \"INF\","
-        + "\"[email protected]\": \"Decimal\","
-        + "\"DecimalValue\": 34.95,"
-        + "\"StringValue\": \"Say \\\"Hello\\\",\\nthen go\","
-        + "\"[email protected]\": \"Date\","
-        + "\"DateValue\": \"2012-12-03\","
-        + "\"[email protected]\": \"DateTimeOffset\","
-        + "\"DateTimeOffsetValue\": \"2012-12-03T07:16:23Z\","
-        + "\"[email protected]\": \"Duration\","
-        + "\"DurationValue\": \"P12DT23H59M59.999999999999S\","
-        + "\"[email protected]\": \"TimeOfDay\","
-        + "\"TimeOfDayValue\": \"07:59:59.999\","
-        + "\"[email protected]\": \"Guid\","
-        + "\"GuidValue\": \"01234567-89ab-cdef-0123-456789abcdef\","
-        + "\"[email protected]\": \"Int64\","
-        + "\"Int64Value\": 0,"
-        + "\"[email protected]\": \"Test.Color\","
-        + "\"ColorEnumValue\": \"Yellow\","
-        + "\"GeographyPoint\": {\"type\": 
\"Point\",\"coordinates\":[142.1,64.1]}"
-        + "}";
+            + "\"NullValue\": null,"
+            + "\"TrueValue\": true,"
+            + "\"FalseValue\": false,"
+            + "\"[email protected]\": \"Binary\","
+            + "\"BinaryValue\": \"T0RhdGE\","
+            + "\"IntegerValue\": -128,"
+            + "\"DoubleValue\": 3.1415926535897931,"
+            + "\"[email protected]\": \"Single\","
+            + "\"SingleValue\": \"INF\","
+            + "\"[email protected]\": \"Decimal\","
+            + "\"DecimalValue\": 34.95,"
+            + "\"StringValue\": \"Say \\\"Hello\\\",\\nthen go\","
+            + "\"[email protected]\": \"Date\","
+            + "\"DateValue\": \"2012-12-03\","
+            + "\"[email protected]\": \"DateTimeOffset\","
+            + "\"DateTimeOffsetValue\": \"2012-12-03T07:16:23Z\","
+            + "\"[email protected]\": \"Duration\","
+            + "\"DurationValue\": \"P12DT23H59M59.999999999999S\","
+            + "\"[email protected]\": \"TimeOfDay\","
+            + "\"TimeOfDayValue\": \"07:59:59.999\","
+            + "\"[email protected]\": \"Guid\","
+            + "\"GuidValue\": \"01234567-89ab-cdef-0123-456789abcdef\","
+            + "\"[email protected]\": \"Int64\","
+            + "\"Int64Value\": 0,"
+            + "\"[email protected]\": \"Test.Color\","
+            + "\"ColorEnumValue\": \"Yellow\","
+            + "\"GeographyPoint\": {\"type\": 
\"Point\",\"coordinates\":[142.1,64.1]}"
+            + "}";
 
     final ODataEntity entity = 
client.getReader().readEntity(IOUtils.toInputStream(fromSection71), 
ODataFormat.JSON);
 
@@ -165,29 +164,29 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
 
     assertEquals(EdmPrimitiveTypeKind.Double, 
entity.getProperty("DoubleValue").getPrimitiveValue().getTypeKind());
     assertEquals(3.1415926535897931,
-        
entity.getProperty("DoubleValue").getPrimitiveValue().toCastValue(Double.class),
 0);
+            
entity.getProperty("DoubleValue").getPrimitiveValue().toCastValue(Double.class),
 0);
 
     assertEquals(EdmPrimitiveTypeKind.Single, 
entity.getProperty("SingleValue").getPrimitiveValue().getTypeKind());
     assertEquals(Float.POSITIVE_INFINITY,
-        
entity.getProperty("SingleValue").getPrimitiveValue().toCastValue(Float.class), 
0);
+            
entity.getProperty("SingleValue").getPrimitiveValue().toCastValue(Float.class), 
0);
 
     assertEquals(EdmPrimitiveTypeKind.Decimal, 
entity.getProperty("DecimalValue").getPrimitiveValue().getTypeKind());
     assertEquals(BigDecimal.valueOf(34.95),
-        
entity.getProperty("DecimalValue").getPrimitiveValue().toCastValue(BigDecimal.class));
+            
entity.getProperty("DecimalValue").getPrimitiveValue().toCastValue(BigDecimal.class));
 
     assertEquals(EdmPrimitiveTypeKind.String, 
entity.getProperty("StringValue").getPrimitiveValue().getTypeKind());
     assertEquals("Say \"Hello\",\nthen go",
-        
entity.getProperty("StringValue").getPrimitiveValue().toCastValue(String.class));
+            
entity.getProperty("StringValue").getPrimitiveValue().toCastValue(String.class));
 
     assertEquals(EdmPrimitiveTypeKind.Date, 
entity.getProperty("DateValue").getPrimitiveValue().getTypeKind());
 
     assertEquals(EdmPrimitiveTypeKind.DateTimeOffset,
-        
entity.getProperty("DateTimeOffsetValue").getPrimitiveValue().getTypeKind());
+            
entity.getProperty("DateTimeOffsetValue").getPrimitiveValue().getTypeKind());
 
     assertEquals(EdmPrimitiveTypeKind.Duration, 
entity.getProperty("DurationValue").getPrimitiveValue().getTypeKind());
 
     assertEquals(EdmPrimitiveTypeKind.TimeOfDay,
-        
entity.getProperty("TimeOfDayValue").getPrimitiveValue().getTypeKind());
+            
entity.getProperty("TimeOfDayValue").getPrimitiveValue().getTypeKind());
 
     assertEquals(EdmPrimitiveTypeKind.Guid, 
entity.getProperty("GuidValue").getPrimitiveValue().getTypeKind());
 
@@ -196,7 +195,7 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
     assertTrue(entity.getProperty("ColorEnumValue").hasEnumValue());
 
     assertEquals(EdmPrimitiveTypeKind.GeographyPoint,
-        
entity.getProperty("GeographyPoint").getPrimitiveValue().getTypeKind());
+            
entity.getProperty("GeographyPoint").getPrimitiveValue().getTypeKind());
   }
 
   /**
@@ -205,21 +204,21 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
   @Test
   public void item4() throws Exception {
     final String fromSection45_1 = "{"
-        + "\"@odata.context\": 
\"http://host/service/$metadata#Customers/$entity\",";
-        + "\"@odata.metadataEtag\": \"W/\\\"A1FF3E230954908F\\\"\","
-        + "\"@odata.etag\": \"W/\\\"A1FF3E230954908G\\\"\","
-        + "\"@odata.type\": \"#Model.VipCustomer\","
-        + "\"@odata.id\": \"http://host/service/Employees(PersonID=3)\","
-        + "\"@odata.editLink\": \"People(976)\","
-        + "\"@odata.mediaEditLink\": \"Employees(1)/$value\","
-        + "\"@odata.mediaContentType\": \"image/jpeg\","
-        + "\"@odata.mediaEtag\": \"W/\\\"A1FF3E230954908H\\\"\","
-        + "\"[email protected]\": \"People(976)/Parent\","
-        + "\"[email protected]\": \"People(976)/Parent\""
-        + "}";
+            + "\"@odata.context\": 
\"http://host/service/$metadata#Customers/$entity\",";
+            + "\"@odata.metadataEtag\": \"W/\\\"A1FF3E230954908F\\\"\","
+            + "\"@odata.etag\": \"W/\\\"A1FF3E230954908G\\\"\","
+            + "\"@odata.type\": \"#Model.VipCustomer\","
+            + "\"@odata.id\": \"http://host/service/Employees(PersonID=3)\","
+            + "\"@odata.editLink\": \"People(976)\","
+            + "\"@odata.mediaEditLink\": \"Employees(1)/$value\","
+            + "\"@odata.mediaContentType\": \"image/jpeg\","
+            + "\"@odata.mediaEtag\": \"W/\\\"A1FF3E230954908H\\\"\","
+            + "\"[email protected]\": \"People(976)/Parent\","
+            + "\"[email protected]\": \"People(976)/Parent\""
+            + "}";
 
     final ResWrap<Entity> entity =
-        
client.getDeserializer(ODataFormat.JSON).toEntity(IOUtils.toInputStream(fromSection45_1));
+            
client.getDeserializer(ODataFormat.JSON).toEntity(IOUtils.toInputStream(fromSection45_1));
 
     assertEquals("http://host/service/$metadata#Customers/$entity";, 
entity.getContextURL().toASCIIString());
     assertEquals("W/\"A1FF3E230954908F\"", entity.getMetadataETag());
@@ -234,14 +233,14 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
     assertEquals("People(976)/Parent", 
entity.getPayload().getAssociationLink("Parent").getHref());
 
     final String fromSection45_2 = "{"
-        + "  \"@odata.count\": 5,"
-        + "  \"value\": [],"
-        + "  \"@odata.nextLink\": \"Customers?$expand=Orders&$skipToken=5\","
-        + "  \"@odata.deltaLink\": 
\"Customers?$expand=Orders&$deltatoken=8015\""
-        + "}";
+            + "  \"@odata.count\": 5,"
+            + "  \"value\": [],"
+            + "  \"@odata.nextLink\": 
\"Customers?$expand=Orders&$skipToken=5\","
+            + "  \"@odata.deltaLink\": 
\"Customers?$expand=Orders&$deltatoken=8015\""
+            + "}";
 
     final ResWrap<EntitySet> entitySet =
-        
client.getDeserializer(ODataFormat.JSON).toEntitySet(IOUtils.toInputStream(fromSection45_2));
+            
client.getDeserializer(ODataFormat.JSON).toEntitySet(IOUtils.toInputStream(fromSection45_2));
 
     assertEquals(5, entitySet.getPayload().getCount(), 0);
     assertEquals("Customers?$expand=Orders&$skipToken=5", 
entitySet.getPayload().getNext().toASCIIString());
@@ -255,23 +254,23 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
   @Test
   public void item5() throws Exception {
     final String sample = "{"
-        + "  \"@odata.context\": \"http://host/service/$metadata#Customers\",";
-        + "  \"@odata.notdefined\": 11,"
-        + "  \"@com.contoso.customer.setkind\": \"VIPs\","
-        + "  \"value\": ["
-        + "    {"
-        + "      \"@com.contoso.display.highlight\": true,"
-        + "      \"ID\": \"ALFKI\","
-        + "      \"[email protected]\": { \"title\": true, 
\"order\": 1 },"
-        + "      \"CompanyName\": \"Alfreds Futterkiste\","
-        + "      \"[email protected]\": { \"order\": 2 },"
-        + "      \"[email protected]\": \"People(976)/Orders\""
-        + "    }"
-        + "  ]"
-        + "}";
+            + "  \"@odata.context\": 
\"http://host/service/$metadata#Customers\",";
+            + "  \"@odata.notdefined\": 11,"
+            + "  \"@com.contoso.customer.setkind\": \"VIPs\","
+            + "  \"value\": ["
+            + "    {"
+            + "      \"@com.contoso.display.highlight\": true,"
+            + "      \"ID\": \"ALFKI\","
+            + "      \"[email protected]\": { \"title\": 
true, \"order\": 1 },"
+            + "      \"CompanyName\": \"Alfreds Futterkiste\","
+            + "      \"[email protected]\": { \"order\": 2 },"
+            + "      \"[email protected]\": \"People(976)/Orders\""
+            + "    }"
+            + "  ]"
+            + "}";
 
     final ODataEntitySet entitySet = client.getReader().
-        readEntitySet(IOUtils.toInputStream(sample), ODataFormat.JSON);
+            readEntitySet(IOUtils.toInputStream(sample), ODataFormat.JSON);
 
     assertEquals(2, entitySet.getAnnotations().size());
 
@@ -314,8 +313,8 @@ public class JSONFormatConformanceTestITCase extends 
AbstractTestITCase {
   @Test
   public void item6() throws EdmPrimitiveTypeException {
     final URI uri = edmClient.newURIBuilder().
-        appendEntitySetSegment("Accounts").appendKeySegment(102).
-        
appendNavigationSegment("MyPaymentInstruments").appendKeySegment(102902).build();
+            appendEntitySetSegment("Accounts").appendKeySegment(102).
+            
appendNavigationSegment("MyPaymentInstruments").appendKeySegment(102902).build();
     final ODataEntityRequest<ODataEntity> req = 
edmClient.getRetrieveRequestFactory().getEntityRequest(uri);
 
     // request format (via Accept header) does not contain odata.streaming=true

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/17544d2d/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/AtomTest.java
----------------------------------------------------------------------
diff --git 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/AtomTest.java 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/AtomTest.java
index 8967e08..9998398 100644
--- 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/AtomTest.java
+++ 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/AtomTest.java
@@ -18,12 +18,13 @@
  */
 package org.apache.olingo.client.core.v4;
 
+import static org.junit.Assert.assertTrue;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.olingo.client.api.v4.ODataClient;
 import org.apache.olingo.client.core.AtomLinksQualifier;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.custommonkey.xmlunit.Diff;
-
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerFactory;
@@ -32,8 +33,6 @@ import javax.xml.transform.stream.StreamSource;
 import java.io.ByteArrayInputStream;
 import java.io.StringWriter;
 
-import static org.junit.Assert.assertTrue;
-
 public class AtomTest extends JSONTest {
 
   @Override
@@ -73,4 +72,9 @@ public class AtomTest extends JSONTest {
     // no test
   }
 
+  @Override
+  public void issueOLINGO390() throws Exception {
+    // no test
+  }
+
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/17544d2d/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
----------------------------------------------------------------------
diff --git 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
index 277aff0..27abb6f 100644
--- 
a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
+++ 
b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/JSONTest.java
@@ -25,21 +25,27 @@ import static org.junit.Assert.assertTrue;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import java.io.ByteArrayInputStream;
+import java.io.StringWriter;
+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.v4.ODataClient;
 import org.apache.olingo.client.core.AbstractTest;
 import org.apache.olingo.commons.api.Constants;
 import org.apache.olingo.commons.api.data.Delta;
 import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.domain.ODataCollectionValue;
+import org.apache.olingo.commons.api.domain.ODataComplexValue;
+import org.apache.olingo.commons.api.domain.v4.ODataEntity;
+import org.apache.olingo.commons.api.domain.v4.ODataProperty;
+import org.apache.olingo.commons.api.domain.v4.ODataValue;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.junit.Test;
-import java.io.ByteArrayInputStream;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 
 public class JSONTest extends AbstractTest {
 
@@ -218,4 +224,37 @@ public class JSONTest extends AbstractTest {
   public void deltas() throws Exception {
     delta("delta", getODataPubFormat());
   }
+
+  @Test
+  public void issueOLINGO390() throws Exception {
+    final ODataEntity message = getClient().getObjectFactory().
+            newEntity(new 
FullQualifiedName("Microsoft.Exchange.Services.OData.Model.Message"));
+
+    final ODataComplexValue<ODataProperty> toRecipient = 
getClient().getObjectFactory().
+            
newComplexValue("Microsoft.Exchange.Services.OData.Model.Recipient");
+    toRecipient.add(getClient().getObjectFactory().newPrimitiveProperty("Name",
+            
getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("challen_olingo_client")));
+    
toRecipient.add(getClient().getObjectFactory().newPrimitiveProperty("Address",
+            
getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("[email protected]")));
+    final ODataCollectionValue<ODataValue> toRecipients = 
getClient().getObjectFactory().
+            
newCollectionValue("Microsoft.Exchange.Services.OData.Model.Recipient");
+    toRecipients.add(toRecipient);
+    
message.getProperties().add(getClient().getObjectFactory().newCollectionProperty("ToRecipients",
 toRecipients));
+
+    final ODataComplexValue<ODataProperty> body =
+            
getClient().getObjectFactory().newComplexValue("Microsoft.Exchange.Services.OData.Model.ItemBody");
+    body.add(getClient().getObjectFactory().newPrimitiveProperty("Content",
+            getClient().getObjectFactory().newPrimitiveValueBuilder().
+            buildString("this is a simple email body content")));
+    body.add(getClient().getObjectFactory().newEnumProperty("ContentType",
+            
getClient().getObjectFactory().newEnumValue("Microsoft.Exchange.Services.OData.Model.BodyType",
 "text")));
+    
message.getProperties().add(getClient().getObjectFactory().newComplexProperty("Body",
 body));
+
+    final String actual = 
IOUtils.toString(getClient().getWriter().writeEntity(message, 
ODataFormat.JSON));
+    final JsonNode expected = 
OBJECT_MAPPER.readTree(IOUtils.toString(getClass().getResourceAsStream("olingo390.json")).
+            
replace(getClient().getServiceVersion().getJsonName(ODataServiceVersion.JsonKey.NAVIGATION_LINK),
+                    Constants.JSON_BIND_LINK_SUFFIX));
+    final ObjectNode actualNode = (ObjectNode) OBJECT_MAPPER.readTree(new 
ByteArrayInputStream(actual.getBytes()));
+    assertEquals(expected, actualNode);
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/17544d2d/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/olingo390.json
----------------------------------------------------------------------
diff --git 
a/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/olingo390.json
 
b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/olingo390.json
new file mode 100644
index 0000000..47543aa
--- /dev/null
+++ 
b/lib/client-core/src/test/resources/org/apache/olingo/client/core/v4/olingo390.json
@@ -0,0 +1,18 @@
+{
+  "@odata.type": "#Microsoft.Exchange.Services.OData.Model.Message",
+  "[email protected]": 
"#Collection(Microsoft.Exchange.Services.OData.Model.Recipient)",
+  "ToRecipients": [{
+      "@odata.type": "#Microsoft.Exchange.Services.OData.Model.Recipient",
+      "[email protected]": "String",
+      "Name": "challen_olingo_client",
+      "[email protected]": "String",
+      "Address": "[email protected]"
+    }],
+  "Body": {
+    "@odata.type": "#Microsoft.Exchange.Services.OData.Model.ItemBody",
+    "[email protected]": "String",
+    "Content": "this is a simple email body content",
+    "[email protected]": 
"#Microsoft.Exchange.Services.OData.Model.BodyType",
+    "ContentType": "text"
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/17544d2d/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
----------------------------------------------------------------------
diff --git 
a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
 
b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
index 9396b77..826d2b7 100644
--- 
a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
+++ 
b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonEntitySerializer.java
@@ -1,18 +1,18 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
+ * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
+ * 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
- * 
+ * 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
+ * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
@@ -30,7 +30,6 @@ import org.apache.olingo.commons.api.domain.ODataOperation;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
-
 import java.io.IOException;
 import java.net.URI;
 
@@ -44,12 +43,13 @@ public class JsonEntitySerializer extends JsonSerializer {
   }
 
   protected void doSerialize(final Entity entity, final JsonGenerator jgen)
-      throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException {
+
     doContainerSerialize(new ResWrap<Entity>((URI) null, null, entity), jgen);
   }
 
   protected void doContainerSerialize(final ResWrap<Entity> container, final 
JsonGenerator jgen)
-      throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException {
 
     final Entity entity = container.getPayload();
 
@@ -58,8 +58,8 @@ public class JsonEntitySerializer extends JsonSerializer {
     if (serverMode) {
       if (container.getContextURL() != null) {
         jgen.writeStringField(version.compareTo(ODataServiceVersion.V40) >= 0
-            ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
-            container.getContextURL().toASCIIString());
+                ? Constants.JSON_CONTEXT : Constants.JSON_METADATA,
+                container.getContextURL().toASCIIString());
       }
       if (version.compareTo(ODataServiceVersion.V40) >= 0 && 
StringUtils.isNotBlank(container.getMetadataETag())) {
         jgen.writeStringField(Constants.JSON_METADATA_ETAG, 
container.getMetadataETag());
@@ -72,7 +72,7 @@ public class JsonEntitySerializer extends JsonSerializer {
 
     if (StringUtils.isNotBlank(entity.getType())) {
       
jgen.writeStringField(version.getJsonName(ODataServiceVersion.JsonKey.TYPE),
-          new 
EdmTypeInfo.Builder().setTypeExpression(entity.getType()).build().external(version));
+              new 
EdmTypeInfo.Builder().setTypeExpression(entity.getType()).build().external(version));
     }
 
     if (entity.getId() != null) {
@@ -89,11 +89,11 @@ public class JsonEntitySerializer extends JsonSerializer {
 
     if (serverMode && entity.getEditLink() != null && 
StringUtils.isNotBlank(entity.getEditLink().getHref())) {
       
jgen.writeStringField(version.getJsonName(ODataServiceVersion.JsonKey.EDIT_LINK),
-          entity.getEditLink().getHref());
+              entity.getEditLink().getHref());
 
       if (entity.isMediaEntity()) {
         
jgen.writeStringField(version.getJsonName(ODataServiceVersion.JsonKey.MEDIA_READ_LINK),
-            entity.getEditLink().getHref() + "/$value");
+                entity.getEditLink().getHref() + "/$value");
       }
     }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/17544d2d/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
----------------------------------------------------------------------
diff --git 
a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
 
b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
index bcd59c1..2c7c66b 100755
--- 
a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
+++ 
b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
@@ -1,18 +1,18 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
+ * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
+ * 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
- * 
+ * 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
+ * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
@@ -43,7 +43,6 @@ import 
org.apache.olingo.commons.api.serialization.ODataSerializer;
 import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
 import 
org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
-
 import java.io.IOException;
 import java.io.Writer;
 import java.util.ArrayList;
@@ -53,18 +52,19 @@ import java.util.Map;
 
 public class JsonSerializer implements ODataSerializer {
 
-  protected ODataServiceVersion version;
-  protected boolean serverMode;
-
   private static final EdmPrimitiveTypeKind[] NUMBER_TYPES = {
-      EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
-      EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double,
-      EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, 
EdmPrimitiveTypeKind.Int64,
-      EdmPrimitiveTypeKind.Decimal
+    EdmPrimitiveTypeKind.Byte, EdmPrimitiveTypeKind.SByte,
+    EdmPrimitiveTypeKind.Single, EdmPrimitiveTypeKind.Double,
+    EdmPrimitiveTypeKind.Int16, EdmPrimitiveTypeKind.Int32, 
EdmPrimitiveTypeKind.Int64,
+    EdmPrimitiveTypeKind.Decimal
   };
 
   private final JsonGeoValueSerializer geoSerializer = new 
JsonGeoValueSerializer();
 
+  protected ODataServiceVersion version;
+
+  protected boolean serverMode;
+
   public JsonSerializer(final ODataServiceVersion version, final boolean 
serverMode) {
     this.version = version;
     this.serverMode = serverMode;
@@ -73,7 +73,7 @@ public class JsonSerializer implements ODataSerializer {
   @Override
   public <T> void write(final Writer writer, final T obj) throws 
ODataSerializerException {
     try {
-      JsonGenerator json = new JsonFactory().createGenerator(writer);
+      final JsonGenerator json = new JsonFactory().createGenerator(writer);
       if (obj instanceof EntitySet) {
         new JsonEntitySetSerializer(version, 
serverMode).doSerialize((EntitySet) obj, json);
       } else if (obj instanceof Entity) {
@@ -96,7 +96,7 @@ public class JsonSerializer implements ODataSerializer {
   public <T> void write(final Writer writer, final ResWrap<T> container) 
throws ODataSerializerException {
     final T obj = container == null ? null : container.getPayload();
     try {
-      JsonGenerator json = new JsonFactory().createGenerator(writer);
+      final JsonGenerator json = new JsonFactory().createGenerator(writer);
       if (obj instanceof EntitySet) {
         new JsonEntitySetSerializer(version, 
serverMode).doContainerSerialize((ResWrap<EntitySet>) container, json);
       } else if (obj instanceof Entity) {
@@ -121,7 +121,8 @@ public class JsonSerializer implements ODataSerializer {
   }
 
   protected void links(final Linked linked, final JsonGenerator jgen)
-      throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException {
+
     if (serverMode) {
       serverLinks(linked, jgen);
     } else {
@@ -130,7 +131,8 @@ public class JsonSerializer implements ODataSerializer {
   }
 
   protected void clientLinks(final Linked linked, final JsonGenerator jgen)
-      throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException {
+
     final Map<String, List<String>> entitySetLinks = new HashMap<String, 
List<String>>();
     for (Link link : linked.getNavigationLinks()) {
       for (Annotation annotation : link.getAnnotations()) {
@@ -166,7 +168,7 @@ public class JsonSerializer implements ODataSerializer {
         new JsonEntitySerializer(version, 
serverMode).doSerialize(link.getInlineEntity(), jgen);
       } else if (link.getInlineEntitySet() != null) {
         jgen.writeArrayFieldStart(link.getTitle());
-        JsonEntitySerializer entitySerializer = new 
JsonEntitySerializer(version, serverMode);
+        final JsonEntitySerializer entitySerializer = new 
JsonEntitySerializer(version, serverMode);
         for (Entity subEntry : link.getInlineEntitySet().getEntities()) {
           entitySerializer.doSerialize(subEntry, jgen);
         }
@@ -185,14 +187,14 @@ public class JsonSerializer implements ODataSerializer {
   }
 
   protected void serverLinks(final Linked linked, final JsonGenerator jgen)
-      throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException {
     if (linked instanceof Entity) {
       for (Link link : ((Entity) linked).getMediaEditLinks()) {
         if (StringUtils.isNotBlank(link.getHref())) {
           jgen.writeStringField(
-              link.getTitle() + StringUtils.prependIfMissing(
-                  
version.getJsonName(ODataServiceVersion.JsonKey.MEDIA_EDIT_LINK), "@"),
-              link.getHref());
+                  link.getTitle() + StringUtils.prependIfMissing(
+                          
version.getJsonName(ODataServiceVersion.JsonKey.MEDIA_EDIT_LINK), "@"),
+                  link.getHref());
         }
       }
     }
@@ -200,8 +202,8 @@ public class JsonSerializer implements ODataSerializer {
     for (Link link : linked.getAssociationLinks()) {
       if (StringUtils.isNotBlank(link.getHref())) {
         jgen.writeStringField(
-            link.getTitle() + 
version.getJsonName(ODataServiceVersion.JsonKey.ASSOCIATION_LINK),
-            link.getHref());
+                link.getTitle() + 
version.getJsonName(ODataServiceVersion.JsonKey.ASSOCIATION_LINK),
+                link.getHref());
       }
     }
 
@@ -212,8 +214,8 @@ public class JsonSerializer implements ODataSerializer {
 
       if (StringUtils.isNotBlank(link.getHref())) {
         jgen.writeStringField(
-            link.getTitle() + 
version.getJsonName(ODataServiceVersion.JsonKey.NAVIGATION_LINK),
-            link.getHref());
+                link.getTitle() + 
version.getJsonName(ODataServiceVersion.JsonKey.NAVIGATION_LINK),
+                link.getHref());
       }
 
       if (link.getInlineEntity() != null) {
@@ -231,40 +233,50 @@ public class JsonSerializer implements ODataSerializer {
   }
 
   private void collection(final JsonGenerator jgen, final EdmTypeInfo typeInfo,
-      final ValueType valueType, final List<?> value) throws IOException, 
EdmPrimitiveTypeException {
+          final ValueType valueType, final List<?> value) throws IOException, 
EdmPrimitiveTypeException {
+
     jgen.writeStartArray();
+
     for (Object item : value) {
-      final EdmTypeInfo itemTypeInfo = typeInfo == null ? null :
-          new 
EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
+      final EdmTypeInfo itemTypeInfo = typeInfo == null
+              ? null
+              : new 
EdmTypeInfo.Builder().setTypeExpression(typeInfo.getFullQualifiedName().toString()).build();
       switch (valueType) {
-      case COLLECTION_PRIMITIVE:
-        primitiveValue(jgen, itemTypeInfo, item);
-        break;
-      case COLLECTION_GEOSPATIAL:
-        jgen.writeStartObject();
-        geoSerializer.serialize(jgen, (Geospatial) item);
-        jgen.writeEndObject();
-        break;
-      case COLLECTION_ENUM:
-        jgen.writeString(item.toString());
-        break;
-      case COLLECTION_COMPLEX:
-        @SuppressWarnings("unchecked")
-        final List<Property> complexItem = (List<Property>) item;
-        complexValue(jgen, itemTypeInfo, complexItem, null);
-        break;
-      case COLLECTION_LINKED_COMPLEX:
-        final LinkedComplexValue complexItem2 = (LinkedComplexValue) item;
-        complexValue(jgen, itemTypeInfo, complexItem2.getValue(), 
complexItem2);
-      default:
-        break;
+        case COLLECTION_PRIMITIVE:
+          primitiveValue(jgen, itemTypeInfo, item);
+          break;
+
+        case COLLECTION_GEOSPATIAL:
+          jgen.writeStartObject();
+          geoSerializer.serialize(jgen, (Geospatial) item);
+          jgen.writeEndObject();
+          break;
+
+        case COLLECTION_ENUM:
+          jgen.writeString(item.toString());
+          break;
+
+        case COLLECTION_COMPLEX:
+          @SuppressWarnings("unchecked")
+          final List<Property> complexItem = (List<Property>) item;
+          complexValue(jgen, itemTypeInfo, complexItem, null);
+          break;
+
+        case COLLECTION_LINKED_COMPLEX:
+          final LinkedComplexValue complexItem2 = (LinkedComplexValue) item;
+          complexValue(jgen, itemTypeInfo, complexItem2.getValue(), 
complexItem2);
+          break;
+
+        default:
       }
     }
+
     jgen.writeEndArray();
   }
 
   protected void primitiveValue(final JsonGenerator jgen, final EdmTypeInfo 
typeInfo, final Object value)
-      throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException {
+
     final EdmPrimitiveTypeKind kind = typeInfo == null ? null : 
typeInfo.getPrimitiveTypeKind();
     final boolean isNumber = kind == null ? value instanceof Number : 
ArrayUtils.contains(NUMBER_TYPES, kind);
     final boolean isBoolean = kind == null ? value instanceof Boolean : kind 
== EdmPrimitiveTypeKind.Boolean;
@@ -274,9 +286,11 @@ public class JsonSerializer implements ODataSerializer {
     } else if (isBoolean) {
       jgen.writeBoolean((Boolean) value);
     } else {
-      final String serialized = kind == null ? value.toString() :
-          EdmPrimitiveTypeFactory.getInstance(kind) // TODO: add facets
-              .valueToString(value, null, null, Constants.DEFAULT_PRECISION, 
Constants.DEFAULT_SCALE, null);
+      final String serialized = kind == null
+              ? value.toString()
+              // TODO: add facets
+              : EdmPrimitiveTypeFactory.getInstance(kind).
+              valueToString(value, null, null, Constants.DEFAULT_PRECISION, 
Constants.DEFAULT_SCALE, null);
       if (isNumber) {
         jgen.writeNumber(serialized);
       } else {
@@ -286,8 +300,8 @@ public class JsonSerializer implements ODataSerializer {
   }
 
   private void complexValue(final JsonGenerator jgen, final EdmTypeInfo 
typeInfo,
-      final List<Property> value, final Linked linked)
-      throws IOException, EdmPrimitiveTypeException {
+          final List<Property> value, final Linked linked)
+          throws IOException, EdmPrimitiveTypeException {
     jgen.writeStartObject();
 
     if (typeInfo != null) {
@@ -305,7 +319,7 @@ public class JsonSerializer implements ODataSerializer {
   }
 
   private void value(final JsonGenerator jgen, final String type, final 
Valuable value)
-      throws IOException, EdmPrimitiveTypeException {
+          throws IOException, EdmPrimitiveTypeException {
     final EdmTypeInfo typeInfo = type == null ? null : new 
EdmTypeInfo.Builder().setTypeExpression(type).build();
 
     if (value.isNull()) {
@@ -328,15 +342,18 @@ public class JsonSerializer implements ODataSerializer {
   }
 
   protected void valuable(final JsonGenerator jgen, final Valuable valuable, 
final String name)
-      throws IOException, EdmPrimitiveTypeException {
-    if (!Constants.VALUE.equals(name) && !(valuable instanceof Annotation) && 
!valuable.isComplex()) {
+          throws IOException, EdmPrimitiveTypeException {
+
+    if (!Constants.VALUE.equals(name) && !(valuable instanceof Annotation)
+            && !valuable.isComplex() && !valuable.isLinkedComplex()) {
+
       String type = valuable.getType();
       if (StringUtils.isBlank(type) && valuable.isPrimitive() || 
valuable.isNull()) {
         type = EdmPrimitiveTypeKind.String.getFullQualifiedName().toString();
       }
       if (StringUtils.isNotBlank(type)) {
         jgen.writeFieldName(
-            name + 
StringUtils.prependIfMissing(version.getJsonName(ODataServiceVersion.JsonKey.TYPE),
 "@"));
+                name + 
StringUtils.prependIfMissing(version.getJsonName(ODataServiceVersion.JsonKey.TYPE),
 "@"));
         jgen.writeString(new 
EdmTypeInfo.Builder().setTypeExpression(type).build().external(version));
       }
     }

Reply via email to