You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/09/11 14:06:08 UTC
git commit: [OLINGO-422] Support for expand in server serializer
Repository: olingo-odata4
Updated Branches:
refs/heads/OLINGO-422-SelectExpandSupport 1976c3407 -> b41129cf9
[OLINGO-422] Support for expand in server serializer
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/b41129cf
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/b41129cf
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/b41129cf
Branch: refs/heads/OLINGO-422-SelectExpandSupport
Commit: b41129cf91401822451e74fe0bff355d9043dc58
Parents: 1976c34
Author: Michael Bolz <mi...@sap.com>
Authored: Thu Sep 11 14:05:43 2014 +0200
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Sep 11 14:05:43 2014 +0200
----------------------------------------------------------------------
.../serializer/json/ODataJsonSerializer.java | 121 ++++++------
.../serializer/utils/ExpandSelectHelper.java | 127 ++++++++++++
.../json/ODataJsonSerializerTest.java | 191 ++++++++++++++++++-
3 files changed, 370 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b41129cf/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 665c258..2e4402b 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
@@ -20,7 +20,6 @@ package org.apache.olingo.server.core.serializer.json;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -29,12 +28,14 @@ import org.apache.olingo.commons.api.Constants;
import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.Link;
import org.apache.olingo.commons.api.data.LinkedComplexValue;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@ -44,12 +45,10 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.server.api.ODataServerError;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializerException;
-import org.apache.olingo.server.api.uri.UriResource;
-import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
-import org.apache.olingo.server.api.uri.queryoption.SelectItem;
import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
import org.apache.olingo.server.core.serializer.utils.ContextURLBuilder;
+import org.apache.olingo.server.core.serializer.utils.ExpandSelectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -143,11 +142,7 @@ public class ODataJsonSerializer implements ODataSerializer {
json.writeNumberField(Constants.JSON_COUNT, entitySet.getCount());
}
json.writeFieldName(Constants.VALUE);
- json.writeStartArray();
- for (Entity entity : entitySet.getEntities()) {
- writeEntity(edmEntitySet, entity, null, options, json);
- }
- json.writeEndArray();
+ writeEntitySet(edmEntitySet.getEntityType(), entitySet, options, json);
if (entitySet.getNext() != null) {
json.writeStringField(Constants.JSON_NEXT_LINK, entitySet.getNext().toASCIIString());
}
@@ -169,7 +164,7 @@ public class ODataJsonSerializer implements ODataSerializer {
CircleStreamBuffer buffer = new CircleStreamBuffer();
try {
JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
- writeEntity(edmEntitySet, entity, contextURL, options, json);
+ writeEntity(edmEntitySet.getEntityType(), entity, contextURL, options, json);
json.close();
} catch (final IOException e) {
throw new ODataSerializerException("An I/O exception occurred.", e,
@@ -178,9 +173,17 @@ public class ODataJsonSerializer implements ODataSerializer {
return buffer.getInputStream();
}
- protected void writeEntity(final EdmEntitySet entitySet, final Entity entity, final ContextURL contextURL,
+ protected void writeEntitySet(final EdmEntityType entityType, final EntitySet entitySet,
+ final ExpandItem options, final JsonGenerator json) throws IOException, ODataSerializerException {
+ json.writeStartArray();
+ for (final Entity entity : entitySet.getEntities()) {
+ writeEntity(entityType, entity, null, options, json);
+ }
+ json.writeEndArray();
+ }
+
+ protected void writeEntity(final EdmEntityType entityType, final Entity entity, final ContextURL contextURL,
final ExpandItem options, final JsonGenerator json) throws IOException, ODataSerializerException {
- final EdmEntityType entityType = entitySet.getEntityType();
json.writeStartObject();
if (format != ODataFormat.JSON_NO_METADATA) {
if (contextURL != null) {
@@ -198,67 +201,66 @@ public class ODataJsonSerializer implements ODataSerializer {
}
}
}
- final boolean all = isAll(options);
- final Set<String> selected = all ? null : getSelectedPropertyNames(options.getSelectOption().getSelectItems());
+ writeProperties(entityType, entity, options, json);
+ writeNavigationProperties(entityType, entity, options, json);
+ json.writeEndObject();
+ }
+
+ protected void writeProperties(final EdmEntityType entityType, final Entity entity, final ExpandItem options,
+ final JsonGenerator json) throws IOException, ODataSerializerException {
+ final boolean all = ExpandSelectHelper.isAll(options);
+ final Set<String> selected = all ? null :
+ ExpandSelectHelper.getSelectedPropertyNames(options.getSelectOption().getSelectItems());
for (final String propertyName : entityType.getPropertyNames()) {
if (all || selected.contains(propertyName)) {
final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
final Property property = entity.getProperty(propertyName);
final Set<List<String>> selectedPaths = all || edmProperty.isPrimitive() ? null :
- getSelectedPaths(options.getSelectOption().getSelectItems(), propertyName);
+ ExpandSelectHelper.getSelectedPaths(options.getSelectOption().getSelectItems(), propertyName);
writeProperty(edmProperty, property, selectedPaths, json);
}
}
- json.writeEndObject();
}
- private boolean isAll(final ExpandItem options) {
- if (options == null || options.getSelectOption() == null
- || options.getSelectOption().getSelectItems() == null
- || options.getSelectOption().getSelectItems().isEmpty()) {
- return true;
- } else {
- for (final SelectItem item : options.getSelectOption().getSelectItems()) {
- if (item.isStar()) {
- return true;
+ protected void writeNavigationProperties(final EdmEntityType entityType, final Entity entity,
+ final ExpandItem options, final JsonGenerator json) throws ODataSerializerException, IOException {
+ if (options != null && (options.isRef() || options.getLevelsOption() != null)) {
+ throw new ODataSerializerException("Expand options $ref and $levels are not supported.",
+ ODataSerializerException.MessageKeys.NOT_IMPLEMENTED);
+ }
+ if (ExpandSelectHelper.hasExpand(options)) {
+ final boolean expandAll = ExpandSelectHelper.isExpandAll(options);
+ final Set<String> expanded = expandAll ? null :
+ ExpandSelectHelper.getExpandedPropertyNames(options.getExpandOption().getExpandItems());
+ for (final String propertyName : entityType.getNavigationPropertyNames()) {
+ if (expandAll || expanded.contains(propertyName)) {
+ final EdmNavigationProperty property = entityType.getNavigationProperty(propertyName);
+ final Link navigationLink = entity.getNavigationLink(property.getName());
+ final ExpandItem innerOptions = expandAll ? null :
+ ExpandSelectHelper.getExpandItem(options.getExpandOption().getExpandItems(), propertyName);
+ writeExpandedNavigationProperty(property, navigationLink, innerOptions, json);
}
}
- return false;
}
}
- private Set<String> getSelectedPropertyNames(final List<SelectItem> selectItems) {
- Set<String> selected = new HashSet<String>();
- for (final SelectItem item : selectItems) {
- final UriResource resource = item.getResourcePath().getUriResourceParts().get(0);
- if (resource instanceof UriResourceProperty) {
- selected.add(((UriResourceProperty) resource).getProperty().getName());
+ protected void writeExpandedNavigationProperty(final EdmNavigationProperty property, final Link navigationLink,
+ final ExpandItem innerOptions, JsonGenerator json) throws IOException, ODataSerializerException {
+ json.writeFieldName(property.getName());
+ if (property.isCollection()) {
+ if (navigationLink == null || navigationLink.getInlineEntitySet() == null) {
+ json.writeStartArray();
+ json.writeEndArray();
+ } else {
+ writeEntitySet(property.getType(), navigationLink.getInlineEntitySet(), innerOptions, json);
}
- }
- return selected;
- }
-
- private Set<List<String>> getSelectedPaths(final List<SelectItem> selectItems, final String propertyName) {
- Set<List<String>> selectedPaths = new HashSet<List<String>>();
- for (final SelectItem item : selectItems) {
- final List<UriResource> parts = item.getResourcePath().getUriResourceParts();
- final UriResource resource = parts.get(0);
- if (resource instanceof UriResourceProperty
- && propertyName.equals(((UriResourceProperty) resource).getProperty().getName())) {
- if (parts.size() > 1) {
- List<String> path = new ArrayList<String>();
- for (final UriResource part : parts.subList(1, parts.size())) {
- if (part instanceof UriResourceProperty) {
- path.add(((UriResourceProperty) part).getProperty().getName());
- }
- }
- selectedPaths.add(path);
- } else {
- return null;
- }
+ } else {
+ if (navigationLink == null || navigationLink.getInlineEntity() == null) {
+ json.writeNull();
+ } else {
+ writeEntity(property.getType(), navigationLink.getInlineEntity(), null, innerOptions, json);
}
}
- return selectedPaths.isEmpty() ? null : selectedPaths;
}
protected void writeProperty(final EdmProperty edmProperty, final Property property,
@@ -338,8 +340,7 @@ public class ODataJsonSerializer implements ODataSerializer {
}
protected void writePrimitiveValue(final EdmProperty edmProperty, final Object primitiveValue,
- final JsonGenerator json)
- throws EdmPrimitiveTypeException, IOException {
+ final JsonGenerator json) throws EdmPrimitiveTypeException, IOException {
final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
final String value = type.valueToString(primitiveValue,
edmProperty.isNullable(), edmProperty.getMaxLength(),
@@ -360,7 +361,7 @@ public class ODataJsonSerializer implements ODataSerializer {
}
}
- private void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
+ protected void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
final Set<List<String>> selectedPaths, JsonGenerator json)
throws IOException, EdmPrimitiveTypeException, ODataSerializerException {
final EdmComplexType type = (EdmComplexType) edmProperty.getType();
@@ -385,7 +386,7 @@ public class ODataJsonSerializer implements ODataSerializer {
return null;
}
- private boolean isSelected(final Set<List<String>> selectedPaths, final String propertyName) {
+ private static boolean isSelected(final Set<List<String>> selectedPaths, final String propertyName) {
for (final List<String> path : selectedPaths) {
if (propertyName.equals(path.get(0))) {
return true;
@@ -394,7 +395,7 @@ public class ODataJsonSerializer implements ODataSerializer {
return false;
}
- private Set<List<String>> getReducedSelectedPaths(final Set<List<String>> selectedPaths,
+ private static Set<List<String>> getReducedSelectedPaths(final Set<List<String>> selectedPaths,
final String propertyName) {
Set<List<String>> reducedPaths = new HashSet<List<String>>();
for (final List<String> path : selectedPaths) {
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b41129cf/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java
new file mode 100644
index 0000000..09bb50d
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ExpandSelectHelper.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.serializer.utils;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.olingo.server.api.serializer.ODataSerializerException;
+import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
+import org.apache.olingo.server.api.uri.UriResourceProperty;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.SelectItem;
+
+public abstract class ExpandSelectHelper {
+
+ public static boolean isAll(final ExpandItem options) {
+ if (options == null || options.getSelectOption() == null
+ || options.getSelectOption().getSelectItems() == null
+ || options.getSelectOption().getSelectItems().isEmpty()) {
+ return true;
+ } else {
+ for (final SelectItem item : options.getSelectOption().getSelectItems()) {
+ if (item.isStar()) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ public static Set<String> getSelectedPropertyNames(final List<SelectItem> selectItems) {
+ Set<String> selected = new HashSet<String>();
+ for (final SelectItem item : selectItems) {
+ final UriResource resource = item.getResourcePath().getUriResourceParts().get(0);
+ if (resource instanceof UriResourceProperty) {
+ selected.add(((UriResourceProperty) resource).getProperty().getName());
+ }
+ }
+ return selected;
+ }
+
+ public static Set<List<String>> getSelectedPaths(final List<SelectItem> selectItems, final String propertyName) {
+ Set<List<String>> selectedPaths = new HashSet<List<String>>();
+ for (final SelectItem item : selectItems) {
+ final List<UriResource> parts = item.getResourcePath().getUriResourceParts();
+ final UriResource resource = parts.get(0);
+ if (resource instanceof UriResourceProperty
+ && propertyName.equals(((UriResourceProperty) resource).getProperty().getName())) {
+ if (parts.size() > 1) {
+ List<String> path = new ArrayList<String>();
+ for (final UriResource part : parts.subList(1, parts.size())) {
+ if (part instanceof UriResourceProperty) {
+ path.add(((UriResourceProperty) part).getProperty().getName());
+ }
+ }
+ selectedPaths.add(path);
+ } else {
+ return null;
+ }
+ }
+ }
+ return selectedPaths.isEmpty() ? null : selectedPaths;
+ }
+
+ public static boolean hasExpand(final ExpandItem options) {
+ return options != null && options.getExpandOption() != null && options.getExpandOption().getExpandItems() != null
+ && !options.getExpandOption().getExpandItems().isEmpty();
+ }
+
+ public static boolean isExpandAll(final ExpandItem options) {
+ for (final ExpandItem item : options.getExpandOption().getExpandItems()) {
+ if (item.isStar()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static Set<String> getExpandedPropertyNames(final List<ExpandItem> expandItems)
+ throws ODataSerializerException {
+ Set<String> expanded = new HashSet<String>();
+ for (final ExpandItem item : expandItems) {
+ final List<UriResource> resourceParts = item.getResourcePath().getUriResourceParts();
+ if (resourceParts.size() == 1) {
+ final UriResource resource = resourceParts.get(0);
+ if (resource instanceof UriResourceNavigation) {
+ expanded.add(((UriResourceNavigation) resource).getProperty().getName());
+ }
+ } else {
+ throw new ODataSerializerException("Expand is not supported within complex properties.",
+ ODataSerializerException.MessageKeys.NOT_IMPLEMENTED);
+ }
+ }
+ return expanded;
+ }
+
+ public static ExpandItem getExpandItem(final List<ExpandItem> expandItems, final String propertyName) {
+ for (final ExpandItem item : expandItems) {
+ final UriResource resource = item.getResourcePath().getUriResourceParts().get(0);
+ if (resource instanceof UriResourceNavigation
+ && propertyName.equals(((UriResourceNavigation) resource).getProperty().getName())) {
+ return item;
+ }
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b41129cf/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 e33e1dd..66363ae 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
@@ -31,19 +31,24 @@ import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.EntitySet;
import org.apache.olingo.commons.api.data.ValueType;
import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmElement;
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializerException;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
+import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourceProperty;
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;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider;
@@ -55,11 +60,11 @@ import org.mockito.Mockito;
public class ODataJsonSerializerTest {
- private final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
- private final EdmEntityContainer entityContainer = edm.getEntityContainer(
+ private static final Edm edm = OData.newInstance().createEdm(new EdmTechProvider());
+ private static final EdmEntityContainer entityContainer = edm.getEntityContainer(
new FullQualifiedName("olingo.odata.test1", "Container"));
private final DataProvider data = new DataProvider();
- private ODataSerializer serializer = new ODataJsonSerializer(ODataFormat.JSON);
+ private final ODataSerializer serializer = new ODataJsonSerializer(ODataFormat.JSON);
@Test
public void entitySimple() throws Exception {
@@ -399,18 +404,173 @@ public class ODataJsonSerializerTest {
resultString);
}
- private SelectItem mockSelectItem(final EdmEntitySet edmEntitySet, final String... names) {
+ @Test
+ public void expand() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
+ final Entity entity = data.readAll(edmEntitySet).getEntities().get(3);
+ final ExpandOption expand = mockExpandOption(Arrays.asList(
+ mockExpandItem(edmEntitySet, "NavPropertyETAllPrimOne")));
+ ExpandItem options = Mockito.mock(ExpandItem.class);
+ Mockito.when(options.getExpandOption()).thenReturn(expand);
+ InputStream result = serializer.entity(edmEntitySet, entity,
+ ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build(),
+ options);
+ final String resultString = IOUtils.toString(result);
+ Assert.assertEquals("{\"@odata.context\":\"$metadata#ESTwoPrim/$entity\","
+ + "\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\","
+ + "\"NavPropertyETAllPrimOne\":{"
+ + "\"PropertyInt16\":32767,"
+ + "\"PropertyString\":\"First Resource - positive values\","
+ + "\"PropertyBoolean\":true,"
+ + "\"PropertyByte\":255,"
+ + "\"PropertySByte\":127,"
+ + "\"PropertyInt32\":2147483647,"
+ + "\"PropertyInt64\":9223372036854775807,"
+ + "\"PropertySingle\":1.79E20,"
+ + "\"PropertyDouble\":-1.79E19,"
+ + "\"PropertyDecimal\":34,"
+ + "\"PropertyBinary\":\"ASNFZ4mrze8=\","
+ + "\"PropertyDate\":\"2012-12-03\","
+ + "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\","
+ + "\"PropertyDuration\":\"PT6S\","
+ + "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\","
+ + "\"PropertyTimeOfDay\":\"03:26:05\"}}",
+ resultString);
+ }
+
+ @Test
+ public void expandSelect() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
+ final Entity entity = data.readAll(edmEntitySet).getEntities().get(3);
+ final SelectOption select = mockSelectOption(Arrays.asList(
+ mockSelectItem(entityContainer.getEntitySet("ESAllPrim"), "PropertyDate")));
+ ExpandItem expandItem = mockExpandItem(edmEntitySet, "NavPropertyETAllPrimOne");
+ Mockito.when(expandItem.getSelectOption()).thenReturn(select);
+ final ExpandOption expand = mockExpandOption(Arrays.asList(expandItem));
+ ExpandItem options = Mockito.mock(ExpandItem.class);
+ Mockito.when(options.getExpandOption()).thenReturn(expand);
+ InputStream result =
+ new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
+ .entity(edmEntitySet, entity,
+ null, // ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build(),
+ options);
+ final String resultString = IOUtils.toString(result);
+ Assert.assertEquals("{"
+ // + "\"@odata.context\":\"$metadata#ESTwoPrim(NavPropertyETAllPrimOne(PropertyDate))/$entity\","
+ + "\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\","
+ + "\"NavPropertyETAllPrimOne\":{\"PropertyDate\":\"2012-12-03\"}}",
+ resultString);
+ }
+
+ @Test
+ public void expandAll() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+ final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
+ final ExpandItem expandItem = mockExpandItem(edmEntitySet, "NavPropertyETTwoPrimOne");
+ ExpandItem expandItemAll = Mockito.mock(ExpandItem.class);
+ Mockito.when(expandItemAll.isStar()).thenReturn(true);
+ final ExpandOption expand = mockExpandOption(Arrays.asList(expandItem, expandItem, expandItemAll));
+ final SelectOption select = mockSelectOption(Arrays.asList(mockSelectItem(edmEntitySet, "PropertySByte")));
+ ExpandItem options = Mockito.mock(ExpandItem.class);
+ Mockito.when(options.getExpandOption()).thenReturn(expand);
+ Mockito.when(options.getSelectOption()).thenReturn(select);
+ InputStream result =
+ new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
+ .entity(edmEntitySet, entity,
+ null, // ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build(),
+ options);
+ final String resultString = IOUtils.toString(result);
+ Assert.assertEquals("{"
+ // + "\"@odata.context\":\"$metadata#ESAllPrim(PropertySByte)/$entity\","
+ + "\"PropertySByte\":127,"
+ + "\"NavPropertyETTwoPrimOne\":{\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\"},"
+ + "\"NavPropertyETTwoPrimMany\":[{\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\"}]}",
+ resultString);
+ }
+
+ @Test
+ public void expandNoData() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+ final Entity entity = data.readAll(edmEntitySet).getEntities().get(1);
+ ExpandItem expandItemAll = Mockito.mock(ExpandItem.class);
+ Mockito.when(expandItemAll.isStar()).thenReturn(true);
+ final ExpandOption expand = mockExpandOption(Arrays.asList(expandItemAll));
+ final SelectOption select = mockSelectOption(Arrays.asList(mockSelectItem(edmEntitySet, "PropertyTimeOfDay")));
+ ExpandItem options = Mockito.mock(ExpandItem.class);
+ Mockito.when(options.getExpandOption()).thenReturn(expand);
+ Mockito.when(options.getSelectOption()).thenReturn(select);
+ InputStream result =
+ new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
+ .entity(edmEntitySet, entity,
+ null, // ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build(),
+ options);
+ final String resultString = IOUtils.toString(result);
+ Assert.assertEquals("{"
+ // + "\"@odata.context\":\"$metadata#ESAllPrim(PropertyTimeOfDay)/$entity\","
+ + "\"PropertyTimeOfDay\":\"23:49:14\","
+ + "\"NavPropertyETTwoPrimOne\":null,\"NavPropertyETTwoPrimMany\":[]}",
+ resultString);
+ }
+
+ @Test
+ public void expandTwoLevels() throws Exception {
+ final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
+ final EdmEntitySet innerEntitySet = entityContainer.getEntitySet("ESAllPrim");
+ final Entity entity = data.readAll(edmEntitySet).getEntities().get(1);
+ ExpandItem expandItemSecond = Mockito.mock(ExpandItem.class);
+ Mockito.when(expandItemSecond.isStar()).thenReturn(true);
+ final ExpandOption expandInner = mockExpandOption(Arrays.asList(expandItemSecond));
+ ExpandItem expandItemFirst = mockExpandItem(edmEntitySet, "NavPropertyETAllPrimMany");
+ Mockito.when(expandItemFirst.getExpandOption()).thenReturn(expandInner);
+ final SelectOption select = mockSelectOption(Arrays.asList(
+ mockSelectItem(innerEntitySet, "PropertyInt32")));
+ Mockito.when(expandItemFirst.getSelectOption()).thenReturn(select);
+ final ExpandOption expand = mockExpandOption(Arrays.asList(expandItemFirst));
+ ExpandItem options = Mockito.mock(ExpandItem.class);
+ Mockito.when(options.getExpandOption()).thenReturn(expand);
+ InputStream result =
+ new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA) // serializer
+ .entity(edmEntitySet, entity,
+ null, // ContextURL.Builder.create().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build(),
+ options);
+ final String resultString = IOUtils.toString(result);
+ Assert.assertEquals("{"
+ // + "\"@odata.context\":\"$metadata#ESTwoPrim(NavPropertyETAllPrimMany(PropertyInt32))/$entity\","
+ + "\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\","
+ + "\"NavPropertyETAllPrimMany\":["
+ + "{\"PropertyInt32\":-2147483648,\"NavPropertyETTwoPrimOne\":null,\"NavPropertyETTwoPrimMany\":[]},"
+ + "{\"PropertyInt32\":0,\"NavPropertyETTwoPrimOne\":null,"
+ + "\"NavPropertyETTwoPrimMany\":["
+ + "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"},"
+ + "{\"PropertyInt16\":-32766,\"PropertyString\":\"Test String3\"},"
+ + "{\"PropertyInt16\":32767,\"PropertyString\":\"Test String4\"}]}]}",
+ resultString);
+ }
+
+ private UriInfoResource mockResource(final EdmEntitySet edmEntitySet, final String... names) {
EdmStructuredType type = edmEntitySet.getEntityType();
List<UriResource> elements = new ArrayList<UriResource>();
for (final String name : Arrays.asList(names)) {
- UriResourceProperty element = Mockito.mock(UriResourceProperty.class);
- final EdmProperty property = (EdmProperty) type.getProperty(name);
- Mockito.when(element.getProperty()).thenReturn(property);
- elements.add(element);
- type = property.isPrimitive() ? null : (EdmStructuredType) property.getType();
+ final EdmElement edmElement = type.getProperty(name);
+ if (edmElement.getType().getKind() == EdmTypeKind.ENTITY) {
+ UriResourceNavigation element = Mockito.mock(UriResourceNavigation.class);
+ Mockito.when(element.getProperty()).thenReturn((EdmNavigationProperty) edmElement);
+ elements.add(element);
+ } else {
+ final EdmProperty property = (EdmProperty) edmElement;
+ UriResourceProperty element = Mockito.mock(UriResourceProperty.class);
+ Mockito.when(element.getProperty()).thenReturn(property);
+ elements.add(element);
+ type = property.isPrimitive() ? null : (EdmStructuredType) property.getType();
+ }
}
UriInfoResource resource = Mockito.mock(UriInfoResource.class);
Mockito.when(resource.getUriResourceParts()).thenReturn(elements);
+ return resource;
+ }
+
+ private SelectItem mockSelectItem(final EdmEntitySet edmEntitySet, final String... names) {
+ final UriInfoResource resource = mockResource(edmEntitySet, names);
SelectItem selectItem = Mockito.mock(SelectItem.class);
Mockito.when(selectItem.getResourcePath()).thenReturn(resource);
return selectItem;
@@ -421,4 +581,17 @@ public class ODataJsonSerializerTest {
Mockito.when(select.getSelectItems()).thenReturn(selectItems);
return select;
}
+
+ private ExpandItem mockExpandItem(final EdmEntitySet edmEntitySet, final String... names) {
+ final UriInfoResource resource = mockResource(edmEntitySet, names);
+ ExpandItem expandItem = Mockito.mock(ExpandItem.class);
+ Mockito.when(expandItem.getResourcePath()).thenReturn(resource);
+ return expandItem;
+ }
+
+ private ExpandOption mockExpandOption(final List<ExpandItem> expandItems) {
+ ExpandOption expand = Mockito.mock(ExpandOption.class);
+ Mockito.when(expand.getExpandItems()).thenReturn(expandItems);
+ return expand;
+ }
}