Repository: olingo-odata4 Updated Branches: refs/heads/OLINGO-811_CountForExpand [created] e7f8ff84a
[OLINGO-811] Added support for 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/e7f8ff84 Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/e7f8ff84 Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/e7f8ff84 Branch: refs/heads/OLINGO-811_CountForExpand Commit: e7f8ff84a206fd03bf909189390e8634c9df4efc Parents: 1831364 Author: Michael Bolz <[email protected]> Authored: Wed Nov 4 14:05:34 2015 +0100 Committer: Michael Bolz <[email protected]> Committed: Wed Nov 4 14:05:34 2015 +0100 ---------------------------------------------------------------------- .../commons/api/data/EntityCollection.java | 3 + .../serializer/json/ODataJsonSerializer.java | 56 ++++++++--- .../core/serializer/ExpandSelectMock.java | 26 +++++ .../json/ODataJsonSerializerTest.java | 99 ++++++++++++++++++++ 4 files changed, 173 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e7f8ff84/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityCollection.java ---------------------------------------------------------------------- diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityCollection.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityCollection.java index adb43dc..79e9430 100644 --- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityCollection.java +++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/data/EntityCollection.java @@ -50,6 +50,9 @@ public class EntityCollection extends AbstractODataObject { * @return number of entries into the entity set. */ public Integer getCount() { + if(count == null) { + return entities.size(); + } return count; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e7f8ff84/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java ---------------------------------------------------------------------- diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java index 1ddc979..0253049 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java @@ -58,6 +58,10 @@ import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriHelper; +import org.apache.olingo.server.api.uri.UriInfoResource; +import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceCount; +import org.apache.olingo.server.api.uri.UriResourceNavigation; import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectOption; @@ -335,31 +339,61 @@ public class ODataJsonSerializer extends AbstractODataSerializer { } } - protected void writeNavigationProperties(final ServiceMetadata metadata, - final EdmStructuredType type, final Linked linked, final ExpandOption expand, - final JsonGenerator json) throws SerializerException, IOException { + protected void writeNavigationProperties(final ServiceMetadata metadata, final EdmStructuredType type, + final Linked linked, final ExpandOption expand, final JsonGenerator json) + throws SerializerException, IOException { if (ExpandSelectHelper.hasExpand(expand)) { final boolean expandAll = ExpandSelectHelper.isExpandAll(expand); - final Set<String> expanded = expandAll ? new HashSet<String>() : - ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems()); + final Set<String> expanded = expandAll ? new HashSet<String>() + : ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems()); for (final String propertyName : type.getNavigationPropertyNames()) { if (expandAll || expanded.contains(propertyName)) { final EdmNavigationProperty property = type.getNavigationProperty(propertyName); final Link navigationLink = linked.getNavigationLink(property.getName()); - final ExpandItem innerOptions = expandAll ? null : - ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName); + final ExpandItem innerOptions = expandAll ? null + : ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName); if (innerOptions != null && innerOptions.getLevelsOption() != null) { throw new SerializerException("Expand option $levels is not supported.", - SerializerException.MessageKeys.NOT_IMPLEMENTED); + SerializerException.MessageKeys.NOT_IMPLEMENTED); + } + + boolean isNavigationPropertyCountOnly = false; + if (innerOptions != null) { + final UriInfoResource uriInfoResource = innerOptions.getResourcePath(); + final List<UriResource> uriResourceParts = uriInfoResource.getUriResourceParts(); + if (uriResourceParts.size() == 2 && uriResourceParts.get(0) instanceof UriResourceNavigation + && uriResourceParts.get(1) instanceof UriResourceCount) { + isNavigationPropertyCountOnly = true; + } + } + + if (isNavigationPropertyCountOnly) { + writeNavigationPropertyCount(property, navigationLink.getInlineEntitySet().getCount(), json); + } else { + if (innerOptions != null && innerOptions.getCountOption() != null + && innerOptions.getCountOption().getValue()) { + writeNavigationPropertyCount(property, navigationLink.getInlineEntitySet().getCount(), json); + } + + writeExpandedNavigationProperty(metadata, property, navigationLink, + innerOptions == null ? null : innerOptions.getExpandOption(), + innerOptions == null ? null : innerOptions.getSelectOption(), json); } - writeExpandedNavigationProperty(metadata, property, navigationLink, - innerOptions == null ? null : innerOptions.getExpandOption(), - innerOptions == null ? null : innerOptions.getSelectOption(), json); } } } } + + private void writeNavigationPropertyCount(final EdmNavigationProperty property, final int count, + final JsonGenerator json) throws IOException { + if (isIEEE754Compatible) { + json.writeStringField(property.getName() + Constants.JSON_COUNT, String.valueOf(count)); + } else { + json.writeNumberField(property.getName() + Constants.JSON_COUNT, count); + } + } + protected void writeExpandedNavigationProperty(final ServiceMetadata metadata, final EdmNavigationProperty property, final Link navigationLink, final ExpandOption innerExpand, final SelectOption innerSelect, final JsonGenerator json) throws IOException, SerializerException { http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e7f8ff84/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/ExpandSelectMock.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/ExpandSelectMock.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/ExpandSelectMock.java index 71a8145..2807282 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/ExpandSelectMock.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/ExpandSelectMock.java @@ -30,8 +30,10 @@ import org.apache.olingo.commons.api.edm.EdmStructuredType; import org.apache.olingo.commons.api.edm.constants.EdmTypeKind; import org.apache.olingo.server.api.uri.UriInfoResource; import org.apache.olingo.server.api.uri.UriResource; +import org.apache.olingo.server.api.uri.UriResourceCount; import org.apache.olingo.server.api.uri.UriResourceNavigation; import org.apache.olingo.server.api.uri.UriResourceProperty; +import org.apache.olingo.server.api.uri.queryoption.CountOption; import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; import org.apache.olingo.server.api.uri.queryoption.SelectItem; @@ -62,6 +64,22 @@ public final class ExpandSelectMock { return resource; } + public static UriInfoResource mockResourceWithCountOnNavigation( + final EdmEntitySet edmEntitySet, final String navigationName) { + + EdmStructuredType type = edmEntitySet.getEntityType(); + List<UriResource> elements = new ArrayList<UriResource>(); + final EdmElement edmElement = type.getProperty(navigationName); + UriResourceNavigation element = Mockito.mock(UriResourceNavigation.class); + Mockito.when(element.getProperty()).thenReturn((EdmNavigationProperty) edmElement); + elements.add(element); + UriResourceCount countResource = Mockito.mock(UriResourceCount.class); + elements.add(countResource); + UriInfoResource resource = Mockito.mock(UriInfoResource.class); + Mockito.when(resource.getUriResourceParts()).thenReturn(elements); + return resource; + } + public static SelectItem mockSelectItem(final EdmEntitySet edmEntitySet, final String... names) { final UriInfoResource resource = mockResource(edmEntitySet, names); SelectItem selectItem = Mockito.mock(SelectItem.class); @@ -76,9 +94,17 @@ public final class ExpandSelectMock { } public static ExpandItem mockExpandItem(final EdmEntitySet edmEntitySet, final String... names) { + return mockExpandItem(edmEntitySet, false, names); + } + + public static ExpandItem mockExpandItem(final EdmEntitySet edmEntitySet, final boolean inlineCount, + final String... names) { final UriInfoResource resource = mockResource(edmEntitySet, names); ExpandItem expandItem = Mockito.mock(ExpandItem.class); Mockito.when(expandItem.getResourcePath()).thenReturn(resource); + CountOption countOption = Mockito.mock(CountOption.class); + Mockito.when(countOption.getValue()).thenReturn(inlineCount); + Mockito.when(expandItem.getCountOption()).thenReturn(countOption); return expandItem; } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e7f8ff84/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java ---------------------------------------------------------------------- diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java index b5da9ae..68b23b1 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java @@ -51,6 +51,7 @@ import org.apache.olingo.server.api.serializer.ReferenceSerializerOptions; import org.apache.olingo.server.api.serializer.SerializerException; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriHelper; +import org.apache.olingo.server.api.uri.UriInfoResource; import org.apache.olingo.server.api.uri.queryoption.CountOption; import org.apache.olingo.server.api.uri.queryoption.ExpandItem; import org.apache.olingo.server.api.uri.queryoption.ExpandOption; @@ -692,6 +693,104 @@ public class ODataJsonSerializerTest { resultString); } + /** + * <code>ESAllPrim$expand=NavPropertyETTwoPrimMany($count)</code> + */ + @Test + public void expandWithInlineOption() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + final Entity entity = data.readAll(edmEntitySet).getEntities().get(2); + final ExpandOption expand = ExpandSelectMock.mockExpandOption(Collections.singletonList( + ExpandSelectMock.mockExpandItem(edmEntitySet, true, "NavPropertyETTwoPrimMany"))); + + InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity, + EntitySerializerOptions.with() + .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()) + .expand(expand) + .build()).getContent(); + + final String resultString = IOUtils.toString(result); + final String expected = "{" + + "\"@odata.context\":\"$metadata#ESAllPrim/$entity\"," + + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + + "\"PropertyInt16\":0," + + "\"PropertyString\":\"\"," + + "\"PropertyBoolean\":false," + + "\"PropertyByte\":0," + + "\"PropertySByte\":0," + + "\"PropertyInt32\":0," + + "\"PropertyInt64\":0," + + "\"PropertySingle\":0.0," + + "\"PropertyDouble\":0.0," + + "\"PropertyDecimal\":0," + + "\"PropertyBinary\":\"\"," + + "\"PropertyDate\":\"1970-01-01\"," + + "\"PropertyDateTimeOffset\":\"2005-12-03T00:00:00Z\"," + + "\"PropertyDuration\":\"PT0S\"," + + "\"PropertyGuid\":\"76543201-23ab-cdef-0123-456789cccddd\"," + + "\"PropertyTimeOfDay\":\"00:01:01\"," + + "\"[email protected]\":3," + + "\"NavPropertyETTwoPrimMany\":[" + + "{" + + "\"PropertyInt16\":32766," + + "\"PropertyString\":\"Test String1\"" + + "},{" + + "\"PropertyInt16\":-32766," + + "\"PropertyString\":null" + + "},{" + + "\"PropertyInt16\":32767," + + "\"PropertyString\":\"Test String4\"" + + "}]}"; + Assert.assertEquals(expected, resultString); + } + + /** + * <code>ESAllPrim$expand=NavPropertyETTwoPrimMany/$count</code> + */ + @Test + public void expandWithCountUri() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); + final Entity entity = data.readAll(edmEntitySet).getEntities().get(2); + + String navName = "NavPropertyETTwoPrimMany"; + final UriInfoResource resource = ExpandSelectMock.mockResourceWithCountOnNavigation(edmEntitySet, navName); + ExpandItem expandItem = Mockito.mock(ExpandItem.class); + Mockito.when(expandItem.getResourcePath()).thenReturn(resource); + + final ExpandOption expand = ExpandSelectMock.mockExpandOption(Collections.singletonList(expandItem)); + + InputStream result = serializer.entity(metadata, edmEntitySet.getEntityType(), entity, + EntitySerializerOptions.with() + .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build()) + .expand(expand) + .build()).getContent(); + + final String resultString = IOUtils.toString(result); + final String expected = "{" + + "\"@odata.context\":\"$metadata#ESAllPrim/$entity\"," + + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + + "\"PropertyInt16\":0," + + "\"PropertyString\":\"\"," + + "\"PropertyBoolean\":false," + + "\"PropertyByte\":0," + + "\"PropertySByte\":0," + + "\"PropertyInt32\":0," + + "\"PropertyInt64\":0," + + "\"PropertySingle\":0.0," + + "\"PropertyDouble\":0.0," + + "\"PropertyDecimal\":0," + + "\"PropertyBinary\":\"\"," + + "\"PropertyDate\":\"1970-01-01\"," + + "\"PropertyDateTimeOffset\":\"2005-12-03T00:00:00Z\"," + + "\"PropertyDuration\":\"PT0S\"," + + "\"PropertyGuid\":\"76543201-23ab-cdef-0123-456789cccddd\"," + + "\"PropertyTimeOfDay\":\"00:01:01\"," + + "\"[email protected]\":3" + + "}"; + Assert.assertEquals(expected, resultString); + } + + @Test public void primitiveProperty() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
