From 4a1d5ab3434dd501f6ad3119d50432fc96cd91a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francesco=20Chicchiricc=C3=B2?= <--global> Date: Mon, 19 May 2014 13:23:42 +0200 Subject: [PATCH] API enhancements: simplified operation import invoke with EdmEnabledODataClient --- .../org/apache/olingo/fit/V4Services.java | 10 +- .../v4/OperationImportInvokeTestITCase.java | 91 +++++++++++++++- .../api/CommonEdmEnabledODataClient.java | 7 ++ .../EdmEnabledInvokeRequestFactory.java | 68 ++++++++++++ .../request/invoke/InvokeRequestFactory.java | 6 +- .../client/api/v3/EdmEnabledODataClient.java | 8 ++ .../client/api/v4/EdmEnabledODataClient.java | 7 ++ .../EdmEnabledInvokeRequestFactoryImpl.java | 100 ++++++++++++++++++ .../EdmEnabledInvokeRequestFactoryImpl.java | 100 ++++++++++++++++++ .../invoke/v4/ODataInvokeRequestImpl.java | 1 - .../client/core/op/AbstractODataBinder.java | 56 ++++++---- .../core/op/impl/v3/ODataBinderImpl.java | 14 ++- .../core/op/impl/v4/ODataBinderImpl.java | 24 ++++- .../core/v3/EdmEnabledODataClientImpl.java | 20 ++++ .../client/core/v3/ODataClientImpl.java | 2 +- .../core/v4/EdmEnabledODataClientImpl.java | 19 ++++ .../client/core/v4/ODataClientImpl.java | 2 +- .../olingo/client/core/v4/EntityTest.java | 2 +- 18 files changed, 504 insertions(+), 33 deletions(-) create mode 100644 lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/EdmEnabledInvokeRequestFactory.java create mode 100644 lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v3/EdmEnabledInvokeRequestFactoryImpl.java create mode 100644 lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/EdmEnabledInvokeRequestFactoryImpl.java diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java index efcd4e78f..9487d1e96 100644 --- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java +++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java @@ -351,7 +351,7 @@ public class V4Services extends AbstractServices { public Response getPeople( @Context UriInfo uriInfo, @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) String accept, - @PathParam("type") final String type, + @PathParam("type") final String type, @QueryParam("$top") @DefaultValue(StringUtils.EMPTY) String top, @QueryParam("$skip") @DefaultValue(StringUtils.EMPTY) String skip, @QueryParam("$format") @DefaultValue(StringUtils.EMPTY) String format, @@ -1269,9 +1269,15 @@ public class V4Services extends AbstractServices { assert "Microsoft.Test.OData.Services.ODataWCFService.Address".equals(entity.getType()); assert entity.getProperty("address").getValue().isComplex(); + final ResWrap result = new ResWrap( + URI.create(Constants.get(version, ConstantKey.ODATA_METADATA_PREFIX) + + "Microsoft.Test.OData.Services.ODataWCFService.Address"), + null, + (AtomPropertyImpl) entity.getProperty("address")); + return xml.createResponse( null, - xml.writeProperty(acceptType, entity.getProperty("address")), + xml.writeProperty(acceptType, result), null, acceptType); } catch (Exception e) { diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/OperationImportInvokeTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/OperationImportInvokeTestITCase.java index 36ad27ba8..9c6defb01 100644 --- a/fit/src/test/java/org/apache/olingo/fit/v4/OperationImportInvokeTestITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/v4/OperationImportInvokeTestITCase.java @@ -153,6 +153,67 @@ public class OperationImportInvokeTestITCase extends AbstractTestITCase { functionImports(ODataPubFormat.JSON_FULL_METADATA); } + @Test + public void edmEnabledFunctionImports() throws EdmPrimitiveTypeException { + // GetDefaultColor + final ODataInvokeRequest defaultColorReq = edmClient.getInvokeRequestFactory(). + getFunctionImportInvokeRequest("GetDefaultColor"); + final ODataProperty defaultColor = defaultColorReq.execute().getBody(); + assertNotNull(defaultColor); + assertTrue(defaultColor.hasEnumValue()); + assertEquals("Red", defaultColor.getEnumValue().getValue()); + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Color", defaultColor.getEnumValue().getTypeName()); + + // GetPerson2 + final ODataPrimitiveValue city = + getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("London"); + final ODataInvokeRequest person2Req = edmClient.getInvokeRequestFactory(). + getFunctionImportInvokeRequest( + "GetPerson2", Collections.singletonMap("city", city)); + final ODataEntity person2 = person2Req.execute().getBody(); + assertNotNull(person2); + assertEquals("Microsoft.Test.OData.Services.ODataWCFService.Customer", person2.getTypeName().toString()); + assertEquals(1, person2.getProperty("PersonID").getPrimitiveValue().toCastValue(Integer.class), 0); + + // GetPerson + final ODataComplexValue address = getClient().getObjectFactory(). + newLinkedComplexValue("Microsoft.Test.OData.Services.ODataWCFService.Address"); + address.add(client.getObjectFactory().newPrimitiveProperty("Street", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("1 Microsoft Way"))); + address.add(client.getObjectFactory().newPrimitiveProperty("City", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("London"))); + address.add(client.getObjectFactory().newPrimitiveProperty("PostalCode", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("98052"))); + + final ODataInvokeRequest personReq = edmClient.getInvokeRequestFactory(). + getFunctionImportInvokeRequest( + "GetPerson", Collections.singletonMap("address", address)); + final ODataEntity person = personReq.execute().getBody(); + assertNotNull(person); + assertEquals(person2, person); + + // GetAllProducts + final ODataInvokeRequest productsReq = edmClient.getInvokeRequestFactory(). + getFunctionImportInvokeRequest("GetAllProducts"); + final ODataEntitySet products = productsReq.execute().getBody(); + assertNotNull(products); + assertEquals(5, products.getCount()); + + // GetProductsByAccessLevel + final ODataEnumValue accessLevel = getClient().getObjectFactory(). + newEnumValue("Microsoft.Test.OData.Services.ODataWCFService.AccessLevel", "None"); + + final ODataInvokeRequest prodByALReq = edmClient.getInvokeRequestFactory(). + getFunctionImportInvokeRequest( + "GetProductsByAccessLevel", + Collections.singletonMap("accessLevel", accessLevel)); + final ODataProperty prodByAL = prodByALReq.execute().getBody(); + assertNotNull(prodByAL); + assertTrue(prodByAL.hasCollectionValue()); + assertEquals(5, prodByAL.getCollectionValue().size()); + assertTrue(prodByAL.getCollectionValue().asJavaCollection().contains("Car")); + } + private void actionImports(final ODataPubFormat format) { final Edm edm = getEdm(); final EdmEntityContainer container = edm.getSchemas().get(0).getEntityContainer(); @@ -204,6 +265,34 @@ public class OperationImportInvokeTestITCase extends AbstractTestITCase { actionImports(ODataPubFormat.JSON_FULL_METADATA); } + @Test + public void edmEnabledActionImports() { + // Discount + final ODataPrimitiveValue percentage = getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(22); + final ODataInvokeRequest discountReq = edmClient.getInvokeRequestFactory(). + getActionImportInvokeRequest( + "Discount", Collections.singletonMap("percentage", percentage)); + final ODataNoContent discount = discountReq.execute().getBody(); + assertNotNull(discount); + + // ResetBossAddress + final ODataComplexValue address = getClient().getObjectFactory(). + newLinkedComplexValue("Microsoft.Test.OData.Services.ODataWCFService.Address"); + address.add(client.getObjectFactory().newPrimitiveProperty("Street", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Via Le Mani Dal Naso, 123"))); + address.add(client.getObjectFactory().newPrimitiveProperty("City", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("Tollo"))); + address.add(client.getObjectFactory().newPrimitiveProperty("PostalCode", + client.getObjectFactory().newPrimitiveValueBuilder().buildString("66010"))); + + final ODataInvokeRequest resetBossAddressReq = edmClient.getInvokeRequestFactory(). + getActionImportInvokeRequest( + "ResetBossAddress", Collections.singletonMap("address", address)); + final ODataProperty resetBossAddress = resetBossAddressReq.execute().getBody(); + assertNotNull(resetBossAddress); + assertEquals(address.getTypeName(), resetBossAddress.getComplexValue().getTypeName()); + } + private void bossEmails(final ODataPubFormat format) { final Edm edm = getEdm(); final EdmEntityContainer container = edm.getSchemas().get(0).getEntityContainer(); @@ -242,7 +331,7 @@ public class OperationImportInvokeTestITCase extends AbstractTestITCase { assertNotNull(bossEmailsViaGET); assertTrue(bossEmailsViaGET.hasCollectionValue()); assertEquals(2, bossEmailsViaGET.getCollectionValue().size()); - assertEquals(bossEmails.getCollectionValue().asJavaCollection(), + assertEquals(bossEmails.getCollectionValue().asJavaCollection(), bossEmailsViaGET.getCollectionValue().asJavaCollection()); } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java index bb06abfd9..ab5569ee7 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/CommonEdmEnabledODataClient.java @@ -19,6 +19,8 @@ package org.apache.olingo.client.api; import org.apache.olingo.client.api.communication.request.cud.CommonUpdateType; +import org.apache.olingo.client.api.communication.request.invoke.EdmEnabledInvokeRequestFactory; +import org.apache.olingo.client.api.uri.CommonURIBuilder; import org.apache.olingo.commons.api.edm.Edm; /** @@ -47,4 +49,9 @@ public interface CommonEdmEnabledODataClient extend * @return Edm */ Edm getCachedEdm(); + + CommonURIBuilder getURIBuilder(); + + @Override + EdmEnabledInvokeRequestFactory getInvokeRequestFactory(); } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/EdmEnabledInvokeRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/EdmEnabledInvokeRequestFactory.java new file mode 100644 index 000000000..a29d1248d --- /dev/null +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/EdmEnabledInvokeRequestFactory.java @@ -0,0 +1,68 @@ +/* + * 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.client.api.communication.request.invoke; + +import java.util.Map; +import org.apache.olingo.commons.api.domain.ODataInvokeResult; +import org.apache.olingo.commons.api.domain.ODataValue; + +public interface EdmEnabledInvokeRequestFactory extends InvokeRequestFactory { + + /** + * Gets an invoke request instance for the first function import with the given name (no overloading supported). + * + * @param OData domain object result, derived from return type defined in the function import + * @param functionImportName operation to be invoked + * @return new {@link ODataInvokeRequest} instance. + */ + ODataInvokeRequest getFunctionImportInvokeRequest( + String functionImportName); + + /** + * Gets an invoke request instance for the first function import with the given name (no overloading supported). + * + * @param OData domain object result, derived from return type defined in the function import + * @param functionImportName operation to be invoked + * @param parameters parameters to pass to operation import invocation + * @return new {@link ODataInvokeRequest} instance. + */ + ODataInvokeRequest getFunctionImportInvokeRequest( + String functionImportName, Map parameters); + + /** + * Gets an invoke request instance for the action import with the given name. + * + * @param OData domain object result, derived from return type defined in the function import + * @param actionImportName operation to be invoked + * @return new {@link ODataInvokeRequest} instance. + */ + ODataInvokeRequest getActionImportInvokeRequest( + String actionImportName); + + /** + * Gets an invoke request instance for the action import with the given name. + * + * @param OData domain object result, derived from return type defined in the function import + * @param actionImportName operation to be invoked + * @param parameters parameters to pass to operation import invocation + * @return new {@link ODataInvokeRequest} instance. + */ + ODataInvokeRequest getActionImportInvokeRequest( + String actionImportName, Map parameters); +} diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java index e25a168cd..1eeaf1c9f 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/invoke/InvokeRequestFactory.java @@ -36,7 +36,7 @@ public interface InvokeRequestFactory extends Serializable { * @param OData domain object result, derived from return type defined in the function import * @param uri URI that identifies the function import * @param operation operation to be invoked - * @return new ODataInvokeRequest instance. + * @return new {@link ODataInvokeRequest} instance. */ ODataInvokeRequest getInvokeRequest(URI uri, EdmOperation operation); @@ -46,8 +46,8 @@ public interface InvokeRequestFactory extends Serializable { * @param OData domain object result, derived from return type defined in the function import * @param uri URI that identifies the function import * @param operation operation to be invoked - * @param parameters parameters to pass to function import invocation - * @return new ODataInvokeRequest instance. + * @param parameters parameters to pass to operation invocation + * @return new {@link ODataInvokeRequest} instance. */ ODataInvokeRequest getInvokeRequest( URI uri, EdmOperation operation, Map parameters); diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java index 379c8b0f5..6f525aab3 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v3/EdmEnabledODataClient.java @@ -20,7 +20,15 @@ package org.apache.olingo.client.api.v3; import org.apache.olingo.client.api.CommonEdmEnabledODataClient; import org.apache.olingo.client.api.communication.request.cud.v3.UpdateType; +import org.apache.olingo.client.api.communication.request.invoke.EdmEnabledInvokeRequestFactory; +import org.apache.olingo.client.api.uri.v3.URIBuilder; public interface EdmEnabledODataClient extends CommonEdmEnabledODataClient, ODataClient { + @Override + URIBuilder getURIBuilder(); + + @Override + EdmEnabledInvokeRequestFactory getInvokeRequestFactory(); + } diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java index abd341d8e..3f6a49c88 100644 --- a/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java +++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/v4/EdmEnabledODataClient.java @@ -20,7 +20,14 @@ package org.apache.olingo.client.api.v4; import org.apache.olingo.client.api.CommonEdmEnabledODataClient; import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType; +import org.apache.olingo.client.api.communication.request.invoke.EdmEnabledInvokeRequestFactory; +import org.apache.olingo.client.api.uri.v4.URIBuilder; public interface EdmEnabledODataClient extends CommonEdmEnabledODataClient, ODataClient { + @Override + URIBuilder getURIBuilder(); + + @Override + EdmEnabledInvokeRequestFactory getInvokeRequestFactory(); } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v3/EdmEnabledInvokeRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v3/EdmEnabledInvokeRequestFactoryImpl.java new file mode 100644 index 000000000..c6a6fd3a3 --- /dev/null +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v3/EdmEnabledInvokeRequestFactoryImpl.java @@ -0,0 +1,100 @@ +/* + * 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.client.core.communication.request.invoke.v3; + +import java.util.Map; +import org.apache.olingo.client.api.communication.request.invoke.EdmEnabledInvokeRequestFactory; +import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest; +import org.apache.olingo.client.api.v3.EdmEnabledODataClient; +import org.apache.olingo.commons.api.domain.ODataInvokeResult; +import org.apache.olingo.commons.api.domain.ODataValue; +import org.apache.olingo.commons.api.edm.EdmActionImport; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmFunctionImport; +import org.apache.olingo.commons.api.edm.EdmSchema; + +public class EdmEnabledInvokeRequestFactoryImpl + extends InvokeRequestFactoryImpl implements EdmEnabledInvokeRequestFactory { + + private static final long serialVersionUID = 5854571629835831697L; + + private final EdmEnabledODataClient edmClient; + + public EdmEnabledInvokeRequestFactoryImpl(final EdmEnabledODataClient client) { + super(client); + this.edmClient = client; + } + + @Override + public ODataInvokeRequest getFunctionImportInvokeRequest( + final String functionImportName) { + + return getFunctionImportInvokeRequest(functionImportName, null); + } + + @Override + public ODataInvokeRequest getFunctionImportInvokeRequest( + final String functionImportName, final Map parameters) { + + EdmFunctionImport efi = null; + for (EdmSchema schema : edmClient.getCachedEdm().getSchemas()) { + final EdmEntityContainer container = schema.getEntityContainer(); + if (container != null) { + efi = container.getFunctionImport(functionImportName); + } + } + if (efi == null) { + throw new IllegalArgumentException("Could not find FunctionImport for name " + functionImportName); + } + + return getInvokeRequest( + edmClient.getURIBuilder().appendOperationCallSegment(functionImportName).build(), + efi.getUnboundFunctions().get(0), + parameters); + } + + @Override + public ODataInvokeRequest getActionImportInvokeRequest( + final String actionImportName) { + + return getActionImportInvokeRequest(actionImportName, null); + } + + @Override + public ODataInvokeRequest getActionImportInvokeRequest( + final String actionImportName, final Map parameters) { + + EdmActionImport eai = null; + for (EdmSchema schema : edmClient.getCachedEdm().getSchemas()) { + final EdmEntityContainer container = schema.getEntityContainer(); + if (container != null) { + eai = container.getActionImport(actionImportName); + } + } + if (eai == null) { + throw new IllegalArgumentException("Could not find ActionImport for name " + actionImportName); + } + + return getInvokeRequest( + edmClient.getURIBuilder().appendOperationCallSegment(actionImportName).build(), + eai.getUnboundAction(), + parameters); + } + +} diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/EdmEnabledInvokeRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/EdmEnabledInvokeRequestFactoryImpl.java new file mode 100644 index 000000000..b33e22592 --- /dev/null +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/EdmEnabledInvokeRequestFactoryImpl.java @@ -0,0 +1,100 @@ +/* + * 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.client.core.communication.request.invoke.v4; + +import java.util.Map; +import org.apache.olingo.client.api.communication.request.invoke.EdmEnabledInvokeRequestFactory; +import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest; +import org.apache.olingo.client.api.v4.EdmEnabledODataClient; +import org.apache.olingo.commons.api.domain.ODataInvokeResult; +import org.apache.olingo.commons.api.domain.ODataValue; +import org.apache.olingo.commons.api.edm.EdmActionImport; +import org.apache.olingo.commons.api.edm.EdmEntityContainer; +import org.apache.olingo.commons.api.edm.EdmFunctionImport; +import org.apache.olingo.commons.api.edm.EdmSchema; + +public class EdmEnabledInvokeRequestFactoryImpl + extends InvokeRequestFactoryImpl implements EdmEnabledInvokeRequestFactory { + + private static final long serialVersionUID = 5854571629835831697L; + + private final EdmEnabledODataClient edmClient; + + public EdmEnabledInvokeRequestFactoryImpl(final EdmEnabledODataClient client) { + super(client); + this.edmClient = client; + } + + @Override + public ODataInvokeRequest getFunctionImportInvokeRequest( + final String functionImportName) { + + return getFunctionImportInvokeRequest(functionImportName, null); + } + + @Override + public ODataInvokeRequest getFunctionImportInvokeRequest( + final String functionImportName, final Map parameters) { + + EdmFunctionImport efi = null; + for (EdmSchema schema : edmClient.getCachedEdm().getSchemas()) { + final EdmEntityContainer container = schema.getEntityContainer(); + if (container != null) { + efi = container.getFunctionImport(functionImportName); + } + } + if (efi == null) { + throw new IllegalArgumentException("Could not find FunctionImport for name " + functionImportName); + } + + return getInvokeRequest( + edmClient.getURIBuilder().appendOperationCallSegment(functionImportName).build(), + efi.getUnboundFunctions().get(0), + parameters); + } + + @Override + public ODataInvokeRequest getActionImportInvokeRequest( + final String actionImportName) { + + return getActionImportInvokeRequest(actionImportName, null); + } + + @Override + public ODataInvokeRequest getActionImportInvokeRequest( + final String actionImportName, final Map parameters) { + + EdmActionImport eai = null; + for (EdmSchema schema : edmClient.getCachedEdm().getSchemas()) { + final EdmEntityContainer container = schema.getEntityContainer(); + if (container != null) { + eai = container.getActionImport(actionImportName); + } + } + if (eai == null) { + throw new IllegalArgumentException("Could not find ActionImport for name " + actionImportName); + } + + return getInvokeRequest( + edmClient.getURIBuilder().appendOperationCallSegment(actionImportName).build(), + eai.getUnboundAction(), + parameters); + } + +} diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/ODataInvokeRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/ODataInvokeRequestImpl.java index 57d391fb8..7860c6b96 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/ODataInvokeRequestImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/invoke/v4/ODataInvokeRequestImpl.java @@ -86,5 +86,4 @@ public class ODataInvokeRequestImpl extends Abstrac throw new IllegalArgumentException("While adding GET parameters", e); } } - } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java index fad13e67b..550490224 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/AbstractODataBinder.java @@ -53,9 +53,11 @@ import org.apache.olingo.commons.api.domain.ODataServiceDocument; import org.apache.olingo.commons.api.domain.ODataValue; import org.apache.olingo.commons.api.edm.Edm; import org.apache.olingo.commons.api.edm.EdmBindingTarget; +import org.apache.olingo.commons.api.edm.EdmElement; import org.apache.olingo.commons.api.edm.EdmEntityContainer; import org.apache.olingo.commons.api.edm.EdmEntityType; import org.apache.olingo.commons.api.edm.EdmNavigationProperty; +import org.apache.olingo.commons.api.edm.EdmPrimitiveType; import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind; import org.apache.olingo.commons.api.edm.EdmProperty; import org.apache.olingo.commons.api.edm.EdmSchema; @@ -285,7 +287,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder { return entitySet; } - protected void odataNavigationLinks(final EdmStructuredType edmType, + protected void odataNavigationLinks(final EdmType edmType, final Linked linked, final ODataLinked odataLinked, final String metadataETag, final URI base) { for (Link link : linked.getNavigationLinks()) { @@ -294,8 +296,8 @@ public abstract class AbstractODataBinder implements CommonODataBinder { if (inlineEntity == null && inlineEntitySet == null) { ODataLinkType linkType = null; - if (edmType != null) { - final EdmNavigationProperty navProp = edmType.getNavigationProperty(link.getTitle()); + if (edmType instanceof EdmStructuredType) { + final EdmNavigationProperty navProp = ((EdmStructuredType) edmType).getNavigationProperty(link.getTitle()); if (navProp != null) { linkType = navProp.isCollection() ? ODataLinkType.ENTITY_SET_NAVIGATION @@ -338,8 +340,8 @@ public abstract class AbstractODataBinder implements CommonODataBinder { * @param metadataETag metadata ETag * @return Edm type information */ - private EdmEntityType findEntityType(final ContextURL contextURL, final String metadataETag) { - EdmEntityType entityType = null; + private EdmType findType(final ContextURL contextURL, final String metadataETag) { + EdmType type = null; if (client instanceof EdmEnabledODataClient && contextURL != null) { final Edm edm = ((EdmEnabledODataClient) client).getEdm(metadataETag); @@ -348,30 +350,33 @@ public abstract class AbstractODataBinder implements CommonODataBinder { for (EdmSchema schema : edm.getSchemas()) { final EdmEntityContainer container = schema.getEntityContainer(); - EdmBindingTarget bindingTarget = - container.getEntitySet(contextURL.getEntitySetOrSingletonOrType()); + EdmBindingTarget bindingTarget = container.getEntitySet(contextURL.getEntitySetOrSingletonOrType()); if (bindingTarget == null) { bindingTarget = container.getSingleton(contextURL.getEntitySetOrSingletonOrType()); } if (bindingTarget != null) { if (contextURL.getNavOrPropertyPath() == null) { - entityType = bindingTarget.getEntityType(); + type = bindingTarget.getEntityType(); } else { final EdmNavigationProperty navProp = bindingTarget.getEntityType(). getNavigationProperty(contextURL.getNavOrPropertyPath()); - entityType = navProp == null + type = navProp == null ? bindingTarget.getEntityType() : navProp.getType(); } } } + if (type == null) { + type = new EdmTypeInfo.Builder().setEdm(edm). + setTypeExpression(contextURL.getEntitySetOrSingletonOrType()).build().getType(); + } } else { - entityType = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity())); + type = edm.getEntityType(new FullQualifiedName(contextURL.getDerivedEntity())); } } - return entityType; + return type; } @Override @@ -386,7 +391,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder { final URI base = resource.getContextURL() == null ? resource.getPayload().getBaseURI() : resource.getContextURL().getServiceRoot(); - final EdmEntityType edmType = findEntityType(resource.getContextURL(), resource.getMetadataETag()); + final EdmType edmType = findType(resource.getContextURL(), resource.getMetadataETag()); FullQualifiedName typeName = null; if (resource.getPayload().getType() == null) { if (edmType != null) { @@ -434,8 +439,14 @@ public abstract class AbstractODataBinder implements CommonODataBinder { } for (Property property : resource.getPayload().getProperties()) { - add(entity, getODataProperty( - new ResWrap(resource.getContextURL(), resource.getMetadataETag(), property))); + EdmType propertyType = null; + if (edmType instanceof EdmEntityType) { + final EdmElement edmProperty = ((EdmEntityType) edmType).getProperty(property.getName()); + if (edmProperty != null) { + propertyType = edmProperty.getType(); + } + } + add(entity, getODataProperty(propertyType, property)); } return entity; @@ -445,14 +456,21 @@ public abstract class AbstractODataBinder implements CommonODataBinder { final String propertyName, final String propertyType) { FullQualifiedName typeName = null; - final EdmType entityType = findEntityType(contextURL, metadataETag); - if (entityType instanceof EdmStructuredType) { - final EdmProperty edmProperty = ((EdmStructuredType) entityType).getStructuralProperty(propertyName); + final EdmType type = findType(contextURL, metadataETag); + if (type instanceof EdmStructuredType) { + final EdmProperty edmProperty = ((EdmStructuredType) type).getStructuralProperty(propertyName); if (edmProperty != null) { typeName = edmProperty.getType().getFullQualifiedName(); } } + if (typeName == null && type != null) { + typeName = type.getFullQualifiedName(); + } + return buildTypeInfo(typeName, propertyType); + } + + protected EdmTypeInfo buildTypeInfo(final FullQualifiedName typeName, final String propertyType) { EdmTypeInfo typeInfo = null; if (typeName == null) { if (propertyType != null) { @@ -468,6 +486,8 @@ public abstract class AbstractODataBinder implements CommonODataBinder { return typeInfo; } + protected abstract CommonODataProperty getODataProperty(EdmType type, Property resource); + protected ODataValue getODataValue(final FullQualifiedName type, final Valuable valuable, final ContextURL contextURL, final String metadataETag) { @@ -475,7 +495,7 @@ public abstract class AbstractODataBinder implements CommonODataBinder { if (valuable.getValue().isPrimitive()) { value = client.getObjectFactory().newPrimitiveValueBuilder(). setText(valuable.getValue().asPrimitive().get()). - setType(type == null + setType(type == null || !EdmPrimitiveType.EDM_NAMESPACE.equals(type.getNamespace()) ? null : EdmPrimitiveTypeKind.valueOfFQN(client.getServiceVersion(), type.toString())).build(); } else if (valuable.getValue().isGeospatial()) { diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java index f9779537a..e59ad66f3 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v3/ODataBinderImpl.java @@ -34,6 +34,7 @@ import org.apache.olingo.commons.api.domain.ODataComplexValue; import org.apache.olingo.commons.api.domain.v3.ODataEntity; import org.apache.olingo.commons.api.domain.v3.ODataEntitySet; import org.apache.olingo.commons.api.domain.v3.ODataProperty; +import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.core.domain.v3.ODataPropertyImpl; import org.apache.olingo.commons.core.edm.EdmTypeInfo; import org.apache.olingo.commons.core.op.ResourceFactory; @@ -95,7 +96,18 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder return new ODataPropertyImpl(property.getPayload().getName(), getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(), - property.getPayload(), property.getContextURL(), property.getMetadataETag())); + property.getPayload(), property.getContextURL(), property.getMetadataETag())); + } + + @Override + protected ODataProperty getODataProperty(final EdmType type, final Property resource) { + final EdmTypeInfo typeInfo = buildTypeInfo(type == null ? null : type.getFullQualifiedName(), resource.getType()); + + return new ODataPropertyImpl(resource.getName(), + getODataValue(typeInfo == null + ? null + : typeInfo.getFullQualifiedName(), + resource, null, null)); } @Override diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java index 4738dde0c..ddf84fc6f 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/op/impl/v4/ODataBinderImpl.java @@ -63,8 +63,8 @@ import org.apache.olingo.commons.api.domain.v4.ODataProperty; import org.apache.olingo.commons.api.domain.v4.ODataValuable; import org.apache.olingo.commons.api.edm.EdmComplexType; import org.apache.olingo.commons.api.edm.EdmEnumType; -import org.apache.olingo.commons.api.edm.EdmStructuredType; import org.apache.olingo.commons.api.edm.EdmTerm; +import org.apache.olingo.commons.api.edm.EdmType; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.core.data.AnnotationImpl; import org.apache.olingo.commons.core.data.EnumValueImpl; @@ -259,7 +259,7 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder } @Override - protected void odataNavigationLinks(final EdmStructuredType edmType, + protected void odataNavigationLinks(final EdmType edmType, final Linked linked, final ODataLinked odataLinked, final String metadataETag, final URI base) { super.odataNavigationLinks(edmType, linked, odataLinked, metadataETag, base); @@ -283,16 +283,32 @@ public class ODataBinderImpl extends AbstractODataBinder implements ODataBinder @Override public ODataProperty getODataProperty(final ResWrap resource) { final EdmTypeInfo typeInfo = buildTypeInfo(resource.getContextURL(), resource.getMetadataETag(), - resource.getPayload().getName(), resource.getPayload().getType()); + resource.getPayload().getName(), resource.getPayload().getType()); final ODataProperty property = new ODataPropertyImpl(resource.getPayload().getName(), - getODataValue(typeInfo == null ? null : typeInfo.getFullQualifiedName(), + getODataValue(typeInfo == null + ? null + : typeInfo.getFullQualifiedName(), resource.getPayload(), resource.getContextURL(), resource.getMetadataETag())); odataAnnotations(resource.getPayload(), property); return property; } + @Override + protected ODataProperty getODataProperty(final EdmType type, final Property resource) { + final EdmTypeInfo typeInfo = buildTypeInfo(type == null ? null : type.getFullQualifiedName(), resource.getType()); + + final ODataProperty property = new ODataPropertyImpl(resource.getName(), + getODataValue(typeInfo == null + ? null + : typeInfo.getFullQualifiedName(), + resource, null, null)); + odataAnnotations(resource, property); + + return property; + } + @Override protected ODataValue getODataValue(final FullQualifiedName type, final Valuable valuable, final ContextURL contextURL, final String metadataETag) { diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java index 5d2cbe809..60f753d70 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/EdmEnabledODataClientImpl.java @@ -18,15 +18,21 @@ */ package org.apache.olingo.client.core.v3; +import org.apache.olingo.client.api.communication.request.invoke.EdmEnabledInvokeRequestFactory; import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.uri.v3.URIBuilder; import org.apache.olingo.client.api.v3.EdmEnabledODataClient; +import org.apache.olingo.client.core.communication.request.invoke.v3.EdmEnabledInvokeRequestFactoryImpl; +import org.apache.olingo.client.core.uri.v3.URIBuilderImpl; import org.apache.olingo.commons.api.edm.Edm; public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEnabledODataClient { private final String serviceRoot; + private EdmEnabledInvokeRequestFactory edmEnabledInvokeRequestFactory; + private Edm edm; public EdmEnabledODataClientImpl(final String serviceRoot) { @@ -57,4 +63,18 @@ public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEna } return this.edm; } + + @Override + public URIBuilder getURIBuilder() { + return new URIBuilderImpl(getServiceVersion(), configuration, serviceRoot); + } + + @Override + public EdmEnabledInvokeRequestFactory getInvokeRequestFactory() { + if (edmEnabledInvokeRequestFactory == null) { + edmEnabledInvokeRequestFactory = new EdmEnabledInvokeRequestFactoryImpl(this); + } + return edmEnabledInvokeRequestFactory; + } + } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ODataClientImpl.java index e968f9bb4..8b3b2e40b 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ODataClientImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v3/ODataClientImpl.java @@ -55,7 +55,7 @@ public class ODataClientImpl extends AbstractODataClient implements private static final long serialVersionUID = -1655712193243609209L; - private final Configuration configuration = new ConfigurationImpl(); + protected final Configuration configuration = new ConfigurationImpl(); private final FilterFactory filterFactory = new FilterFactoryImpl(getServiceVersion()); diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java index b852ba6b1..a9eb35227 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/EdmEnabledODataClientImpl.java @@ -19,9 +19,13 @@ package org.apache.olingo.client.core.v4; import org.apache.commons.lang3.StringUtils; +import org.apache.olingo.client.api.communication.request.invoke.EdmEnabledInvokeRequestFactory; import org.apache.olingo.client.api.communication.request.retrieve.EdmMetadataRequest; import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse; +import org.apache.olingo.client.api.uri.v4.URIBuilder; import org.apache.olingo.client.api.v4.EdmEnabledODataClient; +import org.apache.olingo.client.core.communication.request.invoke.v4.EdmEnabledInvokeRequestFactoryImpl; +import org.apache.olingo.client.core.uri.v4.URIBuilderImpl; import org.apache.olingo.commons.api.edm.Edm; public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEnabledODataClient { @@ -32,6 +36,8 @@ public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEna private String metadataETag; + private EdmEnabledInvokeRequestFactory edmEnabledInvokeRequestFactory; + public EdmEnabledODataClientImpl(final String serviceRoot) { super(); @@ -64,4 +70,17 @@ public class EdmEnabledODataClientImpl extends ODataClientImpl implements EdmEna } return this.edm; } + + @Override + public URIBuilder getURIBuilder() { + return new URIBuilderImpl(getServiceVersion(), configuration, serviceRoot); + } + + @Override + public EdmEnabledInvokeRequestFactory getInvokeRequestFactory() { + if (edmEnabledInvokeRequestFactory == null) { + edmEnabledInvokeRequestFactory = new EdmEnabledInvokeRequestFactoryImpl(this); + } + return edmEnabledInvokeRequestFactory; + } } diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java index cac3f128e..fd298a0c6 100644 --- a/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java +++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/v4/ODataClientImpl.java @@ -58,7 +58,7 @@ public class ODataClientImpl extends AbstractODataClient implements private static final long serialVersionUID = -6653176125573631964L; - private final Configuration configuration = new ConfigurationImpl(); + protected final Configuration configuration = new ConfigurationImpl(); private final FilterFactory filterFactory = new FilterFactoryImpl(getServiceVersion()); diff --git a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java index e1b212afe..5f916251b 100644 --- a/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java +++ b/lib/client-core/src/test/java/org/apache/olingo/client/core/v4/EntityTest.java @@ -359,7 +359,7 @@ public class EntityTest extends AbstractTest { } private void derived(final ODataClient client, final ODataPubFormat format) { - final InputStream input = getClass().getResourceAsStream("Customer." + getSuffix(format)); + final InputStream input = getClass().getResourceAsStream("Customer." + getSuffix(format)); final ODataEntity entity = client.getBinder().getODataEntity(client.getDeserializer().toEntity(input, format)); assertNotNull(entity);