You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/10/22 10:40:10 UTC

[27/48] olingo-odata4 git commit: [OLINGO-801] support for function-parameter aliases in tech. service

[OLINGO-801] support for function-parameter aliases in tech. service

Change-Id: I57b222418cf2760d3926da185f4dba0207311f4a

Signed-off-by: Christian Holzer <c....@sap.com>


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/85ed3707
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/85ed3707
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/85ed3707

Branch: refs/heads/olingo786
Commit: 85ed3707071810fd9ad00115821c73df9550f7ec
Parents: 587f904
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Oct 15 10:52:17 2015 +0200
Committer: Christian Holzer <c....@sap.com>
Committed: Thu Oct 15 10:56:38 2015 +0200

----------------------------------------------------------------------
 .../fit/tecsvc/client/FunctionImportITCase.java | 106 ++++++++-----
 .../olingo/server/api/uri/UriParameter.java     |  10 +-
 .../olingo/server/tecsvc/data/ActionData.java   |  20 ++-
 .../olingo/server/tecsvc/data/DataProvider.java |  85 +++++++---
 .../olingo/server/tecsvc/data/FunctionData.java | 157 +++++++------------
 .../processor/TechnicalEntityProcessor.java     |   9 +-
 .../TechnicalPrimitiveComplexProcessor.java     |   2 +-
 .../tecsvc/processor/TechnicalProcessor.java    |   7 +-
 8 files changed, 210 insertions(+), 186 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FunctionImportITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FunctionImportITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FunctionImportITCase.java
index f9dc938..d506838 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FunctionImportITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FunctionImportITCase.java
@@ -27,13 +27,9 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.io.IOUtils;
 import org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest;
-import org.apache.olingo.client.api.communication.request.retrieve.ODataPropertyRequest;
-import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
 import org.apache.olingo.client.api.communication.request.retrieve.ODataValueRequest;
 import org.apache.olingo.client.api.communication.response.ODataInvokeResponse;
-import org.apache.olingo.client.api.communication.response.ODataRawResponse;
 import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
 import org.apache.olingo.client.api.domain.ClientCollectionValue;
 import org.apache.olingo.client.api.domain.ClientComplexValue;
@@ -42,6 +38,7 @@ import org.apache.olingo.client.api.domain.ClientEntitySet;
 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.core.uri.ParameterAlias;
 import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.fit.tecsvc.TecSvcConst;
 import org.junit.Test;
@@ -166,19 +163,21 @@ public class FunctionImportITCase extends AbstractParamTecSvcITCase {
 
   @Test
   public void countEntityCollection() throws Exception {
-    final ODataRawRequest request = getClient().getRetrieveRequestFactory()
-        .getRawRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI).appendOperationCallSegment("FICRTCollESMedia")
-            .count().build());
-    final ODataRawResponse response = request.execute();
-    assertEquals("4", IOUtils.toString(response.getRawResponse()));
+    ODataValueRequest request = getClient().getRetrieveRequestFactory()
+        .getValueRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
+            .appendOperationCallSegment("FICRTCollESMedia").count().build());
+    setCookieHeader(request);
+    final ODataRetrieveResponse<ClientPrimitiveValue> response = request.execute();
+    saveCookieHeader(response);
+    assertEquals("4", response.getBody().toValue());
   }
 
   @Test
   public void complexWithPath() throws Exception {
     ODataInvokeRequest<ClientProperty> request = getClient().getInvokeRequestFactory()
-        .getFunctionInvokeRequest(
-            getClient().newURIBuilder(TecSvcConst.BASE_URI).appendOperationCallSegment("FICRTCTTwoPrim")
-                .appendPropertySegment("PropertyInt16").build(),
+        .getFunctionInvokeRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
+            .appendOperationCallSegment("FICRTCTTwoPrim")
+            .appendPropertySegment("PropertyInt16").build(),
             ClientProperty.class);
     assertNotNull(request);
     setCookieHeader(request);
@@ -241,44 +240,60 @@ public class FunctionImportITCase extends AbstractParamTecSvcITCase {
 
   @Test
   public void FICRTStringTwoParamNotNull() {
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("ParameterInt16", 3);
-    keys.put("ParameterString", "ab");
-
-    ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
-        .getPropertyRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
-            .appendPropertySegment("FICRTStringTwoParam").appendKeySegment(keys).build());
+    ODataInvokeRequest<ClientProperty> request = getClient().getInvokeRequestFactory()
+        .getFunctionInvokeRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
+            .appendOperationCallSegment("FICRTStringTwoParam").build(),
+            ClientProperty.class,
+            buildTwoParameters(3, "ab"));
     setCookieHeader(request);
-    final ODataRetrieveResponse<ClientProperty> response = request.execute();
+    final ODataInvokeResponse<ClientProperty> response = request.execute();
     saveCookieHeader(response);
     assertEquals("\"ab\",\"ab\",\"ab\"", response.getBody().getPrimitiveValue().toValue());
   }
 
   @Test
   public void FICRTStringTwoParamNull() {
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("ParameterInt16", 1);
-
-    ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
-        .getPropertyRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
-            .appendPropertySegment("FICRTStringTwoParam").appendKeySegment(keys).build());
+    ODataInvokeRequest<ClientProperty> request = getClient().getInvokeRequestFactory()
+        .getFunctionInvokeRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
+            .appendOperationCallSegment("FICRTStringTwoParam").build(),
+            ClientProperty.class,
+            Collections.<String, ClientValue> singletonMap("ParameterInt16",
+                getFactory().newPrimitiveValueBuilder().buildInt32(1)));
     setCookieHeader(request);
-    final ODataRetrieveResponse<ClientProperty> response = request.execute();
+    final ODataInvokeResponse<ClientProperty> response = request.execute();
     saveCookieHeader(response);
     assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), response.getStatusCode());
   }
 
   @Test
-  public void FICRTCollCTTwoPrimTwoParamNotNull() {
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("ParameterInt16", 2);
-    keys.put("ParameterString", "TestString");
+  public void FICRTStringTwoParamWithAliases() {
+    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
+    parameters.put("ParameterInt16", getFactory().newPrimitiveValueBuilder().setValue(
+        new ParameterAlias("first")).build());
+    parameters.put("ParameterString", getFactory().newPrimitiveValueBuilder().setValue(
+        new ParameterAlias("second")).build());
+    ODataInvokeRequest<ClientProperty> request = getClient().getInvokeRequestFactory().getFunctionInvokeRequest(
+        getClient().newURIBuilder(TecSvcConst.BASE_URI)
+            .appendOperationCallSegment("FICRTStringTwoParam")
+            .addParameterAlias("second", "'x'").addParameterAlias("first", "4")
+            .build(),
+        ClientProperty.class,
+        parameters);
+    setCookieHeader(request);
+    final ODataInvokeResponse<ClientProperty> response = request.execute();
+    saveCookieHeader(response);
+    assertEquals("\"x\",\"x\",\"x\",\"x\"", response.getBody().getPrimitiveValue().toValue());
+  }
 
-    ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
-        .getPropertyRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
-            .appendEntitySetSegment("FICRTCollCTTwoPrimTwoParam").appendKeySegment(keys).build());
+  @Test
+  public void FICRTCollCTTwoPrimTwoParamNotNull() {
+    ODataInvokeRequest<ClientProperty> request = getClient().getInvokeRequestFactory()
+        .getFunctionInvokeRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
+            .appendOperationCallSegment("FICRTCollCTTwoPrimTwoParam").build(),
+        ClientProperty.class,
+        buildTwoParameters(3, "TestString"));
     setCookieHeader(request);
-    final ODataRetrieveResponse<ClientProperty> response = request.execute();
+    final ODataInvokeResponse<ClientProperty> response = request.execute();
     saveCookieHeader(response);
     final ClientCollectionValue<ClientValue> collection = response.getBody().getCollectionValue().asCollection();
     final Iterator<ClientValue> iter = collection.iterator();
@@ -295,15 +310,13 @@ public class FunctionImportITCase extends AbstractParamTecSvcITCase {
 
   @Test
   public void FICRTCollCTTwoPrimTwoParamNull() {
-    Map<String, Object> keys = new HashMap<String, Object>();
-    keys.put("ParameterInt16", 2);
-    keys.put("ParameterString", null);
-
-    ODataPropertyRequest<ClientProperty> request = getClient().getRetrieveRequestFactory()
-        .getPropertyRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
-            .appendEntitySetSegment("FICRTCollCTTwoPrimTwoParam").appendKeySegment(keys).build());
+    ODataInvokeRequest<ClientProperty> request = getClient().getInvokeRequestFactory()
+        .getFunctionInvokeRequest(getClient().newURIBuilder(TecSvcConst.BASE_URI)
+            .appendOperationCallSegment("FICRTCollCTTwoPrimTwoParam").build(),
+        ClientProperty.class,
+        buildTwoParameters(2, null));
     setCookieHeader(request);
-    final ODataRetrieveResponse<ClientProperty> response = request.execute();
+    final ODataInvokeResponse<ClientProperty> response = request.execute();
     saveCookieHeader(response);
     final ClientCollectionValue<ClientValue> collection = response.getBody().getCollectionValue().asCollection();
     final Iterator<ClientValue> iter = collection.iterator();
@@ -317,4 +330,11 @@ public class FunctionImportITCase extends AbstractParamTecSvcITCase {
     assertEquals("UFCRTCollCTTwoPrimTwoParamstring value: null",
         complexValue.get("PropertyString").getPrimitiveValue().toValue());
   }
+
+  private Map<String, ClientValue> buildTwoParameters(final int parameterInt16, final String parameterString) {
+    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
+    parameters.put("ParameterInt16", getFactory().newPrimitiveValueBuilder().buildInt32(parameterInt16));
+    parameters.put("ParameterString", getFactory().newPrimitiveValueBuilder().buildString(parameterString));
+    return parameters;
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java
index ab8bfec..6125492 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/UriParameter.java
@@ -21,22 +21,22 @@ package org.apache.olingo.server.api.uri;
 import org.apache.olingo.server.api.uri.queryoption.expression.Expression;
 
 /**
- * Represents an function parameter or key predicate when used in the URI.
+ * Represents a function parameter or key predicate when used in the URI.
  */
 public interface UriParameter {
 
   /**
-   * @return Alias name if the parameters values is an alias, otherwise null
+   * @return Alias name if the parameter's value is an alias, otherwise null
    */
   String getAlias();
 
   /**
-   * @return Text of the parameters value
+   * @return Text of the parameter's value
    */
   String getText();
 
   /**
-   * @return If the parameters value is a expression and expression is returned, otherwise null
+   * @return Expression if the parameter's value is an expression, otherwise null
    */
   Expression getExpression();
 
@@ -46,7 +46,7 @@ public interface UriParameter {
   String getName();
 
   /**
-   * @return Name of the referenced property when referential constrains are used
+   * @return Name of the referenced property when referential constraints are used
    */
   String getReferencedProperty();
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/ActionData.java
----------------------------------------------------------------------
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 d14267d..bc90090 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
@@ -67,7 +67,8 @@ public class ActionData {
       }
       return DataCreator.createPrimitive(null, count);
     }
-    throw new DataProviderException("Action " + name + " is not yet implemented.");
+    throw new DataProviderException("Action " + name + " is not yet implemented.",
+        HttpStatusCode.NOT_IMPLEMENTED);
   }
 
   protected static Property primitiveCollectionAction(final String name, final Map<String, Parameter> parameters,
@@ -83,7 +84,7 @@ public class ActionData {
           return new Property(null, name, ValueType.COLLECTION_PRIMITIVE, Arrays.asList(
                   name + " int16 value: " + param16String,
                   name + " duration value: " + paramDurationString));
-        } catch(EdmPrimitiveTypeException e) {
+        } catch (EdmPrimitiveTypeException e) {
           throw new DataProviderException("EdmPrimitiveTypeException", e);
         }
       }
@@ -103,7 +104,8 @@ public class ActionData {
       }
       return new Property(null, name, ValueType.COLLECTION_PRIMITIVE, collectionValues);
     }
-    throw new DataProviderException("Action " + name + " is not yet implemented.");
+    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)
@@ -122,7 +124,8 @@ public class ActionData {
           (Short) paramInt16.asPrimitive();
       return createCTTwoPrimComplexProperty(name, number, "UARTCTTwoPrimParam string value");
     }
-    throw new DataProviderException("Action " + name + " is not yet implemented.");
+    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) {
@@ -148,7 +151,8 @@ public class ActionData {
       }
       return new Property(null, name, ValueType.COLLECTION_COMPLEX, complexCollection);
     }
-    throw new DataProviderException("Action " + name + " is not yet implemented.");
+    throw new DataProviderException("Action " + name + " is not yet implemented.",
+        HttpStatusCode.NOT_IMPLEMENTED);
   }
 
   protected static EntityActionResult entityAction(final String name, final Map<String, Parameter> parameters,
@@ -191,7 +195,8 @@ public class ActionData {
         return new EntityActionResult().setEntity(entityCollection.getEntities().get(0));
       }
     }
-    throw new DataProviderException("Action " + name + " is not yet implemented.");
+    throw new DataProviderException("Action " + name + " is not yet implemented.",
+        HttpStatusCode.NOT_IMPLEMENTED);
   }
 
   private static Entity createAllPrimEntity(final Short key, final String val, final Calendar date,
@@ -241,7 +246,8 @@ public class ActionData {
       }
       return collection;
     }
-    throw new DataProviderException("Action " + name + " is not yet implemented.");
+    throw new DataProviderException("Action " + name + " is not yet implemented.",
+        HttpStatusCode.NOT_IMPLEMENTED);
   }
 
   @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java
----------------------------------------------------------------------
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 a4f63f1..045360b 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
@@ -43,6 +43,7 @@ import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmFunction;
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.commons.api.edm.EdmParameter;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
@@ -56,6 +57,7 @@ import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataApplicationException;
 import org.apache.olingo.server.api.deserializer.DeserializerException;
 import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.uri.UriInfoResource;
 import org.apache.olingo.server.api.uri.UriParameter;
 import org.apache.olingo.server.api.uri.UriResourceEntitySet;
 
@@ -500,19 +502,55 @@ public class DataProvider {
     entity.setMediaETag("W/\"" + UUID.randomUUID() + "\"");
   }
 
-  public EntityCollection readFunctionEntitySet(final EdmFunction function, final List<UriParameter> parameters)
-      throws DataProviderException {
-    return FunctionData.entityCollectionFunction(function.getName(), parameters, data);
-  }
-
-  public Entity readFunctionEntity(final EdmFunction function, final List<UriParameter> parameters)
-      throws DataProviderException {
-    return FunctionData.entityFunction(function.getName(), parameters, data);
-  }
-
-  public Property readFunctionPrimitiveComplex(final EdmFunction function, final List<UriParameter> parameters)
-      throws DataProviderException {
-    return FunctionData.primitiveComplexFunction(function.getName(), parameters, data, odata);
+  public EntityCollection readFunctionEntityCollection(final EdmFunction function, final List<UriParameter> parameters,
+      final UriInfoResource uriInfo) throws DataProviderException {
+    return FunctionData.entityCollectionFunction(function.getName(),
+        getFunctionParameterValues(function, parameters, uriInfo),
+        data);
+  }
+
+  public Entity readFunctionEntity(final EdmFunction function, final List<UriParameter> parameters,
+      final UriInfoResource uriInfo) throws DataProviderException {
+    return FunctionData.entityFunction(function.getName(),
+        getFunctionParameterValues(function, parameters, uriInfo),
+        data);
+  }
+
+  public Property readFunctionPrimitiveComplex(final EdmFunction function, final List<UriParameter> parameters,
+      final UriInfoResource uriInfo) throws DataProviderException {
+    return FunctionData.primitiveComplexFunction(function.getName(),
+        getFunctionParameterValues(function, parameters, uriInfo),
+        data);
+  }
+
+  private Map<String, Object> getFunctionParameterValues(final EdmFunction function,
+      final List<UriParameter> parameters, final UriInfoResource uriInfo) throws DataProviderException {
+    Map<String, Object> values = new HashMap<String, Object>();
+    for (final UriParameter parameter : parameters) {
+      final EdmParameter edmParameter = function.getParameter(parameter.getName());
+      final String text = parameter.getAlias() == null ?
+          parameter.getText() :
+          uriInfo.getValueForAlias(parameter.getAlias());
+      if (text != null) {
+        if (edmParameter.getType().getKind() == EdmTypeKind.PRIMITIVE
+            && !edmParameter.isCollection()) {
+          final EdmPrimitiveType primitiveType = (EdmPrimitiveType) edmParameter.getType();
+          try {
+            values.put(parameter.getName(),
+                primitiveType.valueOfString(primitiveType.fromUriLiteral(text),
+                    edmParameter.isNullable(), edmParameter.getMaxLength(),
+                    edmParameter.getPrecision(), edmParameter.getScale(), null,
+                    primitiveType.getDefaultType()));
+          } catch (final EdmPrimitiveTypeException e) {
+            throw new DataProviderException("Invalid function parameter.", e);
+          }
+        } else {
+          throw new DataProviderException("Non-primitive and collection functionn parameters are not yet supported.",
+              HttpStatusCode.NOT_IMPLEMENTED);
+        }
+      }
+    }
+    return values;
   }
 
   public Property processActionPrimitive(final String name, final Map<String, Parameter> actionParameters)
@@ -544,33 +582,34 @@ public class DataProvider {
       final Map<String, Parameter> actionParameters) throws DataProviderException {
     return ActionData.entityCollectionAction(name, actionParameters, odata, edm);
   }
-  
+
   public void createReference(final Entity entity, final EdmNavigationProperty navigationProperty, final URI entityId, 
       final String rawServiceRoot) throws DataProviderException {
         setLink(navigationProperty, entity, getEntityByReference(entityId.toASCIIString(), rawServiceRoot));
   }
-  
+
   public void deleteReference(final Entity entity, final EdmNavigationProperty navigationProperty, 
       final String entityId, final String rawServiceRoot) throws DataProviderException {
 
-    if(navigationProperty.isCollection()) {
+    if (navigationProperty.isCollection()) {
       final Entity targetEntity = getEntityByReference(entityId, rawServiceRoot);
       final Link navigationLink = entity.getNavigationLink(navigationProperty.getName());
       
-      if(navigationLink != null && navigationLink.getInlineEntitySet() != null 
+      if (navigationLink != null && navigationLink.getInlineEntitySet() != null 
           && navigationLink.getInlineEntitySet().getEntities().contains(targetEntity)) {
         
         // Remove partner single-valued navigation property
-        if(navigationProperty.getPartner() != null) {
+        if (navigationProperty.getPartner() != null) {
           final EdmNavigationProperty edmPartnerNavigationProperty = navigationProperty.getPartner();
-          if(!edmPartnerNavigationProperty.isCollection() && !edmPartnerNavigationProperty.isNullable()) {
+          if (!edmPartnerNavigationProperty.isCollection() && !edmPartnerNavigationProperty.isNullable()) {
             throw new DataProviderException("Navigation property must not be null", HttpStatusCode.BAD_REQUEST);
-          } else if(!edmPartnerNavigationProperty.isCollection()) {
+          } else if (!edmPartnerNavigationProperty.isCollection()) {
             removeLink(edmPartnerNavigationProperty, targetEntity);
-          } else if(edmPartnerNavigationProperty.isCollection() && edmPartnerNavigationProperty.getPartner() != null) {
+          } else if (edmPartnerNavigationProperty.isCollection()
+              && edmPartnerNavigationProperty.getPartner() != null) {
             // Bidirectional referential constraint
             final Link partnerNavigationLink = targetEntity.getNavigationLink(edmPartnerNavigationProperty.getName());
-            if(partnerNavigationLink != null && partnerNavigationLink.getInlineEntitySet() != null) {
+            if (partnerNavigationLink != null && partnerNavigationLink.getInlineEntitySet() != null) {
               partnerNavigationLink.getInlineEntitySet().getEntities().remove(entity);
             }
           }
@@ -582,7 +621,7 @@ public class DataProvider {
         throw new DataProviderException("Entity not found", HttpStatusCode.NOT_FOUND);
       }
     } else {
-      if(navigationProperty.isNullable()) {
+      if (navigationProperty.isNullable()) {
         removeLink(navigationProperty, entity);
       } else {
         throw new DataProviderException("Navigation property must not be null", HttpStatusCode.BAD_REQUEST);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/FunctionData.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/FunctionData.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/FunctionData.java
index 4037297..d9d0ff1 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/FunctionData.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/FunctionData.java
@@ -28,21 +28,18 @@ import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntityCollection;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ValueType;
-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.server.api.OData;
-import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.server.tecsvc.data.DataProvider.DataProviderException;
 
 public class FunctionData {
 
-  protected static EntityCollection entityCollectionFunction(final String name, final List<UriParameter> parameters,
-      final Map<String, EntityCollection> data) throws DataProviderException {
+  protected static EntityCollection entityCollectionFunction(final String name,
+      final Map<String, Object> parameterValues, final Map<String, EntityCollection> data)
+      throws DataProviderException {
     if (name.equals("UFCRTCollETTwoKeyNavParam")) {
       final List<Entity> esTwoKeyNav = data.get("ESTwoKeyNav").getEntities();
       EntityCollection result = new EntityCollection();
-      final int endIndex = parameters.isEmpty() ? 0 : Short.valueOf(parameters.get(0).getText());
+      final int endIndex = parameterValues.isEmpty() ? 0 : getParameterInt16(parameterValues);
       result.getEntities().addAll(
           esTwoKeyNav.subList(0,
               endIndex < 0 ? 0 : endIndex > esTwoKeyNav.size() ? esTwoKeyNav.size() : endIndex));
@@ -52,11 +49,12 @@ public class FunctionData {
     } else if (name.equals("UFCRTCollETMedia")) {
       return data.get("ESMedia");
     } else {
-      throw new DataProviderException("Function " + name + " is not yet implemented.");
+      throw new DataProviderException("Function " + name + " is not yet implemented.",
+          HttpStatusCode.NOT_IMPLEMENTED);
     }
   }
 
-  protected static Entity entityFunction(final String name, final List<UriParameter> parameters,
+  protected static Entity entityFunction(final String name, final Map<String, Object> parameterValues,
       final Map<String, EntityCollection> data) throws DataProviderException {
     final List<Entity> esTwoKeyNav = data.get("ESTwoKeyNav").getEntities();
     if (name.equals("UFCRTETKeyNav")) {
@@ -64,20 +62,21 @@ public class FunctionData {
     } else if (name.equals("UFCRTETTwoKeyNav")) {
       return esTwoKeyNav.get(0);
     } else if (name.equals("UFCRTETTwoKeyNavParam")) {
-      final int index = parameters.isEmpty() ? 0 : Short.valueOf(parameters.get(0).getText());
+      final int index = parameterValues.isEmpty() ? 0 : getParameterInt16(parameterValues);
       return index < 0 || index >= esTwoKeyNav.size() ? null : esTwoKeyNav.get(index);
     } else if (name.equals("UFCRTETMedia")) {
-      final int index = parameters.isEmpty() ? 1 : Short.valueOf(parameters.get(0).getText());
+      final int index = parameterValues.isEmpty() ? 1 : getParameterInt16(parameterValues);
       final List<Entity> esMedia = data.get("ESMedia").getEntities();
       return index < 1 || index > esMedia.size() ? null : esMedia.get(index - 1);
     } else {
-      throw new DataProviderException("Function " + name + " is not yet implemented.");
+      throw new DataProviderException("Function " + name + " is not yet implemented.",
+          HttpStatusCode.NOT_IMPLEMENTED);
     }
   }
 
   @SuppressWarnings("unchecked")
-  protected static Property primitiveComplexFunction(final String name, final List<UriParameter> parameters,
-      final Map<String, EntityCollection> data, final OData oData) throws DataProviderException {
+  protected static Property primitiveComplexFunction(final String name, final Map<String, Object> parameterValues,
+      final Map<String, EntityCollection> data) throws DataProviderException {
     if (name.equals("UFNRTInt16")) {
       return DataCreator.createPrimitive(name, (short) 12345);
     } else if (name.equals("UFCRTString")) {
@@ -89,19 +88,9 @@ public class FunctionData {
           DataCreator.createPrimitive("PropertyInt16", (short) 16),
           DataCreator.createPrimitive("PropertyString", "UFCRTCTTwoPrim string value"));
     } else if (name.equals("UFCRTCTTwoPrimParam")) {
-      try {
-        return DataCreator.createComplex(name,
-            DataCreator.createPrimitive("PropertyInt16", oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16)
-                .valueOfString(getParameterText("ParameterInt16", parameters),
-                    null, null, null, null, null, Short.class)),
-            DataCreator.createPrimitive("PropertyString",
-                oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String)
-                    .valueOfString(oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String)
-                        .fromUriLiteral(getParameterText("ParameterString", parameters)),
-                        null, null, null, null, null, String.class)));
-      } catch (final EdmPrimitiveTypeException e) {
-        throw new DataProviderException("Error in function " + name + ".", e);
-      }
+      return DataCreator.createComplex(name,
+          DataCreator.createPrimitive("PropertyInt16", getParameterInt16(parameterValues)),
+          DataCreator.createPrimitive("PropertyString", getParameterString(parameterValues)));
     } else if (name.equals("UFCRTCollCTTwoPrim")) {
       return DataCreator.createComplexCollection(name,
           Arrays.asList(DataCreator.createPrimitive("PropertyInt16", (short) 16),
@@ -110,89 +99,57 @@ public class FunctionData {
               DataCreator.createPrimitive("PropertyString", "Test456")),
           Arrays.asList(DataCreator.createPrimitive("PropertyInt16", 18),
               DataCreator.createPrimitive("PropertyString", "Test678")));
-    } else if(name.equals("UFCRTStringTwoParam")) {
-      final String parameterStringRaw = getParameterText("ParameterString", parameters);
-      final String parameterInt16Raw = getParameterText("ParameterInt16", parameters);
-      
+    } else if (name.equals("UFCRTStringTwoParam")) {
+      final String parameterString = getParameterString(parameterValues);
       // ParameterString is not provided
-      if (parameterStringRaw == null) {
-        return new Property(null, "value", ValueType.PRIMITIVE, null);
+      if (parameterString == null) {
+        return DataCreator.createPrimitive(name, null);
       } else {
-        try {
-          final EdmPrimitiveType edmInt16 = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16);
-          final EdmPrimitiveType edmString = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String);
-          final Short parameterInt16 =  edmInt16.valueOfString(parameterInt16Raw, null, null, null, null, null,
-              Short.class);
-          final String parameterString = edmString.fromUriLiteral(parameterStringRaw);
-          final StringBuilder builder = new StringBuilder();
-          // if parameterInt16 <= 0 return an empty string
-          for (short i = parameterInt16; i > 0; i--) {
-            if (builder.length() != 0) {
-              builder.append(',');
-            }
-            builder.append('"');
-            builder.append(parameterString);
-            builder.append('"');
+        final Short parameterInt16 = getParameterInt16(parameterValues);
+        final StringBuilder builder = new StringBuilder();
+        // if parameterInt16 <= 0 return an empty string
+        for (short i = parameterInt16; i > 0; i--) {
+          if (builder.length() != 0) {
+            builder.append(',');
           }
-          return new Property(null, "value", ValueType.PRIMITIVE, builder.toString());
-        } catch (final EdmPrimitiveTypeException e) {
-          throw new DataProviderException("Invalid function parameter.");
+          builder.append('"')
+              .append(parameterString)
+              .append('"');
         }
+        return DataCreator.createPrimitive(name, builder.toString());
       }
     } else if (name.equals("UFCRTCollCTTwoPrimTwoParam")) {
-      String parameterStringRaw = getParameterText("ParameterString", parameters);
-      String parameteInt16Raw = getParameterText("ParameterInt16", parameters);
-      EdmPrimitiveType edmInt16 = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Int16);
-      EdmPrimitiveType edmString = oData.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.String);
-      try {
-        Short parameterInt16 = edmInt16.valueOfString(parameteInt16Raw, null, null, null, null, null, Short.class);
-
-        if (parameterStringRaw == null) {
-          ComplexValue complexValue1 = new ComplexValue();
-          ComplexValue complexValue2 = new ComplexValue();
-          
-          complexValue1.getValue().add(new Property(null, "PropertyInt16", ValueType.PRIMITIVE, 1));
-          complexValue1.getValue().add(new Property(null, "PropertyString", ValueType.PRIMITIVE, 
-              name + " int16 value: " + parameterInt16));
-          
-          complexValue2.getValue().add(new Property(null, "PropertyInt16", ValueType.PRIMITIVE, 2));
-          complexValue2.getValue().add(new Property(null, "PropertyString", ValueType.PRIMITIVE,
-              name + "string value: null"));
-          
-          
-          return new Property(null, "value", ValueType.COLLECTION_COMPLEX, Arrays.asList(new ComplexValue[] {
-              complexValue1, complexValue2
-          }));
-        } else {
-          String parameterString = edmString.fromUriLiteral(parameterStringRaw);
-          List<ComplexValue> complexValues = new ArrayList<ComplexValue>();
-          short counter = 1;
-          
-          for(short i = parameterInt16; 0 < i; i--) {
-            ComplexValue complexValue = new ComplexValue();
-            complexValue.getValue().add(new Property(null, "PropertyInt16", ValueType.PRIMITIVE, counter++));
-            complexValue.getValue().add(new Property(null, "PropertyString", ValueType.PRIMITIVE, 
-                name + " string value: " + parameterString));
-            complexValues.add(complexValue);
-          }
-          
-          return new Property(null, "value", ValueType.COLLECTION_COMPLEX, complexValues);
+      final Short parameterInt16 = getParameterInt16(parameterValues);
+      final String parameterString = getParameterString(parameterValues);
+      if (parameterString == null) {
+        return DataCreator.createComplexCollection(name,
+            Arrays.asList(DataCreator.createPrimitive("PropertyInt16", 1),
+                DataCreator.createPrimitive("PropertyString", name + " int16 value: " + parameterInt16)),
+            Arrays.asList(DataCreator.createPrimitive("PropertyInt16", 2),
+                DataCreator.createPrimitive("PropertyString", name + "string value: null")));
+      } else {
+        List<ComplexValue> complexValues = new ArrayList<ComplexValue>();
+        short counter = 1;
+        for (short i = parameterInt16; 0 < i; i--) {
+          ComplexValue complexValue = new ComplexValue();
+          complexValue.getValue().add(new Property(null, "PropertyInt16", ValueType.PRIMITIVE, counter++));
+          complexValue.getValue().add(new Property(null, "PropertyString", ValueType.PRIMITIVE, 
+              name + " string value: " + parameterString));
+          complexValues.add(complexValue);
         }
-      } catch (EdmPrimitiveTypeException e) {
-        throw new DataProviderException("Invalid function parameter");
+        return new Property(null, name, ValueType.COLLECTION_COMPLEX, complexValues);
       }
-      
     } else {
-      throw new DataProviderException("Function " + name + " is not yet implemented.");
+      throw new DataProviderException("Function " + name + " is not yet implemented.",
+          HttpStatusCode.NOT_IMPLEMENTED);
     }
   }
 
-  private static String getParameterText(final String name, final List<UriParameter> parameters) {
-    for (final UriParameter parameter : parameters) {
-      if (parameter.getName().equals(name)) {
-        return parameter.getText();
-      }
-    }
-    return null;
+  private static Short getParameterInt16(final Map<String, Object> parameterValues) {
+    return (Short) parameterValues.get("ParameterInt16");
+  }
+
+  private static String getParameterString(final Map<String, Object> parameterValues) {
+    return (String) parameterValues.get("ParameterString");
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index b9afddd..95bcdc7 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -498,17 +498,18 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
     final SelectOption select = uriInfo.getSelectOption();
 
     // Transform the entity graph to a tree. The construction is controlled by the expand tree.
-    // Apply all expand system query options to the tree.So the expanded navigation properties can be modified
-    // for serialization,without affecting the data stored in the database.
+    // Apply all expand system query options to the tree.
+    // So the expanded navigation properties can be modified for serialization,
+    // without affecting the data stored in the database.
     final ExpandSystemQueryOptionHandler expandHandler = new ExpandSystemQueryOptionHandler();
     final EntityCollection entitySetSerialization = expandHandler.transformEntitySetGraphToTree(entitySet,
         edmEntitySet,
         expand);
     expandHandler.applyExpandQueryOptions(entitySetSerialization, edmEntitySet, expand);
     final CountOption countOption = uriInfo.getCountOption();
-    
+
     String id;
-    if(edmEntitySet == null) {
+    if (edmEntitySet == null) {
       // Used for functions, function imports etc.
       id = request.getRawODataPath();
     } else {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
index e6a8e90..5928c30 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
@@ -223,7 +223,7 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
     final Property property = entity == null ?
         getPropertyData(
             dataProvider.readFunctionPrimitiveComplex(((UriResourceFunction) resourceParts.get(0)).getFunction(),
-            ((UriResourceFunction) resourceParts.get(0)).getParameters()), path) :
+            ((UriResourceFunction) resourceParts.get(0)).getParameters(), resource), path) :
         getPropertyData(entity, path);
 
     if (property == null && representationType != RepresentationType.COUNT) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/85ed3707/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
index f61f30a..b63bdd8 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalProcessor.java
@@ -139,11 +139,11 @@ public abstract class TechnicalProcessor implements Processor {
           if (uriResource.isCollection()) { // handled in readEntityCollection()
             return null;
           } else {
-            entity = dataProvider.readFunctionEntity(function, uriResource.getParameters());
+            entity = dataProvider.readFunctionEntity(function, uriResource.getParameters(), uriInfo);
           }
         } else {
           entity = dataProvider.read((EdmEntityType) function.getReturnType().getType(),
-              dataProvider.readFunctionEntitySet(function, uriResource.getParameters()),
+              dataProvider.readFunctionEntityCollection(function, uriResource.getParameters(), uriInfo),
               key);
         }
       } else {
@@ -197,7 +197,8 @@ public abstract class TechnicalProcessor implements Processor {
     } else {
       if (resourcePaths.get(0) instanceof UriResourceFunction) {
         final UriResourceFunction uriResource = (UriResourceFunction) resourcePaths.get(0);
-        return dataProvider.readFunctionEntitySet(uriResource.getFunction(), uriResource.getParameters());
+        return dataProvider.readFunctionEntityCollection(uriResource.getFunction(), uriResource.getParameters(),
+            uriInfo);
       } else {
         return dataProvider.readAll(((UriResourceEntitySet) resourcePaths.get(0)).getEntitySet());
       }