From 48f93fd871d386edfefb4f524efd5b9fe5c63de0 Mon Sep 17 00:00:00 2001 From: ramya vasanth Date: Wed, 21 Feb 2018 10:20:51 +0530 Subject: [PATCH] [OLINGO-1231] Serializer for complex collection properties does not respect --- .../http/SelectOnComplexPropertiesITCase.java | 164 ++++++++++++++++++ .../serializer/json/ODataJsonSerializer.java | 8 +- .../serializer/utils/ExpandSelectHelper.java | 22 +++ .../serializer/xml/ODataXmlSerializer.java | 8 +- .../core/serializer/ExpandSelectMock.java | 24 +++ .../json/ODataJsonSerializerTest.java | 90 +++++++++- .../xml/ODataXmlSerializerTest.java | 35 ++++ 7 files changed, 346 insertions(+), 5 deletions(-) create mode 100644 fit/src/test/java/org/apache/olingo/fit/tecsvc/http/SelectOnComplexPropertiesITCase.java diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/SelectOnComplexPropertiesITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/SelectOnComplexPropertiesITCase.java new file mode 100644 index 000000000..207acf6e7 --- /dev/null +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/SelectOnComplexPropertiesITCase.java @@ -0,0 +1,164 @@ +/* + * 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.fit.tecsvc.http; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.net.HttpURLConnection; +import java.net.URL; + +import org.apache.commons.io.IOUtils; +import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.commons.api.format.ContentType; +import org.apache.olingo.commons.api.http.HttpHeader; +import org.apache.olingo.commons.api.http.HttpMethod; +import org.apache.olingo.commons.api.http.HttpStatusCode; +import org.apache.olingo.fit.AbstractBaseTestITCase; +import org.apache.olingo.fit.tecsvc.TecSvcConst; +import org.junit.Test; + +public class SelectOnComplexPropertiesITCase extends AbstractBaseTestITCase { + + private static final String SERVICE_URI = TecSvcConst.BASE_URI + "/"; + + @Test + public void queryESKeyColPropertyComp1() throws Exception { + URL url = new URL(SERVICE_URI + "ESKeyNav(1)/CollPropertyComp" + + "?$select=PropertyComp/PropertyString"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=minimal"); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + assertTrue(content.contains("\"value\":[{\"PropertyComp\":" + + "{\"PropertyString\":\"First Resource - positive values\"}}," + + "{\"PropertyComp\":{\"PropertyString\":\"First Resource - positive values\"}}," + + "{\"PropertyComp\":{\"PropertyString\":\"First Resource - positive values\"}}]")); + } + + @Test + public void queryESKeyColPropertyComp2() throws Exception { + URL url = new URL(SERVICE_URI + "ESKeyNav(1)/CollPropertyComp" + + "?$select=PropertyInt16"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=minimal"); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + assertTrue(content.contains("\"value\":[{\"PropertyInt16\":1},{\"PropertyInt16\":2},{\"PropertyInt16\":3}]")); + } + + @Test + public void queryESKeyColPropertyComp3() throws Exception { + URL url = new URL(SERVICE_URI + "ESKeyNav(1)/CollPropertyComp" + + "?$select=PropertyComp"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=minimal"); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + System.out.println("Content is::"+ content); + assertTrue(content.contains("\"value\":[{\"PropertyComp\":{" + + "\"PropertyString\":\"First Resource - positive values\"," + + "\"PropertyBinary\":\"ASNFZ4mrze8=\",\"PropertyBoolean\":true," + + "\"PropertyByte\":255,\"PropertyDate\":\"2012-12-03\"," + + "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," + + "\"PropertyDecimal\":34,\"PropertySingle\":1.79E20," + + "\"PropertyDouble\":-1.79E20,\"PropertyDuration\":\"PT6S\"," + + "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," + + "\"PropertyInt16\":32767,\"PropertyInt32\":2147483647," + + "\"PropertyInt64\":9223372036854775807,\"PropertySByte\":127," + + "\"PropertyTimeOfDay\":\"21:05:59\"}},{\"PropertyComp\":" + + "{\"PropertyString\":\"First Resource - positive values\"," + + "\"PropertyBinary\":\"ASNFZ4mrze8=\",\"PropertyBoolean\":true," + + "\"PropertyByte\":255,\"PropertyDate\":\"2012-12-03\"," + + "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," + + "\"PropertyDecimal\":34,\"PropertySingle\":1.79E20," + + "\"PropertyDouble\":-1.79E20,\"PropertyDuration\":\"PT6S\"," + + "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," + + "\"PropertyInt16\":32767,\"PropertyInt32\":2147483647," + + "\"PropertyInt64\":9223372036854775807,\"PropertySByte\":127," + + "\"PropertyTimeOfDay\":\"21:05:59\"}},{\"PropertyComp\":" + + "{\"PropertyString\":\"First Resource - positive values\"," + + "\"PropertyBinary\":\"ASNFZ4mrze8=\",\"PropertyBoolean\":true," + + "\"PropertyByte\":255,\"PropertyDate\":\"2012-12-03\"," + + "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"," + + "\"PropertyDecimal\":34,\"PropertySingle\":1.79E20," + + "\"PropertyDouble\":-1.79E20,\"PropertyDuration\":\"PT6S\"," + + "\"PropertyGuid\":\"01234567-89ab-cdef-0123-456789abcdef\"," + + "\"PropertyInt16\":32767,\"PropertyInt32\":2147483647," + + "\"PropertyInt64\":9223372036854775807,\"PropertySByte\":127," + + "\"PropertyTimeOfDay\":\"21:05:59\"}}]")); + } + + @Test + public void queryESKeyPropertyCompCompNav() throws Exception { + URL url = new URL(SERVICE_URI + "ESKeyNav(1)/PropertyCompCompNav" + + "?$select=PropertyCompNav/PropertyInt16"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=minimal"); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON, ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + assertTrue(content.contains("\"PropertyCompNav\":{\"PropertyInt16\":1}")); + connection.disconnect(); + } + + @Test + public void queryESCompCollDerivedWithMixedComplexTypes() throws Exception { + URL url = new URL(SERVICE_URI + "ESCompCollDerived(12345)/" + + "CollPropertyCompAno?$select=PropertyString"); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.GET.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json;odata.metadata=full"); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + assertEquals(ContentType.JSON_FULL_METADATA, ContentType.create( + connection.getHeaderField(HttpHeader.CONTENT_TYPE))); + + final String content = IOUtils.toString(connection.getInputStream()); + assertTrue(content.contains("\"@odata.type\":\"#Collection(olingo.odata.test1.CTTwoPrimAno)\"," + + "\"value\":[{\"@odata.type\":\"#olingo.odata.test1.CTBaseAno\"," + + "\"PropertyString\":\"TEST12345\"},{\"@odata.type\":" + + "\"#olingo.odata.test1.CTTwoPrimAno\",\"PropertyString\":\"TESTabcd\"}]")); + } + + @Override + protected ODataClient getClient() { + return null; + } +} 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 b2273197a..9d9c47abd 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 @@ -1203,7 +1203,13 @@ public class ODataJsonSerializer extends AbstractODataSerializer { } writeOperations(property.getOperations(), json); json.writeFieldName(Constants.VALUE); - writeComplexCollection(metadata, type, property, null, json); + Set> selectedPaths = null; + if (null != options && null != options.getSelect()) { + final boolean all = ExpandSelectHelper.isAll(options.getSelect()); + selectedPaths = all || property.isPrimitive() ? null : ExpandSelectHelper + .getSelectedPaths(options.getSelect().getSelectItems()); + } + writeComplexCollection(metadata, type, property, selectedPaths, json); json.writeEndObject(); json.close(); 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 index 9633f70f8..a6e5012a4 100644 --- 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 @@ -85,6 +85,28 @@ public abstract class ExpandSelectHelper { return selectedPaths.isEmpty() ? null : selectedPaths; } + public static Set> getSelectedPaths(final List selectItems) { + Set> selectedPaths = new HashSet>(); + for (final SelectItem item : selectItems) { + final List parts = item.getResourcePath().getUriResourceParts(); + final UriResource resource = parts.get(0); + if (resource instanceof UriResourceProperty) { + if (parts.size() > 0) { + List path = new ArrayList(); + for (final UriResource part : parts.subList(0, 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 isSelected(final Set> selectedPaths, final String propertyName) { for (final List path : selectedPaths) { if (propertyName.equals(path.get(0))) { diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java index 80ba2b7d4..4c1524bab 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java @@ -1176,7 +1176,13 @@ public class ODataXmlSerializer extends AbstractODataSerializer { writer.writeAttribute(METADATA, NS_METADATA, Constants.CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString()); writeMetadataETag(metadata, writer); - writeComplexCollection(metadata, type, property, null, + Set> selectedPaths = null; + if (null != options && null != options.getSelect()) { + final boolean all = ExpandSelectHelper.isAll(options.getSelect()); + selectedPaths = all || property.isPrimitive() ? null : ExpandSelectHelper + .getSelectedPaths(options.getSelect().getSelectItems()); + } + writeComplexCollection(metadata, type, property, selectedPaths, options == null ? null:options.xml10InvalidCharReplacement(), writer); writer.writeEndElement(); writer.writeEndDocument(); 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 71a8145c3..5c9ab1695 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 @@ -87,4 +87,28 @@ public final class ExpandSelectMock { Mockito.when(expand.getExpandItems()).thenReturn(expandItems); return expand; } + + /** + * @param resource + * @return + */ + public static SelectItem mockSelectItemForColComplexProperty(final UriInfoResource resource) { + SelectItem selectItem = Mockito.mock(SelectItem.class); + Mockito.when(selectItem.getResourcePath()).thenReturn(resource); + return selectItem; + } + + /** + * @param propertyWithinCT + * @return + */ + public static UriInfoResource mockComplexTypeResource(final EdmProperty propertyWithinCT) { + final UriInfoResource resource = Mockito.mock(UriInfoResource.class); + final List elements = new ArrayList(); + final UriResourceProperty element = Mockito.mock(UriResourceProperty.class); + Mockito.when(element.getProperty()).thenReturn(propertyWithinCT); + elements.add(element); + Mockito.when(resource.getUriResourceParts()).thenReturn(elements); + return resource; + } } 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 80b00fd25..c3e8dad00 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 @@ -19,6 +19,7 @@ package org.apache.olingo.server.core.serializer.json; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; @@ -51,15 +52,15 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.FullQualifiedName; -import org.apache.olingo.commons.api.edm.geo.Point; -import org.apache.olingo.commons.api.edm.geo.Polygon; -import org.apache.olingo.commons.api.edm.geo.SRID; import org.apache.olingo.commons.api.edm.geo.Geospatial.Dimension; import org.apache.olingo.commons.api.edm.geo.GeospatialCollection; import org.apache.olingo.commons.api.edm.geo.LineString; import org.apache.olingo.commons.api.edm.geo.MultiLineString; import org.apache.olingo.commons.api.edm.geo.MultiPoint; import org.apache.olingo.commons.api.edm.geo.MultiPolygon; +import org.apache.olingo.commons.api.edm.geo.Point; +import org.apache.olingo.commons.api.edm.geo.Polygon; +import org.apache.olingo.commons.api.edm.geo.SRID; import org.apache.olingo.commons.api.edmx.EdmxReference; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.server.api.OData; @@ -77,6 +78,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; @@ -2592,4 +2594,86 @@ public class ODataJsonSerializerTest { Assert.assertEquals(expected, resultString); } + + @Test + public void complexCollectionWithSelectProperty() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESKeyNav"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + final EdmComplexType complexType = metadata.getEdm().getComplexType( + new FullQualifiedName("olingo.odata.test1", "CTPrimComp")); + final EdmProperty propertyWithinCT = (EdmProperty) complexType.getProperty("PropertyInt16"); + + final UriInfoResource resource = ExpandSelectMock.mockComplexTypeResource(propertyWithinCT); + final SelectItem selectItem = ExpandSelectMock.mockSelectItemForColComplexProperty(resource); + final SelectOption selectOption = ExpandSelectMock.mockSelectOption(Arrays.asList(selectItem)); + + final String resultString = IOUtils.toString(serializer + .complexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, + ComplexSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("1") + .navOrPropertyPath("CollPropertyComp") + .build()).select(selectOption) + .build()).getContent()); + Assert.assertEquals("{\"@odata.context\":\"$metadata#ESKeyNav(1)/CollPropertyComp\"," + + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + + "\"value\":[{\"PropertyInt16\":1},{\"PropertyInt16\":2},{\"PropertyInt16\":3}]}", + resultString); + } + + @Test + public void complexCollectionPropertyWithSelectNoMetadata() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESKeyNav"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + + final EdmComplexType complexType = metadata.getEdm().getComplexType( + new FullQualifiedName("olingo.odata.test1", "CTPrimComp")); + final EdmProperty propertyWithinCT = (EdmProperty) complexType.getProperty("PropertyInt16"); + + final UriInfoResource resource = ExpandSelectMock.mockComplexTypeResource(propertyWithinCT); + final SelectItem selectItem = ExpandSelectMock.mockSelectItemForColComplexProperty(resource); + final SelectOption selectOption = ExpandSelectMock.mockSelectOption(Arrays.asList(selectItem)); + + final String resultString = IOUtils.toString(serializerNoMetadata + .complexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, ComplexSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("1") + .navOrPropertyPath("CollPropertyComp") + .build()).select(selectOption).build()).getContent()); + Assert.assertEquals("{\"value\":[{\"PropertyInt16\":1},{\"PropertyInt16\":2},{\"PropertyInt16\":3}]}", + resultString); + } + + @Test + public void complexCollectionPropertyWithSelectWithMetadataFull() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESKeyNav"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp"); + + final EdmComplexType complexType = metadata.getEdm().getComplexType( + new FullQualifiedName("olingo.odata.test1", "CTPrimComp")); + final EdmProperty propertyWithinCT = (EdmProperty) complexType.getProperty("PropertyInt16"); + + final UriInfoResource resource = ExpandSelectMock.mockComplexTypeResource(propertyWithinCT); + final SelectItem selectItem = ExpandSelectMock.mockSelectItemForColComplexProperty(resource); + final SelectOption selectOption = ExpandSelectMock.mockSelectOption(Arrays.asList(selectItem)); + + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + final String resultString = IOUtils.toString(serializerFullMetadata + .complexCollection(metadata, (EdmComplexType) edmProperty.getType(), + property, ComplexSerializerOptions.with() + .contextURL(ContextURL.with().entitySet(edmEntitySet) + .keyPath("1") + .navOrPropertyPath("CollPropertyComp").build()) + .select(selectOption) + .build()) + .getContent()); + assertTrue(resultString.contains("\"value\":[{\"@odata.type\":\"#olingo.odata.test1.CTPrimComp\"," + + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":1}," + + "{\"@odata.type\":\"#olingo.odata.test1.CTPrimComp\"," + + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":2}," + + "{\"@odata.type\":\"#olingo.odata.test1.CTPrimComp\"," + + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":3}]")); + } } diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java index c8476e3c5..c1f112da6 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java @@ -42,6 +42,7 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmProperty; +import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.edmx.EdmxReference; import org.apache.olingo.commons.api.format.ContentType; import org.apache.olingo.server.api.OData; @@ -56,6 +57,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; @@ -3176,4 +3178,37 @@ public class ODataXmlSerializerTest { public void skippedComparison(Node control, Node test) { } }; + @Test + public void complexCollectionWithSelectProperty() throws Exception { + final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESKeyNav"); + final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp"); + final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName()); + final EdmComplexType complexType = metadata.getEdm().getComplexType( + new FullQualifiedName("olingo.odata.test1", "CTPrimComp")); + final EdmProperty propertyWithinCT = (EdmProperty) complexType.getProperty("PropertyInt16"); + + final UriInfoResource resource = ExpandSelectMock.mockComplexTypeResource(propertyWithinCT); + final SelectItem selectItem = ExpandSelectMock.mockSelectItemForColComplexProperty(resource); + final SelectOption selectOption = ExpandSelectMock.mockSelectOption(Arrays.asList(selectItem)); + + final String resultString = IOUtils.toString(serializer + .complexCollection(metadata, (EdmComplexType) edmProperty.getType(), property, + ComplexSerializerOptions.with() + .contextURL(ContextURL.with() + .entitySet(edmEntitySet).keyPath("1") + .navOrPropertyPath("CollPropertyComp") + .build()).select(selectOption) + .build()).getContent()); + final String expectedResult = "" + + "" + + "1" + + "2" + + "3" + + ""; + Assert.assertEquals(expectedResult, resultString); + } }