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