Repository: olingo-odata4
Updated Branches:
  refs/heads/master a298e1fb7 -> e5fe04aee


[OLINGO-698] technical service supports preferences, part 1

Signed-off-by: Christian Amend <[email protected]>


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

Branch: refs/heads/master
Commit: e5fe04aeeb1efb22404eec493fc341bf4cd0f251
Parents: a298e1f
Author: Klaus Straubinger <[email protected]>
Authored: Tue Jun 16 16:47:39 2015 +0200
Committer: Christian Amend <[email protected]>
Committed: Tue Jun 16 16:50:15 2015 +0200

----------------------------------------------------------------------
 .../fit/tecsvc/client/ActionImportITCase.java   | 197 ++++++++++---------
 .../olingo/fit/tecsvc/client/BasicITCase.java   | 127 ++++++------
 .../tecsvc/client/PrimitiveComplexITCase.java   |  16 ++
 .../tecsvc/client/SystemQueryOptionITCase.java  |  23 ++-
 .../olingo/commons/api/http/HttpHeader.java     |  15 +-
 .../processor/TechnicalActionProcessor.java     | 180 +++++++++++------
 .../processor/TechnicalEntityProcessor.java     |  69 +++++--
 .../TechnicalPrimitiveComplexProcessor.java     |  29 ++-
 .../options/ServerSidePagingHandler.java        | 115 ++++++-----
 9 files changed, 479 insertions(+), 292 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java 
b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java
index 0c40003..0e68a4a 100644
--- 
a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java
+++ 
b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/ActionImportITCase.java
@@ -25,6 +25,7 @@ import static org.junit.Assert.fail;
 import java.math.BigDecimal;
 import java.net.URI;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -32,6 +33,8 @@ import java.util.TimeZone;
 
 import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import 
org.apache.olingo.client.api.communication.request.invoke.ODataInvokeRequest;
 import org.apache.olingo.client.api.communication.response.ODataInvokeResponse;
 import org.apache.olingo.client.api.domain.ClientCollectionValue;
 import org.apache.olingo.client.api.domain.ClientComplexValue;
@@ -42,6 +45,7 @@ import org.apache.olingo.client.api.domain.ClientValue;
 import org.apache.olingo.client.core.ODataClientFactory;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.format.ODataFormat;
+import org.apache.olingo.commons.api.http.HttpStatusCode;
 import org.apache.olingo.fit.AbstractBaseTestITCase;
 import org.apache.olingo.fit.tecsvc.TecSvcConst;
 import org.junit.Test;
@@ -50,50 +54,62 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void noReturnTypeAction() throws Exception {
-      URI actionURI =
-          
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRT").build();
-      ODataInvokeResponse<ClientProperty> response =
-          
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class).execute();
-      assertEquals(204, response.getStatusCode());
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRT").build();
+    ODataInvokeResponse<ClientProperty> response =
+        
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class).execute();
+    assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), 
response.getStatusCode());
   }
-  
+
   @Test
-  public void primitveAction() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTString").build();
+  public void primitiveAction() throws Exception {
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTString").build();
     ODataInvokeResponse<ClientProperty> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class).execute();
-    assertEquals(200, response.getStatusCode());
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     assertEquals("UARTString string value", 
response.getBody().getPrimitiveValue().toValue());
   }
 
   @Test
-  public void primitveActionInvalidParameters() throws Exception {
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters.put("Invalid", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(1));
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTString").build();
+  public void primitiveActionMinimalResponse() throws Exception {
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTString").build();
+    ODataInvokeRequest<ClientProperty> request = 
getClient().getInvokeRequestFactory()
+        .getActionInvokeRequest(actionURI, ClientProperty.class);
+    request.setPrefer(getClient().newPreferences().returnMinimal());
+    final ODataInvokeResponse<ClientProperty> response = request.execute();
+    assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), 
response.getStatusCode());
+    assertEquals("return=\"minimal\"", 
response.getHeader(HeaderName.preferenceApplied).iterator().next());
+  }
+
+  @Test
+  public void primitiveActionInvalidParameters() throws Exception {
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTString").build();
+    Map<String, ClientValue> parameters = Collections.singletonMap("Invalid",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt32(1));
     try {
       getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class, parameters)
-      .execute();
+          .execute();
       fail("Expected an ODataClientErrorException");
     } catch (ODataClientErrorException e) {
-      assertEquals(400, e.getStatusLine().getStatusCode());
+      assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), 
e.getStatusLine().getStatusCode());
     }
   }
 
   @Test
-  public void primitveCollectionAction() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollStringTwoParam").build();
+  public void primitiveCollectionAction() throws Exception {
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollStringTwoParam").build();
     Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
     parameters.put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
3));
-    parameters.put("ParameterDuration", 
getClient().getObjectFactory().newPrimitiveValueBuilder().setType(
-        EdmPrimitiveTypeKind.Duration).setValue(new BigDecimal(1)).build());
+    parameters.put("ParameterDuration", 
getClient().getObjectFactory().newPrimitiveValueBuilder()
+        .setType(EdmPrimitiveTypeKind.Duration).setValue(new 
BigDecimal(1)).build());
     ODataInvokeResponse<ClientProperty> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientCollectionValue<ClientValue> valueArray = 
response.getBody().getCollectionValue();
     assertEquals(3, valueArray.size());
     Iterator<ClientValue> iterator = valueArray.iterator();
@@ -104,14 +120,14 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void complexAction() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCTTwoPrimParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters.put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
3));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCTTwoPrimParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
3));
     ODataInvokeResponse<ClientProperty> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientComplexValue complexValue = response.getBody().getComplexValue();
     ClientProperty propInt16 = complexValue.get("PropertyInt16");
     assertNotNull(propInt16);
@@ -123,28 +139,28 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void complexCollectionActionNoContent() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters.put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
0));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
0));
     ODataInvokeResponse<ClientProperty> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientCollectionValue<ClientValue> complexValueCollection = 
response.getBody().getCollectionValue();
     assertEquals(0, complexValueCollection.size());
   }
 
   @Test
   public void complexCollectionActionSubContent() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters.put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
1));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
1));
     ODataInvokeResponse<ClientProperty> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientCollectionValue<ClientValue> complexValueCollection = 
response.getBody().getCollectionValue();
     assertEquals(1, complexValueCollection.size());
     Iterator<ClientValue> iterator = complexValueCollection.iterator();
@@ -156,14 +172,14 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void complexCollectionActionAllContent() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters.put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
3));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollCTTwoPrimParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
3));
     ODataInvokeResponse<ClientProperty> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientProperty.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientCollectionValue<ClientValue> complexValueCollection = 
response.getBody().getCollectionValue();
     assertEquals(3, complexValueCollection.size());
     Iterator<ClientValue> iterator = complexValueCollection.iterator();
@@ -183,15 +199,14 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void entityActionETTwoKeyTwoPrim() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTETTwoKeyTwoPrimParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters
-    .put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
-365));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTETTwoKeyTwoPrimParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
-365));
     ODataInvokeResponse<ClientEntity> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientEntity.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientEntity entity = response.getBody();
     ClientProperty propInt16 = entity.getProperty("PropertyInt16");
     assertNotNull(propInt16);
@@ -203,15 +218,14 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void entityCollectionActionETKeyNav() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters
-    .put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
3));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollETKeyNavParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
3));
     ODataInvokeResponse<ClientEntitySet> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientEntitySet.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientEntitySet entitySet = response.getBody();
     assertEquals(3, entitySet.getEntities().size());
     Integer key = 1;
@@ -223,51 +237,49 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void entityCollectionActionETKeyNavEmptyCollection() throws Exception 
{
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters
-    .put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
0));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollETKeyNavParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
0));
     ODataInvokeResponse<ClientEntitySet> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientEntitySet.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientEntitySet entitySet = response.getBody();
     assertEquals(0, entitySet.getEntities().size());
   }
 
   @Test
   public void entityCollectionActionETKeyNavNegativeParam() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollETKeyNavParam").build();
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters
-    .put("ParameterInt16", 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
-10));
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollETKeyNavParam").build();
+    Map<String, ClientValue> parameters = 
Collections.singletonMap("ParameterInt16",
+        (ClientValue) 
getClient().getObjectFactory().newPrimitiveValueBuilder().buildInt16((short) 
-10));
     ODataInvokeResponse<ClientEntitySet> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientEntitySet.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientEntitySet entitySet = response.getBody();
     assertEquals(0, entitySet.getEntities().size());
   }
 
   @Test
   public void entityCollectionActionETAllPrim() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTCollESAllPrimParam").build();
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTCollESAllPrimParam").build();
     Calendar time = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
     time.clear();
     time.set(Calendar.HOUR_OF_DAY, 3);
     time.set(Calendar.MINUTE, 0);
     time.set(Calendar.SECOND, 0);
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters
-    .put("ParameterTimeOfDay", 
getClient().getObjectFactory().newPrimitiveValueBuilder().setType(
-        EdmPrimitiveTypeKind.TimeOfDay).setValue(time).build());
+    Map<String, ClientValue> parameters = Collections.singletonMap(
+        "ParameterTimeOfDay",
+        (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder()
+            .setType(EdmPrimitiveTypeKind.TimeOfDay).setValue(time).build());
     ODataInvokeResponse<ClientEntitySet> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientEntitySet.class, parameters)
-        .execute();
-    assertEquals(200, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
     ClientEntitySet entitySet = response.getBody();
     assertEquals(3, entitySet.getEntities().size());
     Integer key = 1;
@@ -279,20 +291,19 @@ public class ActionImportITCase extends 
AbstractBaseTestITCase {
 
   @Test
   public void entityActionETAllPrim() throws Exception {
-    URI actionURI =
-        
getClient().newURIBuilder(TecSvcConst.BASE_URI).appendActionCallSegment("AIRTESAllPrimParam").build();
+    final URI actionURI = getClient().newURIBuilder(TecSvcConst.BASE_URI)
+        .appendActionCallSegment("AIRTESAllPrimParam").build();
     Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
     dateTime.clear();
     dateTime.set(1012, 2, 0, 0, 0, 0);
-    Map<String, ClientValue> parameters = new HashMap<String, ClientValue>();
-    parameters
-    .put("ParameterDate", 
getClient().getObjectFactory().newPrimitiveValueBuilder().setType(
-        EdmPrimitiveTypeKind.Date).setValue(dateTime).build());
+    Map<String, ClientValue> parameters = Collections.singletonMap(
+        "ParameterDate",
+        (ClientValue) getClient().getObjectFactory().newPrimitiveValueBuilder()
+            .setType(EdmPrimitiveTypeKind.Date).setValue(dateTime).build());
     ODataInvokeResponse<ClientEntity> response =
         
getClient().getInvokeRequestFactory().getActionInvokeRequest(actionURI, 
ClientEntity.class, parameters)
-        .execute();
-    // Check 201
-    assertEquals(201, response.getStatusCode());
+            .execute();
+    assertEquals(HttpStatusCode.CREATED.getStatusCode(), 
response.getStatusCode());
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java 
b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
index 819aab7..0f3a099 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
@@ -37,6 +37,7 @@ import java.util.List;
 import org.apache.olingo.client.api.EdmEnabledODataClient;
 import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.header.HeaderName;
 import 
org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
 import 
org.apache.olingo.client.api.communication.request.cud.ODataEntityCreateRequest;
 import 
org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
@@ -401,6 +402,24 @@ public class BasicITCase extends AbstractBaseTestITCase {
   }
 
   @Test
+  public void createEntityMinimalResponse() throws Exception {
+    final ODataClient client = getClient();
+    final ClientObjectFactory factory = client.getObjectFactory();
+    ClientEntity newEntity = factory.newEntity(new 
FullQualifiedName("olingo.odata.test1", "ETTwoPrim"));
+    
newEntity.getProperties().add(factory.newPrimitiveProperty("PropertyString",
+        factory.newPrimitiveValueBuilder().buildString("new")));
+    ODataEntityCreateRequest<ClientEntity> request = 
client.getCUDRequestFactory().getEntityCreateRequest(
+        
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoPrim").build(),
+        newEntity);
+    request.setPrefer(getClient().newPreferences().returnMinimal());
+
+    final ODataEntityCreateResponse<ClientEntity> response = request.execute();
+    assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), 
response.getStatusCode());
+    assertEquals("return=\"minimal\"", 
response.getHeader(HeaderName.preferenceApplied).iterator().next());
+    assertEquals(SERVICE_URI + "/ESTwoPrim(1)", 
response.getHeader(HttpHeader.LOCATION).iterator().next());
+  }
+
+  @Test
   public void readEntityWithExpandedNavigationProperty() {
     final ODataClient client = 
ODataClientFactory.getEdmEnabledClient(SERVICE_URI);
     client.getConfiguration().setDefaultPubFormat(ODataFormat.JSON);
@@ -459,30 +478,20 @@ public class BasicITCase extends AbstractBaseTestITCase {
     entity.getProperties().add(
         of.newCollectionProperty("CollPropertyComp",
             of.newCollectionValue("CTPrimComp")
-            .add(
-                of.newComplexValue("CTPrimComp")
-                .add(
-                            of.newPrimitiveProperty("PropertyInt16", 
of.newPrimitiveValueBuilder()
-                                .buildInt16(
-                                    (short) 42)))
-                            .add(
-                            of.newComplexProperty("PropertyComp", 
of.newComplexValue("CTAllPrim")
-                                .add(
-                                    of.newPrimitiveProperty("PropertyString", 
of
-                                        .newPrimitiveValueBuilder()
-                                        .buildString("42"))))))
-                                            .add(
-                                                
of.newComplexValue("CTPrimComp")
-                                                .add(
-                            of.newPrimitiveProperty("PropertyInt16", 
of.newPrimitiveValueBuilder()
-                                .buildInt16(
-                                    (short) 43)))
-                                                            .add(
-                            of.newComplexProperty("PropertyComp", 
of.newComplexValue("CTAllPrim")
-                                .add(
-                                    of.newPrimitiveProperty("PropertyString", 
of
-                                        .newPrimitiveValueBuilder()
-                                        .buildString("43"))))))));
+                .add(of.newComplexValue("CTPrimComp")
+                    .add(of.newPrimitiveProperty("PropertyInt16",
+                        of.newPrimitiveValueBuilder().buildInt16((short) 42)))
+                    .add(of.newComplexProperty("PropertyComp",
+                        of.newComplexValue("CTAllPrim")
+                            .add(of.newPrimitiveProperty("PropertyString",
+                                
of.newPrimitiveValueBuilder().buildString("42"))))))
+                .add(of.newComplexValue("CTPrimComp")
+                    .add(of.newPrimitiveProperty("PropertyInt16",
+                        of.newPrimitiveValueBuilder().buildInt16((short) 43)))
+                    .add(of.newComplexProperty("PropertyComp",
+                        of.newComplexValue("CTAllPrim")
+                            .add(of.newPrimitiveProperty("PropertyString",
+                                
of.newPrimitiveValueBuilder().buildString("43"))))))));
 
     final URI uri = getClient().newURIBuilder(SERVICE_URI)
         .appendEntitySetSegment("ESKeyNav")
@@ -681,13 +690,15 @@ public class BasicITCase extends AbstractBaseTestITCase {
     entity.getProperties().add(of.newPrimitiveProperty("PropertyString", 
of.newPrimitiveValueBuilder()
         .buildString(null)));
 
-    final ODataEntityUpdateResponse<ClientEntity> updateResponse = 
client.getCUDRequestFactory()
-        .getEntityUpdateRequest(targetURI, UpdateType.PATCH, entity)
-        .execute();
+    ODataEntityUpdateRequest<ClientEntity> request = 
client.getCUDRequestFactory()
+        .getEntityUpdateRequest(targetURI, UpdateType.PATCH, entity);
+    request.setPrefer(getClient().newPreferences().returnRepresentation());
+    final ODataEntityUpdateResponse<ClientEntity> response = request.execute();
 
-    assertEquals(HttpStatusCode.OK.getStatusCode(), 
updateResponse.getStatusCode());
-    
assertTrue(updateResponse.getBody().getProperty("PropertyString").hasNullValue());
-    assertEquals(34, 
updateResponse.getBody().getProperty("PropertyDecimal").getPrimitiveValue().toValue());
+    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
+    assertEquals("return=\"representation\"", 
response.getHeader(HeaderName.preferenceApplied).iterator().next());
+    
assertTrue(response.getBody().getProperty("PropertyString").hasNullValue());
+    assertEquals(34, 
response.getBody().getProperty("PropertyDecimal").getPrimitiveValue().toValue());
   }
 
   @Test(expected = ODataClientErrorException.class)
@@ -743,23 +754,23 @@ public class BasicITCase extends AbstractBaseTestITCase {
                 .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany")
                 .build());
     entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
-    final ODataRetrieveResponse<ClientEntity> entitytResponse = 
entityRequest.execute();
+    final ODataRetrieveResponse<ClientEntity> entityResponse = 
entityRequest.execute();
 
-    assertEquals(HttpStatusCode.OK.getStatusCode(), 
entitytResponse.getStatusCode());
-    assertEquals(1, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne")
+    assertEquals(HttpStatusCode.OK.getStatusCode(), 
entityResponse.getStatusCode());
+    assertEquals(1, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne")
         .asInlineEntity()
         .getEntity()
         .getProperty("PropertyInt16")
         .getPrimitiveValue()
         .toValue());
 
-    assertEquals(3, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(3, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
         .size());
 
-    assertEquals(1, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(1, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
@@ -768,7 +779,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
         .getPrimitiveValue()
         .toValue());
 
-    assertEquals(2, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(2, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
@@ -777,7 +788,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
         .getPrimitiveValue()
         .toValue());
 
-    assertEquals(3, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(3, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
@@ -786,7 +797,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
         .getPrimitiveValue()
         .toValue());
 
-    final Iterator<ClientValue> collectionIterator = entitytResponse.getBody()
+    final Iterator<ClientValue> collectionIterator = entityResponse.getBody()
         .getProperty("CollPropertyString")
         .getCollectionValue()
         .iterator();
@@ -794,7 +805,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
     assertEquals("Single entry!", 
collectionIterator.next().asPrimitive().toValue());
     assertFalse(collectionIterator.hasNext());
 
-    final ClientComplexValue complexValue = entitytResponse.getBody()
+    final ClientComplexValue complexValue = entityResponse.getBody()
         .getProperty("PropertyCompAllPrim")
         .getComplexValue();
 
@@ -825,14 +836,14 @@ public class BasicITCase extends AbstractBaseTestITCase {
         .add(of.newPrimitiveValueBuilder().buildString("Single entry!"))));
     entity.getProperties().add(of.newComplexProperty("PropertyCompAllPrim",
         of.newComplexValue("CTAllPrim")
-        .add(of.newPrimitiveProperty("PropertyString",
-                of.newPrimitiveValueBuilder().buildString("Changed")))));
+        .add(of.newPrimitiveProperty("PropertyString", 
of.newPrimitiveValueBuilder().buildString("Changed")))));
 
-    final ODataEntityUpdateResponse<ClientEntity> response = 
client.getCUDRequestFactory()
-        .getEntityUpdateRequest(targetURI, UpdateType.REPLACE, entity)
-        .execute();
-
-    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
+    ODataEntityUpdateRequest<ClientEntity> request = 
client.getCUDRequestFactory()
+        .getEntityUpdateRequest(targetURI, UpdateType.REPLACE, entity);
+    request.setPrefer(getClient().newPreferences().returnMinimal());
+    final ODataEntityUpdateResponse<ClientEntity> response = request.execute();
+    assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), 
response.getStatusCode());
+    assertEquals("return=\"minimal\"", 
response.getHeader(HeaderName.preferenceApplied).iterator().next());
     final String cookie = 
response.getHeader(HttpHeader.SET_COOKIE).iterator().next();
 
     final ODataEntityRequest<ClientEntity> entityRequest = 
client.getRetrieveRequestFactory()
@@ -843,23 +854,23 @@ public class BasicITCase extends AbstractBaseTestITCase {
                 .expand("NavPropertyETKeyNavOne", "NavPropertyETKeyNavMany")
                 .build());
     entityRequest.addCustomHeader(HttpHeader.COOKIE, cookie);
-    final ODataRetrieveResponse<ClientEntity> entitytResponse = 
entityRequest.execute();
+    final ODataRetrieveResponse<ClientEntity> entityResponse = 
entityRequest.execute();
 
-    assertEquals(HttpStatusCode.OK.getStatusCode(), 
entitytResponse.getStatusCode());
-    assertEquals(1, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne")
+    assertEquals(HttpStatusCode.OK.getStatusCode(), 
entityResponse.getStatusCode());
+    assertEquals(1, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavOne")
         .asInlineEntity()
         .getEntity()
         .getProperty("PropertyInt16")
         .getPrimitiveValue()
         .toValue());
 
-    assertEquals(3, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(3, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
         .size());
 
-    assertEquals(1, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(1, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
@@ -868,7 +879,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
         .getPrimitiveValue()
         .toValue());
 
-    assertEquals(2, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(2, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
@@ -877,7 +888,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
         .getPrimitiveValue()
         .toValue());
 
-    assertEquals(3, 
entitytResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
+    assertEquals(3, 
entityResponse.getBody().getNavigationLink("NavPropertyETKeyNavMany")
         .asInlineEntitySet()
         .getEntitySet()
         .getEntities()
@@ -886,7 +897,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
         .getPrimitiveValue()
         .toValue());
 
-    final Iterator<ClientValue> collectionIterator = entitytResponse.getBody()
+    final Iterator<ClientValue> collectionIterator = entityResponse.getBody()
         .getProperty("CollPropertyString")
         .getCollectionValue()
         .iterator();
@@ -894,7 +905,7 @@ public class BasicITCase extends AbstractBaseTestITCase {
     assertEquals("Single entry!", 
collectionIterator.next().asPrimitive().toValue());
     assertFalse(collectionIterator.hasNext());
 
-    final ClientComplexValue propCompAllPrim = entitytResponse.getBody()
+    final ClientComplexValue propCompAllPrim = entityResponse.getBody()
         .getProperty("PropertyCompAllPrim")
         .getComplexValue();
 
@@ -902,15 +913,15 @@ public class BasicITCase extends AbstractBaseTestITCase {
     assertTrue(propCompAllPrim.get("PropertyInt16").hasNullValue());
     assertTrue(propCompAllPrim.get("PropertyDate").hasNullValue());
 
-    final ClientComplexValue propCompTwoPrim = entitytResponse.getBody()
+    final ClientComplexValue propCompTwoPrim = entityResponse.getBody()
         .getProperty("PropertyCompTwoPrim")
         .getComplexValue();
 
     assertEquals("Must not be null", 
propCompTwoPrim.get("PropertyString").getPrimitiveValue().toValue());
     assertEquals(42, 
propCompTwoPrim.get("PropertyInt16").getPrimitiveValue().toValue());
 
-    
assertNotNull(entitytResponse.getBody().getProperty("PropertyCompNav").getComplexValue());
-    assertTrue(entitytResponse.getBody()
+    
assertNotNull(entityResponse.getBody().getProperty("PropertyCompNav").getComplexValue());
+    assertTrue(entityResponse.getBody()
         .getProperty("PropertyCompNav")
         .getComplexValue()
         .get("PropertyInt16")

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
 
b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
index 1dbd0e6..485aace 100644
--- 
a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
+++ 
b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/PrimitiveComplexITCase.java
@@ -33,6 +33,7 @@ import java.util.Iterator;
 import org.apache.commons.io.IOUtils;
 import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.header.HeaderName;
 import 
org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest;
 import 
org.apache.olingo.client.api.communication.request.cud.ODataPropertyUpdateRequest;
 import 
org.apache.olingo.client.api.communication.request.cud.ODataValueUpdateRequest;
@@ -368,6 +369,21 @@ public class PrimitiveComplexITCase extends 
AbstractBaseTestITCase {
   }
 
   @Test
+  public void updatePropertyValueMinimalResponse() throws Exception {
+    ODataValueUpdateRequest request = 
getClient().getCUDRequestFactory().getValueUpdateRequest(
+        
getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESTwoPrim").appendKeySegment(32766)
+            .appendPropertySegment("PropertyString")
+            .build(),
+        UpdateType.REPLACE,
+        
getClient().getObjectFactory().newPrimitiveValueBuilder().buildString("Test 
String1"));
+    request.setPrefer(getClient().newPreferences().returnMinimal());
+
+    final ODataValueUpdateResponse response = request.execute();
+    assertEquals(HttpStatusCode.NO_CONTENT.getStatusCode(), 
response.getStatusCode());
+    assertEquals("return=\"minimal\"", 
response.getHeader(HeaderName.preferenceApplied).iterator().next());
+  }
+
+  @Test
   public void readPrimitiveCollectionCount() {
     final ODataValueRequest request = getClient().getRetrieveRequestFactory()
         .getValueRequest(getClient().newURIBuilder(SERVICE_URI)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
 
b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
index bbd9d51..9cd8e34 100644
--- 
a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
+++ 
b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/SystemQueryOptionITCase.java
@@ -25,6 +25,8 @@ import java.net.URI;
 
 import org.apache.olingo.client.api.ODataClient;
 import org.apache.olingo.client.api.communication.ODataClientErrorException;
+import org.apache.olingo.client.api.communication.header.HeaderName;
+import 
org.apache.olingo.client.api.communication.request.retrieve.ODataEntitySetRequest;
 import 
org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
 import org.apache.olingo.client.api.domain.ClientEntity;
 import org.apache.olingo.client.api.domain.ClientEntitySet;
@@ -211,7 +213,7 @@ public class SystemQueryOptionITCase extends 
AbstractBaseTestITCase {
 
     // Check initial next link format
     URI nextLink = response.getBody().getNext();
-    assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=1", 
nextLink.toASCIIString());
+    assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=1%2A10", 
nextLink.toASCIIString());
 
     // Check subsequent next links
     response = client.getRetrieveRequestFactory()
@@ -219,7 +221,7 @@ public class SystemQueryOptionITCase extends 
AbstractBaseTestITCase {
         .execute();
 
     nextLink = response.getBody().getNext();
-    assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=2", 
nextLink.toASCIIString());
+    assertEquals(SERVICE_URI + "/ESServerSidePaging?%24skiptoken=2%2A10", 
nextLink.toASCIIString());
   }
 
   @Test
@@ -236,7 +238,7 @@ public class SystemQueryOptionITCase extends 
AbstractBaseTestITCase {
 
     // Check initial next link format
     URI nextLink = response.getBody().getNext();
-    assertEquals(SERVICE_URI + 
"/ESServerSidePaging?%24count=true&%24skiptoken=1",
+    assertEquals(SERVICE_URI + 
"/ESServerSidePaging?%24count=true&%24skiptoken=1%2A10",
         nextLink.toASCIIString());
 
     int token = 1;
@@ -250,7 +252,7 @@ public class SystemQueryOptionITCase extends 
AbstractBaseTestITCase {
 
       nextLink = response.getBody().getNext();
       if (nextLink != null) {
-        assertEquals(SERVICE_URI + 
"/ESServerSidePaging?%24count=true&%24skiptoken=" + token,
+        assertEquals(SERVICE_URI + 
"/ESServerSidePaging?%24count=true&%24skiptoken=" + token + "%2A10",
             nextLink.toASCIIString());
       }
     }
@@ -259,6 +261,19 @@ public class SystemQueryOptionITCase extends 
AbstractBaseTestITCase {
   }
 
   @Test
+  public void nextLinkFormatWithClientPageSize() {
+    final ODataClient client = getClient();
+    final URI uri = 
client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_SERVER_SIDE_PAGING).build();
+    ODataEntitySetRequest<ClientEntitySet> request = 
client.getRetrieveRequestFactory().getEntitySetRequest(uri);
+    request.setPrefer(getClient().newPreferences().maxPageSize(7));
+
+    final ODataRetrieveResponse<ClientEntitySet> response = request.execute();
+    assertEquals("odata.maxpagesize=\"7\"", 
response.getHeader(HeaderName.preferenceApplied).iterator().next());
+    assertEquals(SERVICE_URI + '/' + ES_SERVER_SIDE_PAGING + 
"?%24skiptoken=1%2A" + 7,
+        response.getBody().getNext().toASCIIString());
+  }
+
+  @Test
   public void testNegativeSkip() {
     ODataClient client = getClient();
     URI uri = client.newURIBuilder(SERVICE_URI)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
----------------------------------------------------------------------
diff --git 
a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
 
b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
index ab284b1..de804fc 100644
--- 
a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
+++ 
b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/http/HttpHeader.java
@@ -162,12 +162,17 @@ public interface HttpHeader {
    */
   public static final String ODATA_MAX_VERSION = "OData-MaxVersion";
 
-  // CHECKSTYLE:OFF
   /**
-   * OData Prefer Header
-   * See
-   * {@link <a 
href="http://docs.oasis-open.org/odata/odata/v4.0/errata01/os/complete/part1-protocol/odata-v4.0-errata01-os-part1-protocol-complete.html#_Toc399426728";>
 OData Version 4.0 Part 1: Protocol Plus Errata 01</a>}
+   * OData Prefer Header.
+   * See <a 
href="http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc406398233";>
+   * OData Version 4.0 Part 1: Protocol</a> and <a 
href="https://www.ietf.org/rfc/rfc7240.txt";>RFC 7240</a>.
    */
   public static final String PREFER = "Prefer";
-  // CHECKSTYLE:ON
+
+  /**
+   * OData Preference-Applied Header.
+   * See <a 
href="http://docs.oasis-open.org/odata/odata/v4.0/odata-v4.0-part1-protocol.html#_Toc406398247";>
+   * OData Version 4.0 Part 1: Protocol</a> and <a 
href="https://www.ietf.org/rfc/rfc7240.txt";>RFC 7240</a>.
+   */
+  public static final String PREFERENCE_APPLIED = "Preference-Applied";
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalActionProcessor.java
----------------------------------------------------------------------
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 da8c5cc..b2a9ca4 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
@@ -40,6 +40,8 @@ import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.deserializer.DeserializerResult;
+import org.apache.olingo.server.api.prefer.Preferences.Return;
+import org.apache.olingo.server.api.prefer.PreferencesApplied;
 import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor;
 import org.apache.olingo.server.api.processor.ActionComplexProcessor;
 import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor;
@@ -58,7 +60,7 @@ import org.apache.olingo.server.tecsvc.data.DataProvider;
 import org.apache.olingo.server.tecsvc.data.EntityActionResult;
 
 /**
- * Technical Processor for entity-related functionality.
+ * Technical Processor for action-related functionality.
  */
 public class TechnicalActionProcessor extends TechnicalProcessor
     implements ActionEntityCollectionProcessor, ActionEntityProcessor,
@@ -92,16 +94,26 @@ public class TechnicalActionProcessor extends 
TechnicalProcessor
       throw new ODataApplicationException("The action could not be executed.",
           HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
     }
-    final EdmEntitySet edmEntitySet = 
getEdmEntitySet(uriInfo.asUriInfoResource());
-    final EdmEntityType type = (EdmEntityType) 
action.getReturnType().getType();
-    final ODataFormat format = ODataFormat.fromContentType(responseFormat);
-    EntityCollectionSerializerOptions options = 
EntityCollectionSerializerOptions.with()
-        .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : 
getContextUrl(edmEntitySet, type, false))
-        .build();
-    response.setContent(odata.createSerializer(format)
-        .entityCollection(serviceMetadata, type, collection, 
options).getContent());
-    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-    response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+
+    final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+    if (returnPreference == null || returnPreference == Return.REPRESENTATION) 
{
+      final EdmEntitySet edmEntitySet = 
getEdmEntitySet(uriInfo.asUriInfoResource());
+      final EdmEntityType type = (EdmEntityType) 
action.getReturnType().getType();
+      final ODataFormat format = ODataFormat.fromContentType(responseFormat);
+      final EntityCollectionSerializerOptions options = 
EntityCollectionSerializerOptions.with()
+          .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : 
getContextUrl(edmEntitySet, type, false))
+          .build();
+      response.setContent(odata.createSerializer(format)
+          .entityCollection(serviceMetadata, type, collection, 
options).getContent());
+      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    } else {
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    }
+    if (returnPreference != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+    }
   }
 
   @Override
@@ -129,18 +141,32 @@ public class TechnicalActionProcessor extends 
TechnicalProcessor
             HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
       }
     } else {
-      final ODataFormat format = ODataFormat.fromContentType(responseFormat);
-      response.setContent(odata.createSerializer(format).entity(
-          serviceMetadata,
-          type,
-          entityResult.getEntity(),
-          EntitySerializerOptions.with()
-              .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : 
getContextUrl(edmEntitySet, type, true))
-              .build())
-          .getContent());
-      response.setStatusCode((entityResult.isCreated() ? 
HttpStatusCode.CREATED : HttpStatusCode.OK)
-          .getStatusCode());
-      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+      final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+      if (returnPreference == null || returnPreference == 
Return.REPRESENTATION) {
+        final ODataFormat format = ODataFormat.fromContentType(responseFormat);
+        response.setContent(odata.createSerializer(format).entity(
+            serviceMetadata,
+            type,
+            entityResult.getEntity(),
+            EntitySerializerOptions.with()
+                .contextURL(format == ODataFormat.JSON_NO_METADATA ? null : 
getContextUrl(edmEntitySet, type, true))
+                .build())
+            .getContent());
+        response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+        response.setStatusCode((entityResult.isCreated() ? 
HttpStatusCode.CREATED : HttpStatusCode.OK)
+            .getStatusCode());
+      } else {
+        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+      }
+      if (returnPreference != null) {
+        response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+            
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+      }
+      if (entityResult.isCreated()) {
+        response.setHeader(HttpHeader.LOCATION,
+            request.getRawBaseUri() + '/'
+            + odata.createUriHelper().buildCanonicalURL(edmEntitySet, 
entityResult.getEntity()));
+      }
       if (entityResult.getEntity().getETag() != null) {
         response.setHeader(HttpHeader.ETAG, 
entityResult.getEntity().getETag());
       }
@@ -170,17 +196,25 @@ public class TechnicalActionProcessor extends 
TechnicalProcessor
       throw new ODataApplicationException("The action could not be executed.",
           HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
     }
-    EdmPrimitiveType type = (EdmPrimitiveType) 
action.getReturnType().getType();
-    ContextURL contextURL = 
ContextURL.with().type(type).asCollection().build();
-    PrimitiveSerializerOptions options = 
PrimitiveSerializerOptions.with().contextURL(contextURL).build();
-
-    SerializerResult result =
-        odata.createSerializer(ODataFormat.fromContentType(responseFormat))
-            .primitiveCollection(serviceMetadata, type, property, options);
 
-    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-    response.setContent(result.getContent());
-    response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+    final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+    if (returnPreference == null || returnPreference == Return.REPRESENTATION) 
{
+      final EdmPrimitiveType type = (EdmPrimitiveType) 
action.getReturnType().getType();
+      final ContextURL contextURL = 
ContextURL.with().type(type).asCollection().build();
+      final PrimitiveSerializerOptions options = 
PrimitiveSerializerOptions.with().contextURL(contextURL).build();
+      final SerializerResult result =
+          odata.createSerializer(ODataFormat.fromContentType(responseFormat))
+              .primitiveCollection(serviceMetadata, type, property, options);
+      response.setContent(result.getContent());
+      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    } else {
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    }
+    if (returnPreference != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+    }
   }
 
   @Override
@@ -205,15 +239,22 @@ public class TechnicalActionProcessor extends 
TechnicalProcessor
             HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
       }
     } else {
-      ContextURL contextURL = ContextURL.with().type(type).build();
-      PrimitiveSerializerOptions options = 
PrimitiveSerializerOptions.with().contextURL(contextURL).build();
-
-      SerializerResult result = 
odata.createSerializer(ODataFormat.fromContentType(responseFormat))
-          .primitive(serviceMetadata, type, property, options);
-
-      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-      response.setContent(result.getContent());
-      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+      final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+      if (returnPreference == null || returnPreference == 
Return.REPRESENTATION) {
+        final ContextURL contextURL = ContextURL.with().type(type).build();
+        final PrimitiveSerializerOptions options = 
PrimitiveSerializerOptions.with().contextURL(contextURL).build();
+        final SerializerResult result = 
odata.createSerializer(ODataFormat.fromContentType(responseFormat))
+            .primitive(serviceMetadata, type, property, options);
+        response.setContent(result.getContent());
+        response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+        response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      } else {
+        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+      }
+      if (returnPreference != null) {
+        response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+            
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+      }
     }
   }
 
@@ -240,17 +281,25 @@ public class TechnicalActionProcessor extends 
TechnicalProcessor
       throw new ODataApplicationException("The action could not be executed.",
           HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
     }
-    EdmComplexType type = (EdmComplexType) action.getReturnType().getType();
-    ContextURL contextURL = 
ContextURL.with().type(type).asCollection().build();
-    ComplexSerializerOptions options = 
ComplexSerializerOptions.with().contextURL(contextURL).build();
-
-    SerializerResult result =
-        
odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complexCollection(serviceMetadata,
 type,
-            property, options);
 
-    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-    response.setContent(result.getContent());
-    response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+    final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+    if (returnPreference == null || returnPreference == Return.REPRESENTATION) 
{
+      final EdmComplexType type = (EdmComplexType) 
action.getReturnType().getType();
+      final ContextURL contextURL = 
ContextURL.with().type(type).asCollection().build();
+      final ComplexSerializerOptions options = 
ComplexSerializerOptions.with().contextURL(contextURL).build();
+      final SerializerResult result =
+          
odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complexCollection(serviceMetadata,
 type,
+              property, options);
+      response.setContent(result.getContent());
+      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+    } else {
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    }
+    if (returnPreference != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+    }
   }
 
   @Override
@@ -275,16 +324,23 @@ public class TechnicalActionProcessor extends 
TechnicalProcessor
             HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
       }
     } else {
-      ContextURL contextURL = ContextURL.with().type(type).build();
-      ComplexSerializerOptions options = 
ComplexSerializerOptions.with().contextURL(contextURL).build();
-
-      SerializerResult result =
-          
odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complex(serviceMetadata,
 type, property,
-              options);
-
-      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-      response.setContent(result.getContent());
-      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+      final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+      if (returnPreference == null || returnPreference == 
Return.REPRESENTATION) {
+        final ContextURL contextURL = ContextURL.with().type(type).build();
+        final ComplexSerializerOptions options = 
ComplexSerializerOptions.with().contextURL(contextURL).build();
+        final SerializerResult result =
+            
odata.createSerializer(ODataFormat.fromContentType(responseFormat)).complex(serviceMetadata,
 type, property,
+                options);
+        response.setContent(result.getContent());
+        response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+        response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      } else {
+        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+      }
+      if (returnPreference != null) {
+        response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+            
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/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 575b914..217d768 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
@@ -40,6 +40,8 @@ import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.deserializer.DeserializerResult;
 import org.apache.olingo.server.api.deserializer.ODataDeserializer;
+import org.apache.olingo.server.api.prefer.PreferencesApplied;
+import org.apache.olingo.server.api.prefer.Preferences.Return;
 import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
 import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
 import org.apache.olingo.server.api.processor.EntityProcessor;
@@ -162,11 +164,20 @@ public class TechnicalEntityProcessor extends 
TechnicalProcessor
       expand = deserializerResult.getExpandTree();
     }
 
-    final ODataFormat format = ODataFormat.fromContentType(responseFormat);
-    response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, 
format, expand, null)
-        .getContent());
-    response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
-    response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+    final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+    if (returnPreference == null || returnPreference == Return.REPRESENTATION) 
{
+      final ODataFormat format = ODataFormat.fromContentType(responseFormat);
+      response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, 
format, expand, null)
+          .getContent());
+      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+      response.setStatusCode(HttpStatusCode.CREATED.getStatusCode());
+    } else {
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    }
+    if (returnPreference != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+    }
     response.setHeader(HttpHeader.LOCATION,
         request.getRawBaseUri() + '/' + 
odata.createUriHelper().buildCanonicalURL(edmEntitySet, entity));
     if (entity.getETag() != null) {
@@ -209,11 +220,20 @@ public class TechnicalEntityProcessor extends 
TechnicalProcessor
     dataProvider.update(request.getRawBaseUri(), edmEntitySet, entity, 
changedEntity,
         request.getMethod() == HttpMethod.PATCH, false);
 
-    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-    final ODataFormat format = ODataFormat.fromContentType(responseFormat);
-    response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, 
format, null, null)
-        .getContent());
-    response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+    final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+    if (returnPreference == null || returnPreference == Return.REPRESENTATION) 
{
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      final ODataFormat format = ODataFormat.fromContentType(responseFormat);
+      response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, 
format, null, null)
+          .getContent());
+      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+    } else {
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    }
+    if (returnPreference != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+    }
     if (entity.getETag() != null) {
       response.setHeader(HttpHeader.ETAG, entity.getETag());
     }
@@ -234,11 +254,20 @@ public class TechnicalEntityProcessor extends 
TechnicalProcessor
     dataProvider.setMedia(entity, 
odata.createFixedFormatDeserializer().binary(request.getBody()),
         requestFormat.toContentTypeString());
 
-    final ODataFormat format = ODataFormat.fromContentType(responseFormat);
-    response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, 
format, null, null)
-        .getContent());
-    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-    response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+    final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+    if (returnPreference == null || returnPreference == Return.REPRESENTATION) 
{
+      final ODataFormat format = ODataFormat.fromContentType(responseFormat);
+      response.setContent(serializeEntity(entity, edmEntitySet, edmEntityType, 
format, null, null)
+          .getContent());
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
+    } else {
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    }
+    if (returnPreference != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
+    }
     if (entity.getETag() != null) {
       response.setHeader(HttpHeader.ETAG, entity.getETag());
     }
@@ -414,10 +443,12 @@ public class TechnicalEntityProcessor extends 
TechnicalProcessor
     SkipHandler.applySkipSystemQueryHandler(uriInfo.getSkipOption(), 
entitySet);
     TopHandler.applyTopSystemQueryOption(uriInfo.getTopOption(), entitySet);
 
-    ServerSidePagingHandler.applyServerSidePaging(uriInfo.getSkipTokenOption(),
+    final Integer pageSize = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getMaxPageSize();
+    final Integer serverPageSize = 
ServerSidePagingHandler.applyServerSidePaging(uriInfo.getSkipTokenOption(),
         entitySet,
         edmEntitySet,
-        request.getRawRequestUri());
+        request.getRawRequestUri(),
+        pageSize);
 
     // Apply expand system query option
     final ODataFormat format = 
ODataFormat.fromContentType(requestedContentType);
@@ -443,6 +474,10 @@ public class TechnicalEntityProcessor extends 
TechnicalProcessor
     response.setContent(serializerResult.getContent());
     response.setStatusCode(HttpStatusCode.OK.getStatusCode());
     response.setHeader(HttpHeader.CONTENT_TYPE, 
requestedContentType.toContentTypeString());
+    if (pageSize != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().maxPageSize(serverPageSize).build().toString());
+    }
   }
 
   private SerializerResult serializeEntityCollection(final EntityCollection 
entityCollection,

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/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 1c0d049..6a9af47 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
@@ -48,6 +48,8 @@ import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.deserializer.FixedFormatDeserializer;
+import org.apache.olingo.server.api.prefer.PreferencesApplied;
+import org.apache.olingo.server.api.prefer.Preferences.Return;
 import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
 import org.apache.olingo.server.api.processor.ComplexProcessor;
 import org.apache.olingo.server.api.processor.CountComplexCollectionProcessor;
@@ -305,17 +307,26 @@ public class TechnicalPrimitiveComplexProcessor extends 
TechnicalProcessor
 
     dataProvider.updateETag(entity);
 
-    response.setStatusCode(HttpStatusCode.OK.getStatusCode());
-    if (representationType == RepresentationType.VALUE) {
-      response.setContent(
-          serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) 
edmProperty.getType(), null));
+    final Return returnPreference = 
odata.createPreferences(request.getHeaders(HttpHeader.PREFER)).getReturn();
+    if (returnPreference == null || returnPreference == Return.REPRESENTATION) 
{
+      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
+      if (representationType == RepresentationType.VALUE) {
+        response.setContent(
+            serializePrimitiveValue(property, edmProperty, (EdmPrimitiveType) 
edmProperty.getType(), null));
+      } else {
+        final ODataFormat format = ODataFormat.fromContentType(responseFormat);
+        final SerializerResult result = serializeProperty(entity, 
edmEntitySet, path, property, edmProperty,
+            edmProperty.getType(), null, representationType, format, null, 
null);
+        response.setContent(result.getContent());
+      }
+      response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
     } else {
-      final ODataFormat format = ODataFormat.fromContentType(responseFormat);
-      final SerializerResult result = serializeProperty(entity, edmEntitySet, 
path, property, edmProperty,
-          edmProperty.getType(), null, representationType, format, null, null);
-      response.setContent(result.getContent());
+      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
+    }
+    if (returnPreference != null) {
+      response.setHeader(HttpHeader.PREFERENCE_APPLIED,
+          
PreferencesApplied.with().returnRepresentation(returnPreference).build().toString());
     }
-    response.setHeader(HttpHeader.CONTENT_TYPE, 
responseFormat.toContentTypeString());
     if (entity.getETag() != null) {
       response.setHeader(HttpHeader.ETAG, entity.getETag());
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/e5fe04ae/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
----------------------------------------------------------------------
diff --git 
a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
 
b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
index 9c6b688..71496fd 100644
--- 
a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
+++ 
b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/options/ServerSidePagingHandler.java
@@ -34,77 +34,104 @@ public class ServerSidePagingHandler {
   private static final int MAX_PAGE_SIZE = 10;
   private static final String ES_SERVER_SIDE_PAGING = "ESServerSidePaging";
 
-  public static void applyServerSidePaging(final SkipTokenOption 
skipTokenOption, final EntityCollection entitySet,
-      final EdmEntitySet edmEntitySet, final String rawRequestUri) throws 
ODataApplicationException {
+  /**
+   * <p>Applies server-side paging to the given entity collection.</p>
+   * <p>The next link is constructed and set in the data. It must support 
client-specified
+   * page sizes. Therefore, the format <code>page*pageSize</code> (with a 
literal asterisk)
+   * has been chosen for the skiptoken.</p> 
+   * @param skipTokenOption   the current skiptoken option (from a previous 
response's next link)
+   * @param entityCollection  the data
+   * @param edmEntitySet      the EDM entity set to decide whether paging must 
be done
+   * @param rawRequestUri     the request URI (used to construct the next link)
+   * @param preferredPageSize the client's preference for page size
+   * @return the chosen page size (or <code>null</code> if no paging has been 
done);
+   *        could be used in the Preference-Applied HTTP header
+   * @throws ODataApplicationException
+   */
+  public static Integer applyServerSidePaging(final SkipTokenOption 
skipTokenOption, EntityCollection entityCollection,
+      final EdmEntitySet edmEntitySet, final String rawRequestUri, final 
Integer preferredPageSize)
+      throws ODataApplicationException {
 
     if (edmEntitySet != null && shouldApplyServerSidePaging(edmEntitySet)) {
-      final int maxPageSize = getMaxPageSize();
+      final int pageSize = getPageSize(getPageSize(skipTokenOption), 
preferredPageSize);
       final int page = getPage(skipTokenOption);
-      final int itemsToSkip = maxPageSize * page;
+      final int itemsToSkip = pageSize * page;
 
-      if (itemsToSkip <= entitySet.getEntities().size()) {
-        SkipHandler.popAtMost(entitySet, itemsToSkip);
-        final int remainingItems = entitySet.getEntities().size();
-        TopHandler.reduceToSize(entitySet, maxPageSize);
+      if (itemsToSkip <= entityCollection.getEntities().size()) {
+        SkipHandler.popAtMost(entityCollection, itemsToSkip);
+        final int remainingItems = entityCollection.getEntities().size();
+        TopHandler.reduceToSize(entityCollection, pageSize);
 
-        // Determine if a new next Link has to be provided
-        if (remainingItems > maxPageSize) {
-          entitySet.setNext(createNextLink(rawRequestUri, page + 1));
+        // Determine if a new next Link has to be provided.
+        if (remainingItems > pageSize) {
+          entityCollection.setNext(createNextLink(rawRequestUri, page + 1, 
pageSize));
         }
       } else {
         throw new ODataApplicationException("Nothing found.", 
HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
       }
+      return pageSize;
     }
+    return null;
   }
 
-  private static URI createNextLink(final String rawRequestUri, final Integer 
page)
+  private static URI createNextLink(final String rawRequestUri, final Integer 
page, final int pageSize)
       throws ODataApplicationException {
+    // Remove a maybe existing skiptoken, making sure that the query part is 
not empty.
+    String nextlink = rawRequestUri.contains("?") ?
+        rawRequestUri.replaceAll("(\\$|%24)skiptoken=.+&?", 
"").replaceAll("(\\?|&)$", "") :
+        rawRequestUri;
 
-    try {
-      // Remove skip token
-      String nextlink = rawRequestUri;
+    // Add a question mark or an ampersand, depending on the current query 
part.
+    nextlink += nextlink.contains("?") ? '&' : '?';
 
-      // Remove a may existing skiptoken, make sure that the query part is not 
empty
-      if (rawRequestUri.contains("?")) {
-        nextlink = rawRequestUri.replaceAll("(\\$|%24)skiptoken=.+&?", 
"").replaceAll("(\\?|&)$", "");
-      }
+    // Append the new skiptoken.
+    try {
+      return new URI(nextlink + 
Encoder.encode(SystemQueryOptionKind.SKIPTOKEN.toString()) + '='
+          + Encoder.encode(page.toString() + '*' + pageSize));
+    } catch (final URISyntaxException e) {
+      throw new ODataApplicationException("Exception while constructing next 
link",
+          HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, 
e);
+    }
+  }
 
-      // Add a question mark or an ampersand, depending of the current query 
part
-      if (!nextlink.contains("?")) {
-        nextlink = nextlink + "?";
-      } else {
-        nextlink = nextlink + "&";
-      }
+  private static boolean shouldApplyServerSidePaging(final EdmEntitySet 
edmEntitySet) {
+    return ES_SERVER_SIDE_PAGING.equals(edmEntitySet.getName());
+  }
 
-      // Append the new nextlink
-      return new URI(nextlink + 
Encoder.encode(SystemQueryOptionKind.SKIPTOKEN.toString()) + "="
-          + Encoder.encode(page.toString()));
+  private static int getPageSize(final int skipTokenPageSize, final Integer 
preferredPageSize) {
+    return skipTokenPageSize > 0 ? skipTokenPageSize :
+        preferredPageSize == null || preferredPageSize >= MAX_PAGE_SIZE ?
+            MAX_PAGE_SIZE :
+            preferredPageSize;
+  }
 
-    } catch (URISyntaxException e) {
-      throw new ODataApplicationException("Exception while constructing next 
link",
-          HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT);
+  private static int getPageSize(final SkipTokenOption skipTokenOption) throws 
ODataApplicationException {
+    if (skipTokenOption != null && skipTokenOption.getValue().length() >= 3
+        && skipTokenOption.getValue().contains("*")) {
+      final String value = skipTokenOption.getValue();
+      try {
+        return Integer.parseInt(value.substring(value.indexOf('*') + 1));
+      } catch (final NumberFormatException e) {
+        throw new ODataApplicationException("Invalid skip token", 
HttpStatusCode.BAD_REQUEST.getStatusCode(),
+            Locale.ROOT, e);
+      }
+    } else {
+      return 0;
     }
   }
 
   private static int getPage(final SkipTokenOption skipTokenOption) throws 
ODataApplicationException {
-    if (skipTokenOption != null) {
+    if (skipTokenOption != null && skipTokenOption.getValue().length() >= 3
+        && skipTokenOption.getValue().contains("*")) {
+      final String value = skipTokenOption.getValue();
       try {
-        return Integer.parseInt(skipTokenOption.getValue());
-      } catch (NumberFormatException e) {
+        return Integer.parseInt(value.substring(0, value.indexOf('*')));
+      } catch (final NumberFormatException e) {
         throw new ODataApplicationException("Invalid skip token", 
HttpStatusCode.BAD_REQUEST.getStatusCode(),
-            Locale.ROOT);
+            Locale.ROOT, e);
       }
     } else {
       return 0;
     }
   }
-
-  private static boolean shouldApplyServerSidePaging(final EdmEntitySet 
edmEntitySet) {
-    return ES_SERVER_SIDE_PAGING.equals(edmEntitySet.getName());
-  }
-
-  private static int getMaxPageSize() {
-    // TODO Consider odata.maxpagesize preference?
-    return MAX_PAGE_SIZE;
-  }
 }

Reply via email to