This is an automated email from the ASF dual-hosted git repository. archanarai pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/olingo-odata4.git
The following commit(s) were added to refs/heads/master by this push: new f344a3c [OLINGO-1323]OData v4.0: Context url should have navigation properties within when expanded f344a3c is described below commit f344a3c565b6a67233de1d1169104a728136e7a3 Author: Archana Rai <archana....@sap.com> AuthorDate: Thu Dec 13 16:10:10 2018 +0530 [OLINGO-1323]OData v4.0: Context url should have navigation properties within when expanded --- .../core/serializer/json/ODataJsonSerializer.java | 2 +- .../core/serializer/utils/ContextURLHelper.java | 26 ++++++++++++++--- .../olingo/server/tecsvc/data/DataCreator.java | 12 ++++++++ .../tecsvc/processor/TechnicalActionProcessor.java | 3 +- .../tecsvc/processor/TechnicalEntityProcessor.java | 2 +- .../serializer/json/ODataJsonSerializerTest.java | 23 ++++++++++----- .../json/ODataJsonSerializerv01Test.java | 34 +++++++++++++--------- .../serializer/utils/ContextURLHelperTest.java | 3 +- .../serializer/xml/ODataXmlSerializerTest.java | 9 ++++-- 9 files changed, 82 insertions(+), 32 deletions(-) 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 31029f2..65f9675 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 @@ -1131,7 +1131,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer { writeContextURL(contextURL, json); writeMetadataETag(metadata, json); writeOperations(property.getOperations(), json); - if (property.isNull()) { + if (property.isNull() && options!=null && options.isNullable() != null && !options.isNullable()) { throw new SerializerException("Property value can not be null.", SerializerException.MessageKeys.NULL_INPUT); } else { json.writeFieldName(Constants.VALUE); diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java index 8352ef4..6e20ef4 100644 --- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java +++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java @@ -67,6 +67,8 @@ public final class ContextURLHelper { if (ExpandSelectHelper.hasExpand(expand) && !(null != ExpandSelectHelper.getExpandAll(expand))) { handleExpand(type, expand, result); + }else if(expand != null && null != ExpandSelectHelper.getExpandAll(expand)){ + handleExpandAll(type, expand, result); } return result.length() == 0 ? null : result.toString(); } @@ -267,6 +269,8 @@ public final class ContextURLHelper { final Set<String> expandedPropertyNames = ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems()); for (final String propertyName : type.getNavigationPropertyNames()) { if (expandedPropertyNames.contains(propertyName)) { + + final ExpandItem expandItem = ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName); if (ExpandSelectHelper.hasExpand(expandItem.getExpandOption()) && !(null != ExpandSelectHelper.getExpandAll(expandItem.getExpandOption())) @@ -290,15 +294,29 @@ public final class ContextURLHelper { result.append(Encoder.encode(propertyName)); result.append("/").append(propertyPath); } else { - if (result.length() > 0) { - result.append(','); - } - result.append(Encoder.encode(propertyName) + "()"); + appendExpandedProperty(result, propertyName); } } + + } } } + + private static void handleExpandAll(final EdmStructuredType type, + final ExpandOption expand, final StringBuilder result) throws SerializerException { + for (final String propertyName : type.getNavigationPropertyNames()) { + appendExpandedProperty(result, propertyName); + } + } + + private static void appendExpandedProperty(StringBuilder result, String propertyName) + throws SerializerException { + if (result.length() > 0) { + result.append(','); + } + result.append(Encoder.encode(propertyName) + "()"); + } private static List<String> getPropertyPath(final List<UriResource> path) { List<String> result = new LinkedList<String>(); diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java index cd6fdf0..898fc39 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java @@ -1924,6 +1924,7 @@ public class DataCreator { final EntityCollection entityCollection = data.get("ESKeyNavCont"); final List<Entity> targetEntities = data.get("ETCont").getEntities(); final List<Entity> etBaseContEntities = data.get("ETBaseCont").getEntities(); + final List<Entity> etTwoKeyNav = data.get("ESTwoKeyNav").getEntities(); setLinks(entityCollection.getEntities().get(1), "NavPropertyETContMany", targetEntities.get(1), targetEntities.get(2)); @@ -1932,6 +1933,11 @@ public class DataCreator { setLinks(entityCollection.getEntities().get(2), "NavPropertyETBaseContMany", etBaseContEntities.get(1), etBaseContEntities.get(2)); + + setLinks(entityCollection.getEntities().get(4), "NavPropertyETTwoKeyNavMany", etTwoKeyNav.get(0), + etTwoKeyNav.get(2)); + + setLinkForContNav(entityCollection.getEntities().get(4), "NavPropertyETTwoKeyNavOne", etTwoKeyNav.get(0)); } protected static void setLinkForContNav(final Entity entity, @@ -2133,6 +2139,12 @@ public class DataCreator { .addProperty(createPrimitive("PropertyString", "Test String4")) .addProperty(createComplex("PropertyCompNavCont", ComplexTypeProvider.nameCTNavCont.getFullQualifiedNameAsString()))); + + entityCollection.getEntities().add(new Entity() + .addProperty(createPrimitive("PropertyInt16", (short) 1)) + .addProperty(createPrimitive("PropertyString", "Test String1")) + .addProperty(createComplex("PropertyCompNavCont", + ComplexTypeProvider.nameCTNavCont.getFullQualifiedNameAsString()))); setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETKeyNavCont)); createEntityId(edm, odata, "ESKeyNavCont", entityCollection); diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java index c4964a2..5b64685 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java @@ -296,7 +296,8 @@ public class TechnicalActionProcessor extends TechnicalProcessor final Return returnPreference = odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn(); if (returnPreference == null || returnPreference == Return.REPRESENTATION) { final EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType(); - final ContextURL contextURL = ContextURL.with().type(type).asCollection().build(); + final ContextURL contextURL = ContextURL.with().type(type).navOrPropertyPath(action.getName()) + .asCollection().build(); final PrimitiveSerializerOptions options = PrimitiveSerializerOptions.with().contextURL(contextURL).build(); final SerializerResult result = odata.createSerializer(responseFormat).primitiveCollection(serviceMetadata, type, property, options); diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java index c5256db..77a624e 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java @@ -711,7 +711,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor response.setHeader(HttpHeader.PREFERENCE_APPLIED, PreferencesApplied.with().trackChanges().build().toValueString()); } - if(delta!=null){ + if(delta!=null && request.getHeaders(HttpHeader.ODATA_MAX_VERSION) != null){ response.setHeader(HttpHeader.ODATA_VERSION,request.getHeaders(HttpHeader.ODATA_MAX_VERSION).get(0)); } } 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 ec9482b..786403e 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 @@ -1530,7 +1530,8 @@ public class ODataJsonSerializerTest { .select(select) .build()).getContent()); Assert.assertEquals("{" - + "\"@odata.context\":\"$metadata#ESAllPrim(PropertyInt16,PropertySByte)/$entity\"," + + "\"@odata.context\":\"$metadata#ESAllPrim(PropertyInt16,PropertySByte," + + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany())/$entity\"," + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"@odata.id\":\"ESAllPrim(32767)\",\"PropertyInt16\":32767," + "\"PropertySByte\":127," @@ -1559,7 +1560,8 @@ public class ODataJsonSerializerTest { .select(select) .build()).getContent()); Assert.assertEquals("{" - + "\"@odata.context\":\"$metadata#ESAllPrim(PropertyInt16,PropertyTimeOfDay)/$entity\"," + + "\"@odata.context\":\"$metadata#ESAllPrim(PropertyInt16,PropertyTimeOfDay," + + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany())/$entity\"," + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"@odata.id\":\"ESAllPrim(-32768)\",\"PropertyInt16\":-32768," + "\"PropertyTimeOfDay\":\"23:49:14\"," @@ -1592,7 +1594,8 @@ public class ODataJsonSerializerTest { .build()).getContent()); Assert.assertEquals("{" + "\"@odata.context\":\"$metadata#ESTwoPrim(PropertyInt16," - + "NavPropertyETAllPrimMany(PropertyInt16,PropertyInt32))/$entity\"," + + "NavPropertyETAllPrimMany(PropertyInt16,PropertyInt32," + + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany()))/$entity\"," + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\"," + "\"NavPropertyETAllPrimMany\":[" @@ -1630,7 +1633,8 @@ public class ODataJsonSerializerTest { .suffix(Suffix.ENTITY).build()) .expand(expand) .build()).getContent()); - Assert.assertEquals("{\"@odata.context\":\"$metadata#ESTwoPrim(PropertyInt16)/$entity\"," + Assert.assertEquals("{\"@odata.context\":\"$metadata#ESTwoPrim(PropertyInt16," + + "NavPropertyETAllPrimOne(),NavPropertyETAllPrimMany())/$entity\"," + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\"," + "\"NavPropertyETAllPrimOne\":null," @@ -1709,17 +1713,22 @@ public class ODataJsonSerializerTest { resultString); } - @Test(expected = SerializerException.class) + @Test public void primitivePropertyNull() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString"); final Property property = new Property("Edm.String", edmProperty.getName(), ValueType.PRIMITIVE, null); - serializer.primitive(metadata, (EdmPrimitiveType) edmProperty.getType(), property, + final String resultString = IOUtils + .toString(serializer.primitive(metadata, (EdmPrimitiveType) edmProperty.getType(), property, PrimitiveSerializerOptions.with() .contextURL(ContextURL.with() .entitySet(edmEntitySet).keyPath("4242").navOrPropertyPath(edmProperty.getName()) .build()) - .build()); + .build()).getContent()); + Assert.assertEquals( + "{\"@odata.context\":\"../$metadata#ESAllPrim(4242)/PropertyString\"," + +"\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\",\"value\":null}", + resultString); } @Test diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java index 17532c0..37afbe5 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerv01Test.java @@ -18,9 +18,6 @@ */ package org.apache.olingo.server.core.serializer.json; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; - import java.io.IOException; import java.io.InputStream; import java.net.URI; @@ -52,15 +49,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; @@ -1538,7 +1535,8 @@ public class ODataJsonSerializerv01Test { .select(select) .build()).getContent()); Assert.assertEquals("{" - + "\"@context\":\"$metadata#ESAllPrim(PropertyInt16,PropertySByte)/$entity\"," + + "\"@context\":\"$metadata#ESAllPrim(PropertyInt16,PropertySByte," + + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany())/$entity\"," + "\"@metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"@id\":\"ESAllPrim(32767)\",\"PropertyInt16\":32767," + "\"PropertySByte\":127," @@ -1567,7 +1565,8 @@ public class ODataJsonSerializerv01Test { .select(select) .build()).getContent()); Assert.assertEquals("{" - + "\"@context\":\"$metadata#ESAllPrim(PropertyInt16,PropertyTimeOfDay)/$entity\"," + + "\"@context\":\"$metadata#ESAllPrim(PropertyInt16,PropertyTimeOfDay," + + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany())/$entity\"," + "\"@metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"@id\":\"ESAllPrim(-32768)\",\"PropertyInt16\":-32768," + "\"PropertyTimeOfDay\":\"23:49:14\"," @@ -1600,7 +1599,8 @@ public class ODataJsonSerializerv01Test { .build()).getContent()); Assert.assertEquals("{" + "\"@context\":\"$metadata#ESTwoPrim(PropertyInt16," - + "NavPropertyETAllPrimMany(PropertyInt16,PropertyInt32))/$entity\"," + + "NavPropertyETAllPrimMany(PropertyInt16,PropertyInt32," + + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany()))/$entity\"," + "\"@metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\"," + "\"NavPropertyETAllPrimMany\":[" @@ -1638,7 +1638,8 @@ public class ODataJsonSerializerv01Test { .suffix(Suffix.ENTITY).build()) .expand(expand) .build()).getContent()); - Assert.assertEquals("{\"@context\":\"$metadata#ESTwoPrim(PropertyInt16)/$entity\"," + Assert.assertEquals("{\"@context\":\"$metadata#ESTwoPrim(PropertyInt16," + + "NavPropertyETAllPrimOne(),NavPropertyETAllPrimMany())/$entity\"," + "\"@metadataEtag\":\"W/\\\"metadataETag\\\"\"," + "\"PropertyInt16\":-365,\"PropertyString\":\"Test String2\"," + "\"NavPropertyETAllPrimOne\":null," @@ -1717,19 +1718,24 @@ public class ODataJsonSerializerv01Test { resultString); } - @Test(expected = SerializerException.class) + @Test public void primitivePropertyNull() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim"); final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString"); final Property property = new Property("Edm.String", edmProperty.getName(), ValueType.PRIMITIVE, null); - serializer.primitive(metadata, (EdmPrimitiveType) edmProperty.getType(), property, + final String resultString = IOUtils + .toString(serializer.primitive(metadata, (EdmPrimitiveType) edmProperty.getType(), property, PrimitiveSerializerOptions.with() .contextURL(ContextURL.with() .entitySet(edmEntitySet).keyPath("4242").navOrPropertyPath(edmProperty.getName()) .build()) - .build()); + .build()).getContent()); + Assert.assertEquals( + "{\"@context\":\"../$metadata#ESAllPrim(4242)/PropertyString\"," + +"\"@metadataEtag\":\"W/\\\"metadataETag\\\"\",\"value\":null}", + resultString); } - + @Test public void primitiveCollectionProperty() throws Exception { final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim"); diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java index 1541a3d..1c4bdf8 100644 --- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java +++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelperTest.java @@ -178,7 +178,8 @@ public class ContextURLHelperTest { final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(expandItem)); final ContextURL contextURL = ContextURL.with().entitySet(entitySet) .selectList(ContextURLHelper.buildSelectList(entitySet.getEntityType(), expand, null)).build(); - assertEquals("$metadata#ESTwoPrim", ContextURLBuilder.create(contextURL).toASCIIString()); + assertEquals("$metadata#ESTwoPrim(NavPropertyETAllPrimOne(),NavPropertyETAllPrimMany())", + ContextURLBuilder.create(contextURL).toASCIIString()); } @Test 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 e217ec0..7e1a963 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 @@ -2145,7 +2145,8 @@ public class ODataXmlSerializerTest { "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\"\n" + " xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" " - + "m:context=\"$metadata#ESAllPrim(PropertyInt16,PropertySByte)/$entity\"\n" + + + "m:context=\"$metadata#ESAllPrim(PropertyInt16,PropertySByte,"+ + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany())/$entity\"\n" + " m:metadata-etag=\"metadataETag\">\n" + " <a:id>ESAllPrim(32767)</a:id>\n" + " <a:title />\n" + @@ -2290,7 +2291,8 @@ public class ODataXmlSerializerTest { "<a:entry xmlns:a=\"http://www.w3.org/2005/Atom\" " + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" " - + "m:context=\"$metadata#ESAllPrim(PropertyInt16,PropertyTimeOfDay)/$entity\"\n" + + + "m:context=\"$metadata#ESAllPrim(PropertyInt16,PropertyTimeOfDay,"+ + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany())/$entity\"\n" + " m:metadata-etag=\"metadataETag\">\n" + " <a:id>ESAllPrim(-32768)</a:id>\n" + " <a:title />\n" + @@ -2360,7 +2362,8 @@ public class ODataXmlSerializerTest { + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"\n" + " xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\"\n" + " m:context=\"$metadata#ESTwoPrim(PropertyInt16," - + "NavPropertyETAllPrimMany(PropertyInt16,PropertyInt32))/$entity\"\n" + + + "NavPropertyETAllPrimMany(PropertyInt16,PropertyInt32,"+ + "NavPropertyETTwoPrimOne(),NavPropertyETTwoPrimMany()))/$entity\"\n" + " m:metadata-etag=\"metadataETag\">\n" + " <a:id>ESTwoPrim(-365)</a:id>\n" + " <a:title />\n" +