From d4f1b73875e8c5a474d7265f9d36c57854bca800 Mon Sep 17 00:00:00 2001 From: ramya vasanth Date: Wed, 9 Aug 2017 15:56:52 +0530 Subject: [PATCH] [OLINGO-1159] Enhancements to Bound Actions in V4 --- .../tecsvc/http/BasicBoundActionsITCase.java | 273 ++++++++++++++ .../http/DerivedAndMixedTypeTestITCase.java | 24 +- .../commons/core/edm/EdmProviderImpl.java | 44 ++- .../olingo/server/tecsvc/data/ActionData.java | 335 +++++++++++++++++- .../server/tecsvc/data/DataProvider.java | 53 +++ .../processor/TechnicalActionProcessor.java | 222 ++++++++++-- .../tecsvc/provider/ActionProvider.java | 82 ++++- .../tecsvc/provider/SchemaProvider.java | 6 + .../xml/ODataXmlSerializerTest.java | 9 + 9 files changed, 1000 insertions(+), 48 deletions(-) create mode 100644 fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBoundActionsITCase.java diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBoundActionsITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBoundActionsITCase.java new file mode 100644 index 000000000..a0a708553 --- /dev/null +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/BasicBoundActionsITCase.java @@ -0,0 +1,273 @@ +/* + * 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.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.OutputStreamWriter; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest; +import org.apache.olingo.client.api.domain.ClientCollectionValue; +import org.apache.olingo.client.api.domain.ClientComplexValue; +import org.apache.olingo.client.api.domain.ClientEntity; +import org.apache.olingo.client.api.domain.ClientPrimitiveValue; +import org.apache.olingo.client.api.domain.ClientProperty; +import org.apache.olingo.client.api.domain.ClientValue; +import org.apache.olingo.client.api.uri.URIBuilder; +import org.apache.olingo.client.core.ODataClientFactory; +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.junit.Test; + +public class BasicBoundActionsITCase { + + private static final String SERVICE_URI = "http://localhost:8083/odata-server-tecsvc/odata.svc/"; + protected static final ODataClient client = ODataClientFactory.getClient(); + + @Test + public void boundActionReturningBaseType() throws Exception { + URL url = new URL(SERVICE_URI + "ESTwoBaseTwoKeyNav(PropertyInt16=1,PropertyString='1')/" + + "olingo.odata.test1.BAETTwoBaseTwoKeyNavRTETBaseTwoKeyNav"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.POST.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json"); + connection.setRequestProperty(HttpHeader.CONTENT_TYPE, "application/json"); + connection.connect(); + + assertEquals(HttpStatusCode.CREATED.getStatusCode(), connection.getResponseCode()); + + final String content = IOUtils.toString(connection.getInputStream()); + final String expected = "\"PropertyInt16\":1,\"PropertyString\":\"1\"," + + "\"PropertyComp\":{\"PropertyInt16\":11," + + "\"PropertyComp\":{\"PropertyString\":\"StringValue\"," + + "\"PropertyBinary\":\"ASNFZ4mrze8=\",\"PropertyBoolean\":true," + + "\"PropertyByte\":255,\"PropertyDate\":\"2012-12-03\"," + + "\"PropertyDateTimeOffset\":null,\"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\"}}," + + "\"PropertyCompNav\":{\"PropertyInt16\":1,\"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\"}},\"CollPropertyComp\":[]," + + "\"CollPropertyCompNav\":[{\"PropertyInt16\":1}]," + + "\"CollPropertyString\":[\"1\",\"2\"],\"PropertyCompTwoPrim\":" + + "{\"PropertyInt16\":11,\"PropertyString\":\"11\"},\"PropertyDate\":\"2013-12-12\"}"; + assertTrue(content.contains(expected)); + } + + @Test + public void boundActionReturningEntityWithNavigationSegInAction() throws Exception { + URL url = new URL(SERVICE_URI + "ESTwoKeyNav(PropertyInt16=1,PropertyString='1')/" + + "NavPropertyETTwoKeyNavOne/olingo.odata.test1.BAETTwoKeyNavRTETTwoKeyNavParam"); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod(HttpMethod.POST.name()); + connection.setRequestProperty(HttpHeader.ACCEPT, "application/json"); + connection.setRequestProperty(HttpHeader.CONTENT_TYPE, "application/json"); + connection.setDoOutput(true); + final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); + writer.append("{\"PropertyComp\" : {\"PropertyInt16\" : 30}}"); + writer.close(); + connection.connect(); + + assertEquals(HttpStatusCode.OK.getStatusCode(), connection.getResponseCode()); + + final String content = IOUtils.toString(connection.getInputStream()); + final String expected = "\"PropertyInt16\":1,\"PropertyString\":\"1\"," + + "\"PropertyComp\":{\"PropertyInt16\":30,\"PropertyComp\":" + + "{\"PropertyString\":\"StringValue\",\"PropertyBinary\":\"ASNFZ4mrze8=\"," + + "\"PropertyBoolean\":true,\"PropertyByte\":255,\"PropertyDate\":\"2012-12-03\"," + + "\"PropertyDateTimeOffset\":null,\"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\"}}," + + "\"PropertyCompNav\":{\"PropertyInt16\":1,\"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\"}},\"CollPropertyComp\":[]," + + "\"CollPropertyCompNav\":[{\"PropertyInt16\":1}],\"CollPropertyString\":[\"1\",\"2\"]," + + "\"PropertyCompTwoPrim\":{\"PropertyInt16\":11,\"PropertyString\":\"11\"}}"; + assertTrue(content.contains(expected)); + } + + @Test + public void boundActionReturningDerivedTypeWithTypeCastSegInAction() throws Exception { + URIBuilder builder = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESBase"). + appendKeySegment(111).appendDerivedEntityTypeSegment("olingo.odata.test1.ETTwoBase"). + appendActionCallSegment("olingo.odata.test1.BAETBaseETTwoBaseRTETTwoBase"); + Map parameters = new HashMap(); + final ClientPrimitiveValue propStrValue = + client.getObjectFactory().newPrimitiveValueBuilder().buildString("NewStrValue"); + parameters.put("PropertyString", propStrValue); + + final ClientPrimitiveValue addPropStr1 = + client.getObjectFactory().newPrimitiveValueBuilder().buildString("AddStrProp_5"); + parameters.put("AdditionalPropertyString_5", addPropStr1); + + final ClientPrimitiveValue addPropStr2 = + client.getObjectFactory().newPrimitiveValueBuilder().buildString("AddStrProp_6"); + parameters.put("AdditionalPropertyString_6", addPropStr2); + + final ODataInvokeRequest req = + client.getInvokeRequestFactory().getActionInvokeRequest(builder.build(), ClientEntity.class, parameters); + req.setFormat(ContentType.JSON_FULL_METADATA); + req.setContentType(ContentType.APPLICATION_JSON.toContentTypeString() + ";odata.metadata=full"); + ClientEntity entity = req.execute().getBody(); + assertNotNull(entity); + assertEquals(entity.getProperties().size(), 4); + assertEquals(entity.getTypeName().getFullQualifiedNameAsString(), "olingo.odata.test1.ETTwoBase"); + } + + @Test + public void boundActionReturningColComplexTypeWithComplexTypeSegInAction() throws Exception { + URIBuilder builder = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESMixPrimCollComp"). + appendKeySegment(32767).appendPropertySegment("CollPropertyComp"). + appendActionCallSegment("olingo.odata.test1.BAETMixPrimCollCompCTTWOPrimCompRTCollCTTwoPrim"); + final ClientComplexValue propertyComp = client.getObjectFactory(). + newComplexValue("olingo.odata.test1.CTTwoPrim"); + propertyComp.add(client.getObjectFactory().newPrimitiveProperty("PropertyInt16", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 111))); + propertyComp.add(client.getObjectFactory().newPrimitiveProperty("PropertyString", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("ABC"))); + + Map parameters = new HashMap(); + parameters.put("PropertyComp", propertyComp); + + final ODataInvokeRequest req = + client.getInvokeRequestFactory().getActionInvokeRequest(builder.build(), ClientProperty.class, parameters); + req.setFormat(ContentType.JSON_FULL_METADATA); + req.setContentType(ContentType.APPLICATION_JSON.toContentTypeString() + ";odata.metadata=full"); + ClientProperty prop = req.execute().getBody(); + assertNotNull(prop); + assertNotNull(prop.getCollectionValue()); + assertEquals(prop.getCollectionValue().asCollection().size(), 1); + assertEquals(prop.getCollectionValue().getTypeName(), "Collection(olingo.odata.test1.CTTwoPrim)"); + } + + @Test + public void boundActionReturningComplexDerivedTypeWithComplexTypeSegInAction() throws Exception { + Map segmentValues = new HashMap(); + segmentValues.put("PropertyInt16", 1); + segmentValues.put("PropertyString", "1"); + URIBuilder builder = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoKeyNav"). + appendKeySegment(segmentValues).appendPropertySegment("PropertyCompNav"). + appendDerivedEntityTypeSegment("olingo.odata.test1.CTTwoBasePrimCompNav"). + appendActionCallSegment("olingo.odata.test1." + + "BAETTwoKeyNavCTBasePrimCompNavCTTwoBasePrimCompNavRTCTTwoBasePrimCompNav"); + + Map parameters = new HashMap(); + + final ODataInvokeRequest req = + client.getInvokeRequestFactory().getActionInvokeRequest(builder.build(), ClientEntity.class, parameters); + req.setFormat(ContentType.JSON_FULL_METADATA); + req.setContentType(ContentType.APPLICATION_JSON.toContentTypeString() + ";odata.metadata=full"); + ClientEntity entity = req.execute().getBody(); + assertNotNull(entity); + assertEquals(entity.getProperties().size(), 2); + assertEquals(entity.getTypeName().getFullQualifiedNameAsString(), + "olingo.odata.test1.CTTwoBasePrimCompNav"); + } + + @Test + public void boundActionReturningCollComplexTypeWithMixedTypes() throws Exception { + URIBuilder builder = client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESMixPrimCollComp"). + appendKeySegment(32767). + appendActionCallSegment("olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim"); + + final ClientCollectionValue colPropertyComp = + client.getObjectFactory(). + newCollectionValue("Collection(olingo.odata.test1.CTTwoPrim)"); + + final ClientComplexValue property1 = client.getObjectFactory(). + newComplexValue("olingo.odata.test1.CTTwoPrim"); + property1.add(client.getObjectFactory().newPrimitiveProperty("PropertyInt16", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 111))); + property1.add(client.getObjectFactory().newPrimitiveProperty("PropertyString", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("ABC"))); + colPropertyComp.add(property1); + + final ClientComplexValue property2 = client.getObjectFactory(). + newComplexValue("olingo.odata.test1.CTTwoPrim"); + property2.add(client.getObjectFactory().newPrimitiveProperty("PropertyInt16", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 222))); + property2.add(client.getObjectFactory().newPrimitiveProperty("PropertyString", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("DEF"))); + colPropertyComp.add(property2); + + final ClientComplexValue property3 = client.getObjectFactory(). + newComplexValue("olingo.odata.test1.CTBase"); + property3.add(client.getObjectFactory().newPrimitiveProperty("PropertyInt16", + client.getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 333))); + property3.add(client.getObjectFactory().newPrimitiveProperty("PropertyString", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("GHI"))); + colPropertyComp.add(property3); + + Map parameters = new HashMap(); + parameters.put("CollPropertyComp", colPropertyComp); + + final ODataInvokeRequest req = + client.getInvokeRequestFactory().getActionInvokeRequest(builder.build(), ClientProperty.class, parameters); + req.setFormat(ContentType.JSON_FULL_METADATA); + req.setContentType(ContentType.APPLICATION_JSON.toContentTypeString() + ";odata.metadata=full"); + ClientProperty prop = req.execute().getBody(); + assertNotNull(prop); + assertEquals(prop.getCollectionValue().getTypeName(), + "Collection(olingo.odata.test1.CTTwoPrim)"); + assertEquals(prop.getCollectionValue().asCollection().size(), 3); + Iterator itr = prop.getCollectionValue().asCollection().iterator(); + int i = 0; + while (itr.hasNext()) { + ClientValue value = itr.next(); + if (i == 2) { + assertEquals(value.asComplex().getTypeName(), "#olingo.odata.test1.CTBase"); + } else { + assertEquals(value.asComplex().getTypeName(), "#olingo.odata.test1.CTTwoPrim"); + } + i++; + } + } +} diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedAndMixedTypeTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedAndMixedTypeTestITCase.java index 75967b64e..69fe65ec1 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedAndMixedTypeTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/http/DerivedAndMixedTypeTestITCase.java @@ -188,7 +188,7 @@ public class DerivedAndMixedTypeTestITCase extends AbstractBaseTestITCase { ContentType.create(connection.getHeaderField(HttpHeader.CONTENT_TYPE))); final String content = IOUtils.toString(connection.getInputStream()); - assertTrue(content.contains("\"value\":" + final String actualContent = "\"value\":" + "[{\"@odata.type\":\"#olingo.odata.test1.ETMixPrimCollComp\"," + "\"@odata.id\":\"ESMixPrimCollComp(32767)\"," + "\"PropertyInt16@odata.type\":\"#Int16\"," @@ -214,7 +214,10 @@ public class DerivedAndMixedTypeTestITCase extends AbstractBaseTestITCase { + "\"PropertyInt16@odata.type\":\"#Int16\"," + "\"PropertyInt16\":789," + "\"PropertyString\":\"TEST 3\"," - + "\"AdditionalPropString\":\"ADD TEST\"}]}," + + "\"AdditionalPropString\":\"ADD TEST\"}]," + + "\"#olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\":" + + "{\"title\":\"olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\"," + + "\"target\":\"ESMixPrimCollComp(32767)/olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\"}}," + "{\"@odata.type\":\"#olingo.odata.test1.ETMixPrimCollComp\"," + "\"@odata.id\":\"ESMixPrimCollComp(7)\"," + "\"PropertyInt16@odata.type\":\"#Int16\"," @@ -230,7 +233,11 @@ public class DerivedAndMixedTypeTestITCase extends AbstractBaseTestITCase { + "{\"@odata.type\":\"#olingo.odata.test1.CTTwoPrim\",\"PropertyInt16@odata.type\":\"#Int16\"," + "\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"},{\"@odata.type\":\"#olingo.odata.test1.CTBase\"," + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"," - + "\"AdditionalPropString\":\"ADD TEST\"}]},{\"@odata.type\":\"#olingo.odata.test1.ETMixPrimCollComp\"," + + "\"AdditionalPropString\":\"ADD TEST\"}]," + + "\"#olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\":" + + "{\"title\":\"olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\"," + + "\"target\":\"ESMixPrimCollComp(7)/olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\"}}," + + "{\"@odata.type\":\"#olingo.odata.test1.ETMixPrimCollComp\"," + "\"@odata.id\":\"ESMixPrimCollComp(0)\",\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":0," + "\"CollPropertyString@odata.type\":\"#Collection(String)\",\"CollPropertyString\":" + "[\"Employee1@company.example\",\"Employee2@company.example\",\"Employee3@company.example\"]," @@ -244,7 +251,11 @@ public class DerivedAndMixedTypeTestITCase extends AbstractBaseTestITCase { + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"}," + "{\"@odata.type\":\"#olingo.odata.test1.CTBase\"," + "\"PropertyInt16@odata.type\":\"#Int16\",\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"," - + "\"AdditionalPropString\":\"ADD TEST\"}]}]")); + + "\"AdditionalPropString\":\"ADD TEST\"}]," + + "\"#olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\":" + + "{\"title\":\"olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\"," + + "\"target\":\"ESMixPrimCollComp(0)/olingo.odata.test1.BAETMixPrimCollCompRTCTTwoPrim\"}}]"; + assertTrue(content.contains(actualContent)); } @Test @@ -338,7 +349,10 @@ public class DerivedAndMixedTypeTestITCase extends AbstractBaseTestITCase { + "\"PropertyInt16@odata.type\":\"#Int16\"," + "\"PropertyInt16\":111," + "\"PropertyString\":\"TEST A\"," - + "\"AdditionalPropertyString_5\":\"TEST A 0815\"}]")); + + "\"AdditionalPropertyString_5\":\"TEST A 0815\"" + + ",\"#olingo.odata.test1.BAETBaseETTwoBaseRTETTwoBase\":" + + "{\"title\":\"olingo.odata.test1.BAETBaseETTwoBaseRTETTwoBase\"," + + "\"target\":\"ESBase(111)/olingo.odata.test1.BAETBaseETTwoBaseRTETTwoBase\"}}]")); } @Test diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java index ed43139b6..1cdcc173e 100644 --- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java +++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/edm/EdmProviderImpl.java @@ -47,6 +47,7 @@ import org.apache.olingo.commons.api.edm.provider.CsdlEntityType; import org.apache.olingo.commons.api.edm.provider.CsdlEnumType; import org.apache.olingo.commons.api.edm.provider.CsdlFunction; import org.apache.olingo.commons.api.edm.provider.CsdlParameter; +import org.apache.olingo.commons.api.edm.provider.CsdlProperty; import org.apache.olingo.commons.api.edm.provider.CsdlSchema; import org.apache.olingo.commons.api.edm.provider.CsdlTerm; import org.apache.olingo.commons.api.edm.provider.CsdlTypeDefinition; @@ -154,7 +155,10 @@ public class EdmProviderImpl extends AbstractEdm { if (action.isBound()) { final List parameters = action.getParameters(); final CsdlParameter parameter = parameters.get(0); - if (bindingParameterTypeName.equals(parameter.getTypeFQN()) + if ((bindingParameterTypeName.equals(parameter.getTypeFQN()) || + isEntityPreviousTypeCompatibleToBindingParam(bindingParameterTypeName, parameter) || + isComplexPreviousTypeCompatibleToBindingParam(bindingParameterTypeName, parameter, + isBindingParameterCollection)) && isBindingParameterCollection.booleanValue() == parameter.isCollection()) { return new EdmActionImpl(this, actionName, action); @@ -168,6 +172,44 @@ public class EdmProviderImpl extends AbstractEdm { } } + /** + * @param bindingParameterTypeName + * @param parameter + * @param isBindingParameterCollection + * @return + * @throws ODataException + */ + private boolean isComplexPreviousTypeCompatibleToBindingParam( + final FullQualifiedName bindingParameterTypeName, final CsdlParameter parameter, + Boolean isBindingParameterCollection) + throws ODataException { + CsdlComplexType complexType = provider.getComplexType(bindingParameterTypeName); + List properties = provider.getEntityType(parameter.getTypeFQN()).getProperties(); + for (CsdlProperty property : properties) { + String paramPropertyTypeName = property.getTypeAsFQNObject().getFullQualifiedNameAsString(); + if ((complexType != null && complexType.getBaseType() != null && + complexType.getBaseTypeFQN().getFullQualifiedNameAsString().equals(paramPropertyTypeName)) || + paramPropertyTypeName.equals(bindingParameterTypeName.getFullQualifiedNameAsString()) && + isBindingParameterCollection.booleanValue() == property.isCollection()) { + return true; + } + } + return false; + } + + /** + * @param bindingParameterTypeName + * @param parameter + * @return + * @throws ODataException + */ + private boolean isEntityPreviousTypeCompatibleToBindingParam(final FullQualifiedName bindingParameterTypeName, + final CsdlParameter parameter) throws ODataException { + return provider.getEntityType(bindingParameterTypeName) != null && + provider.getEntityType(bindingParameterTypeName).getBaseTypeFQN() != null && + provider.getEntityType(bindingParameterTypeName).getBaseTypeFQN().equals(parameter.getTypeFQN()); + } + @Override public EdmFunction createBoundFunction(final FullQualifiedName functionName, final FullQualifiedName bindingParameterTypeName, final Boolean isBindingParameterCollection, diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/ActionData.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/ActionData.java index 1b3e1f45c..ab9705b5b 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/ActionData.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/ActionData.java @@ -23,22 +23,32 @@ import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; +import org.apache.olingo.commons.api.Constants; import org.apache.olingo.commons.api.data.ComplexValue; import org.apache.olingo.commons.api.data.Entity; import org.apache.olingo.commons.api.data.EntityCollection; +import org.apache.olingo.commons.api.data.Link; import org.apache.olingo.commons.api.data.Parameter; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.data.ValueType; import org.apache.olingo.commons.api.edm.Edm; +import org.apache.olingo.commons.api.edm.EdmEntitySet; +import org.apache.olingo.commons.api.edm.EdmEntityType; +import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef; +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; +import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.server.api.OData; import org.apache.olingo.server.api.serializer.SerializerException; +import org.apache.olingo.server.api.uri.UriParameter; import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException; import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider; @@ -67,6 +77,25 @@ public class ActionData { HttpStatusCode.NOT_IMPLEMENTED); } + + protected static Property primitiveBoundAction(final String name, final Map parameters, + final Map data, final EdmEntitySet edmEntitySet, final List keyList) + throws DataProviderException { + List keyPropertyValues = new ArrayList(); + List keyPropertyNames = new ArrayList(); + if ("BAETTwoPrimRTString".equals(name)) { + if (!keyList.isEmpty()) { + setBindingPropertyKeyNameAndValue(keyList, edmEntitySet, keyPropertyValues, keyPropertyNames); + EntityCollection entityCollection = data.get(edmEntitySet.getName()); + Entity entity = getSpecificEntity1(entityCollection, keyPropertyValues, keyPropertyNames); + Property property = entity.getProperty("PropertyString"); + return property; + } + } + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } + protected static Property primitiveCollectionAction(final String name, final Map parameters, final OData oData) throws DataProviderException { if ("UARTCollStringTwoParam".equals(name)) { @@ -103,6 +132,26 @@ public class ActionData { throw new DataProviderException("Action " + name + " is not yet implemented.", HttpStatusCode.NOT_IMPLEMENTED); } + + protected static Property primitiveCollectionBoundAction(final String name, final Map parameters, + final Map data, + EdmEntitySet edmEntitySet, List keyList, final OData oData) throws DataProviderException { + List collectionValues = new ArrayList(); + if ("BAETTwoPrimRTCollString".equals(name)) { + EdmPrimitiveType strType = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String); + try { + String strValue1 = strType.valueToString("ABC", false, 100, null, null, false); + collectionValues.add(strValue1); + String strValue2 = strType.valueToString("XYZ", false, 100, null, null, false); + collectionValues.add(strValue2); + } catch (EdmPrimitiveTypeException e) { + throw new DataProviderException("EdmPrimitiveTypeException", HttpStatusCode.BAD_REQUEST, e); + } + return new Property(null, name, ValueType.COLLECTION_PRIMITIVE, collectionValues); + } + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } private static String valueAsString(final Parameter parameter, final EdmPrimitiveTypeKind kind, final OData oData) throws EdmPrimitiveTypeException { @@ -123,6 +172,22 @@ public class ActionData { throw new DataProviderException("Action " + name + " is not yet implemented.", HttpStatusCode.NOT_IMPLEMENTED); } + + protected static Property complexBoundAction(final String name, final Map parameters, + final Map data, + EdmEntitySet edmEntitySet, List keyList) + throws DataProviderException { + if ("BAETTwoKeyNavCTBasePrimCompNavCTTwoBasePrimCompNavRTCTTwoBasePrimCompNav".equals(name)) { + if (!keyList.isEmpty()) { + return DataCreator.createComplex(name, + ComplexTypeProvider.nameCTTwoBasePrimCompNav.getFullQualifiedNameAsString(), + DataCreator.createPrimitive("PropertyInt16", 10), + createKeyNavAllPrimComplexValue("PropertyComp")); + } + } + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } private static Property createCTTwoPrimComplexProperty(final String name, final Short number, final String text) { return DataCreator.createComplex(name, @@ -151,7 +216,58 @@ public class ActionData { throw new DataProviderException("Action " + name + " is not yet implemented.", HttpStatusCode.NOT_IMPLEMENTED); } - + + @SuppressWarnings("unchecked") + protected static Property complexCollectionBoundAction(final String name, + final Map parameters, final Map data, + EdmEntitySet edmEntitySet, List keyList) + throws DataProviderException { + List keyPropertyValues = new ArrayList(); + List keyPropertyNames = new ArrayList(); + if ("BAETMixPrimCollCompRTCTTwoPrim".equals(name)) { + if (!keyList.isEmpty()) { + setBindingPropertyKeyNameAndValue(keyList, edmEntitySet, keyPropertyValues, keyPropertyNames); + EntityCollection entityCollection = data.get(edmEntitySet.getName()); + Entity entity = getSpecificEntity1(entityCollection, keyPropertyValues, keyPropertyNames); + List complexProperties = (List) entity.getProperty("CollPropertyComp"). + asCollection(); + List complexParameters = (List) parameters.get("CollPropertyComp"). + asCollection(); + for (int i = 0; i < complexProperties.size() && i < complexParameters.size(); i++) { + List values = complexProperties.get(i).getValue(); + List paramValues = complexParameters.get(i).getValue(); + for (int j = 0; j < values.size() && j < paramValues.size(); j++) { + values.get(j).setValue(values.get(j).getValueType(), paramValues.get(j).asPrimitive()); + } + } + return new Property(entity.getProperty("CollPropertyComp").getType(), + entity.getProperty("CollPropertyComp").getName(), + entity.getProperty("CollPropertyComp").getValueType(), complexProperties); + } + } else if ("BAETMixPrimCollCompCTTWOPrimCompRTCollCTTwoPrim".equals(name)) { + List complexCollection = new ArrayList(); + if (!keyList.isEmpty()) { + setBindingPropertyKeyNameAndValue(keyList, edmEntitySet, keyPropertyValues, keyPropertyNames); + EntityCollection entityCollection = data.get(edmEntitySet.getName()); + Entity entity = getSpecificEntity1(entityCollection, keyPropertyValues, keyPropertyNames); + ComplexValue complexValue = entity.getProperty("PropertyComp").asComplex(); + ComplexValue paramComplexValue = parameters.get("PropertyComp").asComplex(); + List complexProperties = complexValue.getValue(); + List paramProperties = paramComplexValue.getValue(); + for (int i = 0; i < complexProperties.size() && i < paramProperties.size(); i++) { + complexProperties.get(i).setValue(complexProperties.get(i).getValueType(), + paramProperties.get(i).asPrimitive()); + } + complexCollection.add(complexValue); + return new Property(entity.getProperty("PropertyComp").getType(), + entity.getProperty("PropertyComp").getName(), + ValueType.COLLECTION_COMPLEX, complexCollection); + } + } + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } + protected static EntityActionResult entityAction(final String name, final Map parameters, final Map data, final OData oData, final Edm edm) throws DataProviderException { if ("UARTETTwoKeyTwoPrimParam".equals(name)) { @@ -195,6 +311,154 @@ public class ActionData { throw new DataProviderException("Action " + name + " is not yet implemented.", HttpStatusCode.NOT_IMPLEMENTED); } + + protected static EntityActionResult entityBoundAction(final String name, final Map parameters, + final Map data, final OData oData, final Edm edm, + List keyList, EdmEntitySet edmEntitySet) throws DataProviderException { + List keyPropertyValues = new ArrayList(); + List keyPropertyNames = new ArrayList(); + if ("BA_RTETTwoKeyNav".equals(name)) { + if (!keyList.isEmpty()) { + setBindingPropertyKeyNameAndValue(keyList, edmEntitySet, keyPropertyValues, keyPropertyNames); + EntityCollection entityCollection = data.get(edmEntitySet.getName()); + Entity entity = null; + if (edmEntitySet.getName().equals("ESKeyNav")) { + entity = getSpecificEntity1(entityCollection, keyPropertyValues, keyPropertyNames); + Entity etTwoKeyNavEntity = + createETTwoKeyNav((short)100, "String1", oData, edm); + Link link = new Link(); + link.setRel(Constants.NS_NAVIGATION_LINK_REL + "NavPropertyETTwoKeyNavOne"); + link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE); + link.setTitle("NavPropertyETTwoKeyNavOne"); + link.setHref(etTwoKeyNavEntity.getId().toASCIIString()); + link.setInlineEntity(etTwoKeyNavEntity); + entity.getNavigationLinks().add(link); + return new EntityActionResult().setEntity(etTwoKeyNavEntity); + } else { + entity = getSpecificEntity(entityCollection, keyPropertyValues, keyPropertyNames); + return new EntityActionResult().setEntity(entity); + } + } + } else if ("BAETTwoBaseTwoKeyNavRTETBaseTwoKeyNav".equals(name)) { + if (!keyList.isEmpty()) { + setBindingPropertyKeyNameAndValue(keyList, edmEntitySet, keyPropertyValues, keyPropertyNames); + EdmEntityType entityTypeFqn = edmEntitySet.getEntityType().getBaseType(); + List entitySets = edm.getEntityContainer().getEntitySets(); + for (EdmEntitySet entitySet : entitySets) { + if (entitySet.getEntityType().getFullQualifiedName().getFullQualifiedNameAsString().equals + (entityTypeFqn.getFullQualifiedName().getFullQualifiedNameAsString())) { + edmEntitySet = entitySet; + break; + } + } + EntityCollection entityCollection = data.get(edmEntitySet.getName()); + Entity entity = getSpecificEntity(entityCollection, keyPropertyValues, keyPropertyNames); + return new EntityActionResult().setEntity(entity).setCreated(true); + } + } else if ("BAETBaseETTwoBaseRTETTwoBase".equals(name)) { + if (!keyList.isEmpty()) { + setBindingPropertyKeyNameAndValue(keyList, edmEntitySet, keyPropertyValues, keyPropertyNames); + EntityCollection entityCollection = data.get(edmEntitySet.getName()); + Entity entity = getSpecificEntity1(entityCollection, keyPropertyValues, keyPropertyNames); + Property property1 = entity.getProperty("PropertyString"); + property1.setValue(property1.getValueType(), parameters.get("PropertyString").asPrimitive()); + + Property property2 = entity.getProperty("AdditionalPropertyString_5"); + property2.setValue(property2.getValueType(), parameters.get("AdditionalPropertyString_5").asPrimitive()); + + Property property3 = entity.getProperty("AdditionalPropertyString_6"); + property3.setValue(property3.getValueType(), parameters.get("AdditionalPropertyString_6").asPrimitive()); + + return new EntityActionResult().setEntity(entity).setCreated(true); + } + } + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } + + protected static EntityActionResult entityBoundActionWithNavigation(final String name, + final Map parameters, + final Map data, List keyList, + EdmEntitySet edmEntitySet, EdmNavigationProperty navProperty) + throws DataProviderException { + List keyPropertyValues = new ArrayList(); + List keyPropertyNames = new ArrayList(); + if ("BAETTwoKeyNavRTETTwoKeyNavParam".equals(name)) { + if (!keyList.isEmpty()) { + setBindingPropertyKeyNameAndValue(keyList, edmEntitySet, keyPropertyValues, keyPropertyNames); + EntityCollection entityCollection = data.get(edmEntitySet.getName()); + Entity entity = getSpecificEntity(entityCollection, keyPropertyValues, keyPropertyNames); + + Link link = entity.getNavigationLink(navProperty.getName()); + Entity inlineEntity = link.getInlineEntity(); + ComplexValue complexValue = inlineEntity.getProperty("PropertyComp").asComplex(); + List complexProperties = complexValue.getValue(); + Iterator itr = complexProperties.iterator(); + Parameter actionParam = parameters.get("PropertyComp"); + Property actionProp = actionParam.asComplex().getValue().get(0); + while (itr.hasNext()) { + Property property = itr.next(); + if (property.getName().equals(actionProp.getName())) { + property.setValue(actionProp.getValueType(), actionProp.getValue()); + break; + } + } + return new EntityActionResult().setEntity(inlineEntity); + } + } + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } + + private static Entity getSpecificEntity(EntityCollection entityCollection, List values, + List propertyNames) throws DataProviderException { + for (Entity entity : entityCollection.getEntities()) { + Object asPrimitive1 = entity.getProperty(propertyNames.get(0)).asPrimitive(); + Object asPrimitive2 = entity.getProperty(propertyNames.get(1)).asPrimitive(); + if (values.get(0).equals(String.valueOf(asPrimitive1)) && + values.get(1).equals(String.valueOf(asPrimitive2))) { + return entity; + } + } + // Entity Not found + throw new DataProviderException("Entity not found with key: " + values.get(0) + + "," + values.get(1), HttpStatusCode.NOT_FOUND); + } + + private static Entity getSpecificEntity1(EntityCollection entityCollection, List values, + List propertyNames) throws DataProviderException { + for (Entity entity : entityCollection.getEntities()) { + Object asPrimitive1 = entity.getProperty(propertyNames.get(0)).asPrimitive(); + if (values.get(0).equals(String.valueOf(asPrimitive1))) { + return entity; + } + } + // Entity Not found + throw new DataProviderException("Entity not found with key: " + values.get(0), + HttpStatusCode.NOT_FOUND); + } + + /** + * @param keyList + * @param edmEntitySet + * @param values + * @param propertyNames + * @throws DataProviderException + */ + private static void setBindingPropertyKeyNameAndValue(List keyList, EdmEntitySet edmEntitySet, + List values, List propertyNames) throws DataProviderException { + for (final UriParameter key : keyList) { + EdmKeyPropertyRef refType = edmEntitySet.getEntityType().getKeyPropertyRef(key.getName()); + final EdmProperty property = refType.getProperty(); + final EdmPrimitiveType type = (EdmPrimitiveType) property.getType(); + try { + values.add(type.fromUriLiteral(key.getText())); + } catch (EdmPrimitiveTypeException e) { + throw new DataProviderException("Wrong key!", HttpStatusCode.BAD_REQUEST, e); + } + propertyNames.add(key.getName()); + } + } private static Entity createAllPrimEntity(final Short key, final String val, final Calendar date, final OData oData, final Edm edm) throws DataProviderException { @@ -247,6 +511,73 @@ public class ActionData { HttpStatusCode.NOT_IMPLEMENTED); } + protected static EntityCollection entityCollectionBoundAction(final String name, + final Map parameters, + Map data, final OData oData, final Edm edm, EdmEntitySet edmEntitySet) + throws DataProviderException { + if ("BAESTwoKeyNavRTESTwoKeyNav".equals(name)) { + EntityCollection collection = data.get(edmEntitySet.getName()); + collection.getEntities().add(createETTwoKeyNav((short)111, "newValue", oData, edm)); + return collection; + } + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } + + protected static EntityCollection entityCollectionBoundActionWithNav(final String name, + final Map parameters, Map data, + final OData oData, final Edm edm, EdmEntitySet edmEntitySet, EdmNavigationProperty navProperty) + throws DataProviderException { + throw new DataProviderException("Action " + name + " is not yet implemented.", + HttpStatusCode.NOT_IMPLEMENTED); + } + + @SuppressWarnings("unchecked") + private static Entity createETTwoKeyNav (final short number, final String value, final OData oData, + final Edm edm) throws DataProviderException { + Entity entity = new Entity() + .addProperty(DataCreator.createPrimitive("PropertyInt16", number)) + .addProperty(DataCreator.createPrimitive("PropertyString", value)) + .addProperty(DataCreator.createComplex("PropertyComp", + ComplexTypeProvider.nameCTPrimComp.getFullQualifiedNameAsString(), + DataCreator.createPrimitive("PropertyInt16", 11), + DataCreator.createComplex("PropertyComp", + ComplexTypeProvider.nameCTAllPrim.getFullQualifiedNameAsString(), + DataCreator.createPrimitive("PropertyString", "StringValue"), + DataCreator.createPrimitive("PropertyBinary", new byte[] { 1, 35, 69, 103, -119, -85, -51, -17 }), + DataCreator.createPrimitive("PropertyBoolean", true), + DataCreator.createPrimitive("PropertyByte", (short) 255), + DataCreator.createPrimitive("PropertyDate", null), + DataCreator.createPrimitive("PropertyDecimal", BigDecimal.valueOf(34)), + DataCreator.createPrimitive("PropertySingle", (float) 179000000000000000000D), + DataCreator.createPrimitive("PropertyDouble", -179000000000000000000D), + DataCreator.createPrimitive("PropertyDuration", BigDecimal.valueOf(6)), + DataCreator.createPrimitive("PropertyGuid", UUID.fromString("01234567-89ab-cdef-0123-456789abcdef")), + DataCreator.createPrimitive("PropertyInt16", Short.MAX_VALUE), + DataCreator.createPrimitive("PropertyInt32", Integer.MAX_VALUE), + DataCreator.createPrimitive("PropertyInt64", Long.MAX_VALUE), + DataCreator.createPrimitive("PropertySByte", Byte.MAX_VALUE), + DataCreator.createPrimitive("PropertyTimeOfDay", null)))) + .addProperty(DataCreator.createComplex("PropertyCompNav", + ComplexTypeProvider.nameCTBasePrimCompNav.getFullQualifiedNameAsString(), + DataCreator.createPrimitive("PropertyInt16", (short) 1), + createKeyNavAllPrimComplexValue("PropertyComp"))) + .addProperty(DataCreator.createComplexCollection("CollPropertyComp", null)) + .addProperty(DataCreator.createComplexCollection("CollPropertyCompNav", + ComplexTypeProvider.nameCTNavFiveProp.getFullQualifiedNameAsString(), + Arrays.asList( + DataCreator.createPrimitive("PropertyInt16", (short) 1)))) + .addProperty(DataCreator.createPrimitiveCollection("CollPropertyString", + "1", + "2")) + .addProperty(DataCreator.createComplex("PropertyCompTwoPrim", + ComplexTypeProvider.nameCTTwoPrim.getFullQualifiedNameAsString(), + DataCreator.createPrimitive("PropertyInt16", (short) 11), + DataCreator.createPrimitive("PropertyString", "11"))); + setEntityId(entity, "ESTwoKeyNav", oData, edm); + return entity; + } + @SuppressWarnings("unchecked") private static Entity createETKeyNavEntity(final Short number, final OData oData, final Edm edm) throws DataProviderException { @@ -274,7 +605,7 @@ public class ActionData { setEntityId(entity, "ESKeyNav", oData, edm); return entity; } - + private static void setEntityId(Entity entity, final String entitySetName, final OData oData, final Edm edm) throws DataProviderException { try { diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java index 9e5acded9..0a90d120a 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java @@ -664,31 +664,84 @@ public class DataProvider { return ActionData.primitiveAction(name, actionParameters); } + public Property processBoundActionPrimitive(final String name, final Map actionParameters, + final EdmEntitySet edmEntitySet, final List keyList) + throws DataProviderException { + return ActionData.primitiveBoundAction(name, actionParameters, data, edmEntitySet, keyList); + } + public Property processActionComplex(final String name, final Map actionParameters) throws DataProviderException { return ActionData.complexAction(name, actionParameters); } + public Property processBoundActionComplex(final String name, final Map actionParameters, + final EdmEntitySet edmEntitySet, + final List keyList) + throws DataProviderException { + return ActionData.complexBoundAction(name, actionParameters, data, edmEntitySet, keyList); + } + public Property processActionComplexCollection(final String name, final Map actionParameters) throws DataProviderException { return ActionData.complexCollectionAction(name, actionParameters); } + public Property processBoundActionComplexCollection(final String name, + final Map actionParameters, final EdmEntitySet edmEntitySet, + final List keyList) + throws DataProviderException { + return ActionData.complexCollectionBoundAction(name, actionParameters, data, edmEntitySet, keyList); + } + public Property processActionPrimitiveCollection(final String name, final Map actionParameters) throws DataProviderException { return ActionData.primitiveCollectionAction(name, actionParameters, odata); } + public Property processBoundActionPrimitiveCollection(final String name, + final Map actionParameters, final EdmEntitySet edmEntitySet, + final List keyList) + throws DataProviderException { + return ActionData.primitiveCollectionBoundAction(name, actionParameters, data, edmEntitySet, keyList, odata); + } + public EntityActionResult processActionEntity(final String name, final Map actionParameters) throws DataProviderException { return ActionData.entityAction(name, actionParameters, data, odata, edm); } + public EntityActionResult processBoundActionEntity(final String name, final Map actionParameters, + List keyList, EdmEntitySet edmEntitySet) + throws DataProviderException { + return ActionData.entityBoundAction(name, actionParameters, data, odata, edm, keyList, edmEntitySet); + } + + public EntityActionResult processBoundActionWithNavigationEntity(final String name, + final Map actionParameters, + List keyList, EdmEntitySet edmEntitySet, EdmNavigationProperty navProperty) + throws DataProviderException { + return ActionData.entityBoundActionWithNavigation(name, actionParameters, data, keyList, + edmEntitySet, navProperty); + } + public EntityCollection processActionEntityCollection(final String name, final Map actionParameters) throws DataProviderException { return ActionData.entityCollectionAction(name, actionParameters, odata, edm); } + public EntityCollection processBoundActionEntityCollection(final String name, + final Map actionParameters, EdmEntitySet edmEntitySet) throws DataProviderException { + return ActionData.entityCollectionBoundAction(name, actionParameters, data, odata, edm, edmEntitySet); + } + + public EntityCollection processBoundActionWithNavEntityCollection(final String name, + final Map actionParameters, EdmEntitySet edmEntitySet, EdmNavigationProperty navProperty) + throws DataProviderException { + return ActionData.entityCollectionBoundActionWithNav(name, actionParameters, data, odata, edm, + edmEntitySet, navProperty); + } + public void createReference(final Entity entity, final EdmNavigationProperty navigationProperty, final URI entityId, final String rawServiceRoot) throws DataProviderException { setLink(navigationProperty, entity, getEntityByReference(entityId.toASCIIString(), rawServiceRoot)); 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 c4afc9c8b..c4964a2dc 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 @@ -20,6 +20,8 @@ package org.apache.olingo.server.tecsvc.processor; import java.io.InputStream; import java.util.Collections; +import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; @@ -31,8 +33,10 @@ import org.apache.olingo.commons.api.data.Parameter; import org.apache.olingo.commons.api.data.Property; import org.apache.olingo.commons.api.edm.EdmAction; import org.apache.olingo.commons.api.edm.EdmComplexType; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; 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.format.ContentType; import org.apache.olingo.commons.api.http.HttpHeader; @@ -58,7 +62,10 @@ import org.apache.olingo.server.api.serializer.EntitySerializerOptions; import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions; import org.apache.olingo.server.api.serializer.SerializerResult; import org.apache.olingo.server.api.uri.UriInfo; +import org.apache.olingo.server.api.uri.UriResource; import org.apache.olingo.server.api.uri.UriResourceAction; +import org.apache.olingo.server.api.uri.UriResourceEntitySet; +import org.apache.olingo.server.api.uri.UriResourceNavigation; import org.apache.olingo.server.tecsvc.data.DataProvider; import org.apache.olingo.server.tecsvc.data.EntityActionResult; @@ -79,13 +86,36 @@ public class TechnicalActionProcessor extends TechnicalProcessor public void processActionEntityCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - final Map parameters = readParameters(action, request.getBody(), requestFormat); - EntityCollection collection = - dataProvider.processActionEntityCollection(action.getName(), parameters); - + Map parameters = new HashMap(); + EdmAction action = null; + EntityCollection collection = null; + List resourcePaths = uriInfo.asUriInfoResource().getUriResourceParts(); + if (resourcePaths.size() > 1) { + UriResourceEntitySet boundEntityCollection = (UriResourceEntitySet) resourcePaths.get(0); + if (resourcePaths.get(1) instanceof UriResourceNavigation) { + UriResourceNavigation navResource = (UriResourceNavigation) resourcePaths.get(1); + EdmNavigationProperty navProperty = navResource.getProperty(); + action = ((UriResourceAction) resourcePaths.get(2)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + collection = + dataProvider.processBoundActionWithNavEntityCollection(action.getName(), parameters, + boundEntityCollection.getEntitySet(), navProperty); + } else if (resourcePaths.get(0) instanceof UriResourceEntitySet) { + action = ((UriResourceAction) resourcePaths.get(1)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + collection = + dataProvider.processBoundActionEntityCollection(action.getName(), parameters, + boundEntityCollection.getEntitySet()); + } + } else { + action = ((UriResourceAction) resourcePaths.get(0)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + collection = + dataProvider.processActionEntityCollection(action.getName(), parameters); + } // Collections must never be null. // Not nullable return types must not contain a null value. if (collection == null @@ -118,15 +148,57 @@ public class TechnicalActionProcessor extends TechnicalProcessor public void processActionEntity(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); + EdmAction action = null; + Map parameters = new HashMap(); + EntityActionResult entityResult = null; + + final List resourcePaths = uriInfo.asUriInfoResource().getUriResourceParts(); + if (resourcePaths.size() > 1) { + UriResourceEntitySet boundEntity = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet entitySet = boundEntity.getEntitySet(); + if (resourcePaths.get(1) instanceof UriResourceNavigation) { + UriResourceNavigation navEntity = (UriResourceNavigation) resourcePaths.get(1); + action = ((UriResourceAction) resourcePaths.get(2)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + if (navEntity.getTypeFilterOnEntry() != null) { + EdmEntityType edmEntityType = (EdmEntityType) navEntity. + getTypeFilterOnEntry(); + entitySet = getTypeCastedEntitySet(entitySet, edmEntityType); + entityResult = + dataProvider.processBoundActionEntity(action.getName(), parameters, boundEntity.getKeyPredicates(), + entitySet); + } else { + EdmNavigationProperty navProperty = navEntity.getProperty(); + entityResult = + dataProvider.processBoundActionWithNavigationEntity(action.getName(), + parameters, boundEntity.getKeyPredicates(), + entitySet, navProperty); + } + } else if (resourcePaths.get(0) instanceof UriResourceEntitySet) { + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + action = ((UriResourceAction) resourcePaths.get(1)) + .getAction(); + if (uriResourceEntitySet.getTypeFilterOnEntry() != null) { + EdmEntityType edmEntityType = (EdmEntityType) uriResourceEntitySet. + getTypeFilterOnEntry(); + entitySet = getTypeCastedEntitySet(entitySet, edmEntityType); + } + parameters = readParameters(action, request.getBody(), requestFormat); + entityResult = + dataProvider.processBoundActionEntity(action.getName(), parameters, boundEntity.getKeyPredicates(), + entitySet); + } + } else { + action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + entityResult = + dataProvider.processActionEntity(action.getName(), parameters); + } final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource()); final EdmEntityType type = (EdmEntityType) action.getReturnType().getType(); - final Map parameters = readParameters(action, request.getBody(), requestFormat); - final EntityActionResult entityResult = - dataProvider.processActionEntity(action.getName(), parameters); if (entityResult == null || entityResult.getEntity() == null) { if (action.getReturnType().isNullable()) { response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode()); @@ -169,17 +241,47 @@ public class TechnicalActionProcessor extends TechnicalProcessor } } } + + /** + * @param entitySet + * @param edmType + * @param edmEntityType + * @return + */ + private EdmEntitySet getTypeCastedEntitySet(EdmEntitySet entitySet, EdmEntityType edmEntityType) { + EdmEntityContainer container = serviceMetadata.getEdm().getEntityContainer(); + List entitySets = container.getEntitySets(); + for (EdmEntitySet enSet : entitySets) { + if (enSet.getEntityType().getFullQualifiedName().getFullQualifiedNameAsString().equals + (edmEntityType.getFullQualifiedName().getFullQualifiedNameAsString())) { + entitySet = enSet; + break; + } + } + return entitySet; + } @Override public void processActionPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - final Map parameters = readParameters(action, request.getBody(), requestFormat); - Property property = - dataProvider.processActionPrimitiveCollection(action.getName(), parameters); + EdmAction action = null; + Map parameters = null; + List uriResource = uriInfo.asUriInfoResource().getUriResourceParts(); + Property property = null; + if (uriResource.size() > 1) { + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResource.get(0); + action = ((UriResourceAction) uriResource.get(uriResource.size() - 1)).getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = dataProvider.processBoundActionPrimitiveCollection(action.getName(), parameters, + uriResourceEntitySet.getEntitySet(), uriResourceEntitySet.getKeyPredicates()); + } else { + action = ((UriResourceAction) uriResource.get(0)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = + dataProvider.processActionPrimitiveCollection(action.getName(), parameters); + } if (property == null || property.isNull()) { // Collection Propertys must never be null @@ -214,11 +316,23 @@ public class TechnicalActionProcessor extends TechnicalProcessor public void processActionPrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - final Map parameters = readParameters(action, request.getBody(), requestFormat); - Property property = dataProvider.processActionPrimitive(action.getName(), parameters); + EdmAction action = null; + Map parameters = null; + List uriResource = uriInfo.asUriInfoResource().getUriResourceParts(); + Property property = null; + if (uriResource.size() > 1) { + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) uriResource.get(0); + action = ((UriResourceAction) uriResource.get(uriResource.size() - 1)).getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = dataProvider.processBoundActionPrimitive(action.getName(), parameters, + uriResourceEntitySet.getEntitySet(), uriResourceEntitySet.getKeyPredicates()); + } else { + action = ((UriResourceAction) uriResource.get(0)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = dataProvider.processActionPrimitive(action.getName(), parameters); + } + EdmPrimitiveType type = (EdmPrimitiveType) action.getReturnType().getType(); if (property == null || property.isNull()) { if (action.getReturnType().isNullable()) { @@ -252,13 +366,29 @@ public class TechnicalActionProcessor extends TechnicalProcessor public void processActionComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - final Map parameters = readParameters(action, request.getBody(), requestFormat); - Property property = - dataProvider.processActionComplexCollection(action.getName(), parameters); - + EdmAction action = null; + Map parameters = null; + Property property = null; + final List resourcePaths = uriInfo.asUriInfoResource().getUriResourceParts(); + if (resourcePaths.size() > 1) { + if (resourcePaths.get(0) instanceof UriResourceEntitySet) { + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet entitySet = uriResourceEntitySet.getEntitySet(); + action = ((UriResourceAction) resourcePaths.get(resourcePaths.size() - 1)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = + dataProvider.processBoundActionComplexCollection(action.getName(), parameters, entitySet, + uriResourceEntitySet.getKeyPredicates()); + } + } else { + action = ((UriResourceAction) resourcePaths.get(0)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = + dataProvider.processActionComplexCollection(action.getName(), parameters); + } + if (property == null || property.isNull()) { // Collection Propertys must never be null throw new ODataApplicationException("The action could not be executed.", @@ -291,11 +421,28 @@ public class TechnicalActionProcessor extends TechnicalProcessor public void processActionComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat) throws ODataApplicationException, ODataLibraryException { - blockBoundActions(uriInfo); - final EdmAction action = ((UriResourceAction) uriInfo.asUriInfoResource().getUriResourceParts().get(0)) - .getAction(); - final Map parameters = readParameters(action, request.getBody(), requestFormat); - Property property = dataProvider.processActionComplex(action.getName(), parameters); + EdmAction action = null; + Map parameters = null; + Property property = null; + final List resourcePaths = uriInfo.asUriInfoResource().getUriResourceParts(); + if (resourcePaths.size() > 1) { + if (resourcePaths.get(0) instanceof UriResourceEntitySet) { + UriResourceEntitySet uriResourceEntitySet = (UriResourceEntitySet) resourcePaths.get(0); + EdmEntitySet entitySet = uriResourceEntitySet.getEntitySet(); + action = ((UriResourceAction) resourcePaths.get(resourcePaths.size() - 1)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = + dataProvider.processBoundActionComplex(action.getName(), parameters, entitySet, + uriResourceEntitySet.getKeyPredicates()); + } + } else { + action = ((UriResourceAction) resourcePaths.get(0)) + .getAction(); + parameters = readParameters(action, request.getBody(), requestFormat); + property = dataProvider.processActionComplex(action.getName(), parameters); + } + EdmComplexType type = (EdmComplexType) action.getReturnType().getType(); if (property == null || property.isNull()) { if (action.getReturnType().isNullable()) { @@ -339,7 +486,8 @@ public class TechnicalActionProcessor extends TechnicalProcessor final ContentType requestFormat) throws ODataApplicationException, DeserializerException { if (action.getParameterNames().size() - (action.isBound() ? 1 : 0) > 0) { checkRequestFormat(requestFormat); - return odata.createDeserializer(requestFormat).actionParameters(body, action).getActionParameters(); + return odata.createDeserializer(requestFormat, serviceMetadata). + actionParameters(body, action).getActionParameters(); } return Collections. emptyMap(); } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ActionProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ActionProvider.java index 4f1559c81..f280a102b 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ActionProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ActionProvider.java @@ -74,6 +74,25 @@ public class ActionProvider { public static final FullQualifiedName nameBAETTwoKeyNavRTETTwoKeyNavParam = new FullQualifiedName(SchemaProvider.NAMESPACE, "BAETTwoKeyNavRTETTwoKeyNavParam"); + public static final FullQualifiedName nameBAETBaseETTwoBaseRTETTwoBase = + new FullQualifiedName(SchemaProvider.NAMESPACE, "BAETBaseETTwoBaseRTETTwoBase"); + + public static final FullQualifiedName nameBAETMixPrimCollCompRTCTTwoPrim = + new FullQualifiedName(SchemaProvider.NAMESPACE, "BAETMixPrimCollCompRTCTTwoPrim"); + + public static final FullQualifiedName nameBAETMixPrimCollCompCTTwoPrimRTCTTwoPrim = + new FullQualifiedName(SchemaProvider.NAMESPACE, "BAETMixPrimCollCompCTTwoPrimRTCTTwoPrim"); + + public static final FullQualifiedName nameBAETMixPrimCollCompCTTWOPrimCompRTCTTwoPrim = + new FullQualifiedName(SchemaProvider.NAMESPACE, "BAETMixPrimCollCompCTTWOPrimCompRTCTTwoPrim"); + + public static final FullQualifiedName nameBAETMixPrimCollCompCTTWOPrimCompRTCollCTTwoPrim = + new FullQualifiedName(SchemaProvider.NAMESPACE, "BAETMixPrimCollCompCTTWOPrimCompRTCollCTTwoPrim"); + + public static final FullQualifiedName + nameBAETTwoKeyNavCTBasePrimCompNavCTTwoBasePrimCompNavRTCTTwoBasePrimCompNav = + new FullQualifiedName(SchemaProvider.NAMESPACE, + "BAETTwoKeyNavCTBasePrimCompNavCTTwoBasePrimCompNavRTCTTwoBasePrimCompNav"); // Unknown Actions public static final FullQualifiedName name_A_RTTimeOfDay_ = new FullQualifiedName(SchemaProvider.NAMESPACE, "_A_RTTimeOfDay_"); @@ -109,7 +128,7 @@ public class ActionProvider { nameBAETTwoBaseTwoKeyNavRTETBaseTwoKeyNav, nameBA_RTETTwoKeyNav,nameBAESAllPrimRT, nameBAETAllPrimRT, nameBAETTwoPrimRTString, nameBAETTwoPrimRTCollString, nameBAETTwoPrimRTCTAllPrim, nameBAETTwoPrimRTCollCTAllPrim, nameBAETCompAllPrimRTETCompAllPrim, nameBAETTwoKeyNavRTETTwoKeyNavParam, - name_A_RTTimeOfDay_ }; + nameBAETBaseETTwoBaseRTETTwoBase, nameBAETMixPrimCollCompRTCTTwoPrim, name_A_RTTimeOfDay_ }; List actions = new ArrayList(); for (FullQualifiedName fqn:actionNames) { @@ -404,10 +423,67 @@ public class ActionProvider { .setParameters(Arrays.asList( new CsdlParameter().setName("BindingParam").setType(EntityTypeProvider.nameETTwoKeyNav) .setNullable(false), - new CsdlParameter().setName("ParameterInt16").setType(PropertyProvider.nameInt16) + new CsdlParameter().setName("PropertyComp").setType(ComplexTypeProvider.nameCTPrimComp) .setNullable(false))) .setReturnType(new CsdlReturnType().setType(EntityTypeProvider.nameETTwoKeyNav))); - } + } else if (actionName.equals(nameBAETBaseETTwoBaseRTETTwoBase)) { + return Collections.singletonList( + new CsdlAction().setName(nameBAETBaseETTwoBaseRTETTwoBase.getName()) + .setBound(true) + .setEntitySetPath("BindingParam/olingo.odata.test1.ETTwoBase") + .setParameters(Arrays.asList( + new CsdlParameter().setName("BindingParam").setType(EntityTypeProvider.nameETBase) + .setNullable(false), + new CsdlParameter().setName("PropertyString").setType(PropertyProvider.nameString) + .setNullable(false), + new CsdlParameter().setName("AdditionalPropertyString_5").setType(PropertyProvider.nameString) + .setNullable(false), + new CsdlParameter().setName("AdditionalPropertyString_6").setType(PropertyProvider.nameString) + .setNullable(false))) + .setReturnType(new CsdlReturnType().setType(EntityTypeProvider.nameETTwoBase))); + } else if (actionName.equals(nameBAETMixPrimCollCompRTCTTwoPrim)) { + return Collections.singletonList( + new CsdlAction().setName(nameBAETMixPrimCollCompRTCTTwoPrim.getName()) + .setBound(true) + .setParameters(Arrays.asList( + new CsdlParameter().setName("BindingParam").setType(EntityTypeProvider.nameETMixPrimCollComp) + .setNullable(false), + new CsdlParameter().setName("CollPropertyComp").setType(ComplexTypeProvider.nameCTTwoPrim) + .setNullable(false).setCollection(true))) + .setReturnType(new CsdlReturnType().setType(ComplexTypeProvider.nameCTTwoPrim).setCollection(true))); + } else if (actionName.equals(nameBAETMixPrimCollCompCTTWOPrimCompRTCTTwoPrim)) { + return Collections.singletonList( + new CsdlAction().setName(nameBAETMixPrimCollCompCTTWOPrimCompRTCTTwoPrim.getName()) + .setBound(true) + .setEntitySetPath("BindingParam") + .setParameters(Arrays.asList( + new CsdlParameter().setName("BindingParam").setType(EntityTypeProvider.nameETMixPrimCollComp) + .setNullable(false), + new CsdlParameter().setName("PropertyComp").setType(ComplexTypeProvider.nameCTTwoPrim) + .setNullable(false))) + .setReturnType(new CsdlReturnType().setType(ComplexTypeProvider.nameCTTwoPrim))); + } else if (actionName.equals(nameBAETMixPrimCollCompCTTWOPrimCompRTCollCTTwoPrim)) { + return Collections.singletonList( + new CsdlAction().setName(nameBAETMixPrimCollCompCTTWOPrimCompRTCollCTTwoPrim.getName()) + .setBound(true) + .setEntitySetPath("BindingParam/CollPropertyComp") + .setParameters(Arrays.asList( + new CsdlParameter().setName("BindingParam").setType(EntityTypeProvider.nameETMixPrimCollComp) + .setNullable(false).setCollection(true), + new CsdlParameter().setName("PropertyComp").setType(ComplexTypeProvider.nameCTTwoPrim) + .setNullable(false))) + .setReturnType(new CsdlReturnType().setType(ComplexTypeProvider.nameCTTwoPrim).setCollection(true))); + } else if (actionName.equals(nameBAETTwoKeyNavCTBasePrimCompNavCTTwoBasePrimCompNavRTCTTwoBasePrimCompNav)) { + return Collections.singletonList( + new CsdlAction().setName( + nameBAETTwoKeyNavCTBasePrimCompNavCTTwoBasePrimCompNavRTCTTwoBasePrimCompNav.getName()) + .setBound(true) + .setEntitySetPath("BindingParam/PropertyCompNav/olingo.odata.test1.CTTwoBasePrimCompNav") + .setParameters(Arrays.asList( + new CsdlParameter().setName("BindingParam").setType(EntityTypeProvider.nameETTwoKeyNav) + .setNullable(false))) + .setReturnType(new CsdlReturnType().setType(ComplexTypeProvider.nameCTTwoBasePrimCompNav))); + } return null; } } diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java index 7cb32ae96..6d3997606 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/SchemaProvider.java @@ -128,6 +128,12 @@ public class SchemaProvider { actions.addAll(prov.getActions(ActionProvider.nameBAETTwoPrimRTCollCTAllPrim)); actions.addAll(prov.getActions(ActionProvider.nameBAETCompAllPrimRTETCompAllPrim)); actions.addAll(prov.getActions(ActionProvider.nameBAETTwoKeyNavRTETTwoKeyNavParam)); + actions.addAll(prov.getActions(ActionProvider.nameBAETMixPrimCollCompRTCTTwoPrim)); + actions.addAll(prov.getActions(ActionProvider.nameBAETBaseETTwoBaseRTETTwoBase)); + actions.addAll(prov.getActions(ActionProvider.nameBAETMixPrimCollCompCTTWOPrimCompRTCollCTTwoPrim)); + actions.addAll(prov.getActions(ActionProvider.nameBAETMixPrimCollCompCTTWOPrimCompRTCTTwoPrim)); + actions.addAll(prov.getActions(ActionProvider. + nameBAETTwoKeyNavCTBasePrimCompNavCTTwoBasePrimCompNavRTCTTwoBasePrimCompNav)); actions.addAll(prov.getActions(ActionProvider.nameUARTString)); actions.addAll(prov.getActions(ActionProvider.nameUARTCollStringTwoParam)); actions.addAll(prov.getActions(ActionProvider.nameUARTCTTwoPrimParam)); 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 9097d728b..c8476e3c5 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 @@ -678,6 +678,9 @@ public class ODataXmlSerializerTest { " \n" + " \n" + " \n" + + " \n" + "\n"; checkXMLEqual(expectedResult, resultString); } @@ -718,6 +721,9 @@ public class ODataXmlSerializerTest { " \n" + " \n" + " \n" + + " \n" + ""; checkXMLEqual(expectedResult, resultString); } @@ -2350,6 +2356,9 @@ public class ODataXmlSerializerTest { " TEST A 0815\n "+ " \n "+ " \n "+ + " \n" + " \n "+ " \n "+ " " +