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/01/14 15:32:53 UTC

olingo-odata4 git commit: [OLINGO-511] Navigation property reference improved

Repository: olingo-odata4
Updated Branches:
  refs/heads/master b32bfd9a1 -> 1c735e89b


[OLINGO-511] Navigation property reference improved

Signed-off-by: Christian Amend <ch...@apache.org>


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

Branch: refs/heads/master
Commit: 1c735e89b37a1adadd6d52173776ada983345827
Parents: b32bfd9
Author: Christian Holzer <c....@sap.com>
Authored: Mon Dec 22 15:28:11 2014 +0100
Committer: Christian Amend <ch...@apache.org>
Committed: Wed Jan 14 15:32:12 2015 +0100

----------------------------------------------------------------------
 .../commons/AbstractPersistenceManager.java     |  4 +-
 .../java/org/apache/olingo/fit/V4Services.java  | 25 ++++++++++
 .../fit/proxy/v4/APIBasicDesignTestITCase.java  | 19 +++++++-
 .../olingo/fit/v4/EntityUpdateTestITCase.java   | 45 +++++++++++++----
 .../request/cud/v4/CUDRequestFactory.java       | 44 +++++++++++------
 .../cud/v4/ODataReferenceAddingRequest.java     | 10 +++-
 .../v4/ODataReferenceAddingResponse.java        |  7 ++-
 .../client/api/serialization/ODataWriter.java   | 13 +++++
 .../cud/v3/ODataLinkUpdateRequestImpl.java      |  2 +-
 .../request/cud/v4/CUDRequestFactoryImpl.java   | 34 +++++++++----
 .../cud/v4/ODataReferenceAddingRequestImpl.java | 51 ++++++++++++--------
 .../core/serialization/ODataWriterImpl.java     | 21 ++++++++
 .../core/serialization/AtomSerializer.java      | 17 +++++++
 .../core/serialization/JsonSerializer.java      | 13 +++++
 14 files changed, 244 insertions(+), 61 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
----------------------------------------------------------------------
diff --git a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
index 917ea7b..a45df6f 100644
--- a/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
+++ b/ext/client-proxy/src/main/java/org/apache/olingo/ext/proxy/commons/AbstractPersistenceManager.java
@@ -479,10 +479,12 @@ abstract class AbstractPersistenceManager implements PersistenceManager {
           final PersistenceChanges changeset) {
 
     LOG.debug("Update '{}'", targetRef);
+    URI sericeRoot = handler.getClient().newURIBuilder(handler.getClient().getServiceRoot()).build();
+    
     if (service.getClient().getServiceVersion().compareTo(ODataServiceVersion.V30) >= 1) {
       final ODataReferenceAddingRequest req =
               ((org.apache.olingo.client.api.v4.EdmEnabledODataClient) service.getClient()).getCUDRequestFactory().
-              getReferenceAddingRequest(source, targetRef);
+              getReferenceAddingRequest(sericeRoot, source, targetRef);
 
       req.setPrefer(new ODataPreferences(service.getClient().getServiceVersion()).returnContent());
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/fit/src/main/java/org/apache/olingo/fit/V4Services.java
----------------------------------------------------------------------
diff --git a/fit/src/main/java/org/apache/olingo/fit/V4Services.java b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
index b370cb8..6af5e2e 100644
--- a/fit/src/main/java/org/apache/olingo/fit/V4Services.java
+++ b/fit/src/main/java/org/apache/olingo/fit/V4Services.java
@@ -61,6 +61,7 @@ import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.NotFoundException;
 import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
@@ -70,6 +71,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -85,6 +87,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import java.util.regex.Pattern;
+
 import javax.ws.rs.BadRequestException;
 
 @Service
@@ -175,7 +178,29 @@ public class V4Services extends AbstractServices {
       return xml.createFaultResponse(Accept.JSON_FULLMETA.toString(), e);
     }
   }
+  
+  @PUT
+  @Path("/People(1)/Parent")
+  @SuppressWarnings("unused")
+  public Response changeSingleValuedNavigationPropertyReference(
+      @Context final UriInfo uriInfo,
+      @HeaderParam("Accept") @DefaultValue(StringUtils.EMPTY) final String accept,
+      @HeaderParam("Content-Type") @DefaultValue(StringUtils.EMPTY) final String contentType,
+      final String content) {
 
+    try {
+        final Accept contentTypeValue = Accept.parse(contentType, version);
+        assert contentTypeValue == Accept.JSON;
+        
+        ResWrap<Entity> entity = jsonDeserializer.toEntity(IOUtils.toInputStream(content, Constants.ENCODING));
+        
+        return Response.noContent().type(MediaType.APPLICATION_JSON).build();
+      }catch (Exception e) {
+        LOG.error("While update single property reference", e);
+        return xml.createFaultResponse(accept, e);
+      }
+  }
+  
   @POST
   @Path("/async/$batch")
   public Response async(

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
index 2f91916..2aa5fbd 100644
--- a/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/proxy/v4/APIBasicDesignTestITCase.java
@@ -31,6 +31,7 @@ import java.math.BigDecimal;
 import java.sql.Timestamp;
 import java.util.Calendar;
 import java.util.TimeZone;
+
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.olingo.client.api.v4.EdmEnabledODataClient;
@@ -106,7 +107,23 @@ public class APIBasicDesignTestITCase extends AbstractTestITCase {
     assertEquals("http://localhost:9080/stub/StaticService/V40/Static.svc/Orders(7)",
             orders.iterator().next().readEntityReferenceID());
   }
-
+  
+  @Test
+  public void changeSingleNavigationProperty() {
+    /*
+     * See OData Spec 11.4.6.3 
+     * Alternatively, a relationship MAY be updated as part of an update to the source entity by including 
+     * the required binding information for the new target entity.
+     * 
+     * => use PATCH instead of PUT
+     */
+    final Person person1 = container.getPeople().getByKey(1).load();
+    final Person person5 = container.getPeople().getByKey(5).load();
+    
+    person1.setParent(person5);
+    container.flush();
+  }
+  
   @Test
   public void addViaReference() {
     final Order order = container.getOrders().getByKey(8).load();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/fit/src/test/java/org/apache/olingo/fit/v4/EntityUpdateTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/EntityUpdateTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/EntityUpdateTestITCase.java
index 2670368..3f6ab92 100644
--- a/fit/src/test/java/org/apache/olingo/fit/v4/EntityUpdateTestITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/EntityUpdateTestITCase.java
@@ -18,26 +18,29 @@
  */
 package org.apache.olingo.fit.v4;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.UUID;
+
 import org.apache.olingo.client.api.communication.request.cud.ODataEntityUpdateRequest;
+import org.apache.olingo.client.api.communication.request.cud.v4.ODataReferenceAddingRequest;
 import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
 import org.apache.olingo.client.api.communication.response.ODataEntityUpdateResponse;
+import org.apache.olingo.client.api.communication.response.v4.ODataReferenceAddingResponse;
 import org.apache.olingo.commons.api.domain.ODataLink;
 import org.apache.olingo.commons.api.domain.v4.ODataEntity;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ODataFormat;
+import org.junit.Ignore;
 import org.junit.Test;
 
-import java.math.BigDecimal;
-import java.net.URI;
-import java.util.Calendar;
-import java.util.TimeZone;
-import java.util.UUID;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
 public class EntityUpdateTestITCase extends AbstractTestITCase {
 
   private void upsert(final UpdateType updateType, final ODataFormat format) {
@@ -75,6 +78,30 @@ public class EntityUpdateTestITCase extends AbstractTestITCase {
   }
 
   @Test
+  @Ignore
+  public void testUpateSingleValuedNavtiogationReference() throws Exception {
+    URI targetURI =
+        getClient().newURIBuilder(testStaticServiceRootURL)
+            .appendEntitySetSegment("People")
+            .appendKeySegment(1)
+            .appendNavigationSegment("Parent")
+            .build();
+
+    URI reference = getClient().newURIBuilder(testStaticServiceRootURL)
+        .appendEntitySetSegment("People")
+        .appendKeySegment(0)
+        .build();
+
+    final ODataReferenceAddingRequest request =
+        getClient().getCUDRequestFactory().getReferenceSingleChangeRequest(new URI(testStaticServiceRootURL),
+            targetURI, reference);
+
+    final ODataReferenceAddingResponse response = request.execute();
+
+    assertEquals(204, response.getStatusCode());
+  }
+
+  @Test
   public void atomUpsert() {
     upsert(UpdateType.PATCH, ODataFormat.ATOM);
     upsert(UpdateType.REPLACE, ODataFormat.ATOM);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
index 54884fe..0e4900d 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/CUDRequestFactory.java
@@ -1,18 +1,18 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
+ * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
+ * regarding copyright ownership. The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
+ * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
@@ -27,20 +27,32 @@ import org.apache.olingo.commons.api.domain.v4.ODataSingleton;
 public interface CUDRequestFactory extends CommonCUDRequestFactory<UpdateType> {
 
   ODataEntityUpdateRequest<ODataSingleton> getSingletonUpdateRequest(
-          URI targetURI, UpdateType type, ODataSingleton changes);
+      URI targetURI, UpdateType type, ODataSingleton changes);
 
   ODataEntityUpdateRequest<ODataSingleton> getSingletonUpdateRequest(
-          UpdateType type, ODataSingleton entity);
+      UpdateType type, ODataSingleton entity);
 
   /**
    * A successful POST request to a navigation property's references collection adds a relationship to an existing
-   * entity. The request body MUST contain a single entity reference that identifies the entity to be added. See the
-   * appropriate format document for details. On successful completion, the response MUST be 204 No Content and contain
-   * an empty body.
-   *
-   * @param targetURI entity set URI
+   * entity. The request body MUST contain a single entity reference that identifies the entity to be added.
+   * [OData-Protocol 4.0 - 11.4.6.1]
+   * 
+   * @param serviceRoot serviceRoot URI
+   * @param targetURI navigation property reference collection URI
    * @param reference entity reference
-   * @return new ODataEntityCreateRequest instance.
+   * @return new ODataReferenceAddingRequest instance.
    */
-  ODataReferenceAddingRequest getReferenceAddingRequest(URI targetURI, URI reference);
+  ODataReferenceAddingRequest getReferenceAddingRequest(URI serviceRoot, URI targetURI, URI reference);
+
+  /**
+   * A successful PUT request to a single-valued navigation property�s reference resource changes the related entity.
+   * The request body MUST contain a single entity reference that identifies the existing entity to be related.
+   * [OData-Protocol 4.0 - 11.4.6.3]
+   * 
+   * @param serviceRoot serviceRoot URI
+   * @param targetURI single-valued navigation property URI
+   * @param reference reference
+   * @return new ODataReferenceAddingRequest instance
+   */
+  ODataReferenceAddingRequest getReferenceSingleChangeRequest(URI serviceRoot, URI targetURI, URI reference);
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/ODataReferenceAddingRequest.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/ODataReferenceAddingRequest.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/ODataReferenceAddingRequest.java
index d107eb3..73a6ef4 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/ODataReferenceAddingRequest.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/request/cud/v4/ODataReferenceAddingRequest.java
@@ -23,7 +23,15 @@ import org.apache.olingo.client.api.communication.request.ODataBatchableRequest;
 import org.apache.olingo.client.api.communication.response.v4.ODataReferenceAddingResponse;
 
 /**
- * This class implements an OData delete request.
+ * This class implements an OData reference adding request.
+ * 
+ * ODataReferenceAdding requests eighter add or change the reference of navigation properties.
+ * 
+ * If the navigation property is a collection of navigation references, the request adds a new reference to the
+ * collection.  [OData Protocol 4.0 - 11.4.6.1]
+ * 
+ * If the request addresses an navigation property, which references a single entity, the reference will
+ * be changed to the value provided by the request. [OData-Protocol 4.0 - 11.4.6.3]
  */
 public interface ODataReferenceAddingRequest
         extends ODataBasicRequest<ODataReferenceAddingResponse>, ODataBatchableRequest {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/ODataReferenceAddingResponse.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/ODataReferenceAddingResponse.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/ODataReferenceAddingResponse.java
index 8c85461..9527d38 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/ODataReferenceAddingResponse.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/communication/response/v4/ODataReferenceAddingResponse.java
@@ -21,9 +21,12 @@ package org.apache.olingo.client.api.communication.response.v4;
 import org.apache.olingo.client.api.communication.response.ODataResponse;
 
 /**
- * This class implements the response to an OData delete request.
+ * This class implements the response to an OData Reference Adding request.
  *
- * @see org.apache.olingo.client.api.communication.request.cud.ODataDeleteRequest
+ * If the request was successful, the service response has status code 204 and
+ * the body has to be empty.
+ *
+ * @see org.apache.olingo.api.request.cud.v4.ODataReferenceAddingRequest
  */
 public interface ODataReferenceAddingResponse extends ODataResponse {
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java
----------------------------------------------------------------------
diff --git a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java
index 8711487..0e92989 100644
--- a/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java
+++ b/lib/client-api/src/main/java/org/apache/olingo/client/api/serialization/ODataWriter.java
@@ -19,8 +19,10 @@
 package org.apache.olingo.client.api.serialization;
 
 import java.io.InputStream;
+import java.net.URI;
 import java.util.Collection;
 
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataLink;
@@ -79,4 +81,15 @@ public interface ODataWriter {
    */
   InputStream writeLink(ODataLink link, ODataFormat format)
       throws ODataSerializerException;
+  
+  /**
+   * Writes a entity reference
+   * 
+   * @param reference reference to be serialized
+   * @param format  serialization format
+   * @return stream of serialized objects 
+   * @throws ODataSerializerException
+   */
+  InputStream writeReference(ResWrap<URI> reference, ODataFormat format)
+    throws ODataSerializerException;
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
index b182d89..b39f424 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v3/ODataLinkUpdateRequestImpl.java
@@ -55,7 +55,7 @@ public class ODataLinkUpdateRequestImpl extends AbstractODataBasicRequest<ODataL
    * @param targetURI entity URI.
    * @param link entity to be linked.
    */
-  ODataLinkUpdateRequestImpl(final CommonODataClient<?> odataClient,
+  public ODataLinkUpdateRequestImpl(final CommonODataClient<?> odataClient,
           final HttpMethod method, final URI targetURI, final ODataLink link) {
     super(odataClient, method, targetURI);
     // set request body

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
index f53e985..fdf0cd7 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/CUDRequestFactoryImpl.java
@@ -1,18 +1,18 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
+ * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
+ * regarding copyright ownership. The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
+ * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
@@ -26,6 +26,7 @@ import org.apache.olingo.client.api.communication.request.cud.v4.ODataReferenceA
 import org.apache.olingo.client.api.communication.request.cud.v4.UpdateType;
 import org.apache.olingo.client.api.v4.ODataClient;
 import org.apache.olingo.client.core.communication.request.cud.AbstractCUDRequestFactory;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.v4.ODataSingleton;
 import org.apache.olingo.commons.api.http.HttpMethod;
 
@@ -50,7 +51,20 @@ public class CUDRequestFactoryImpl extends AbstractCUDRequestFactory<UpdateType>
   }
 
   @Override
-  public ODataReferenceAddingRequest getReferenceAddingRequest(final URI targetURI, final URI reference) {
-    return new ODataReferenceAddingRequestImpl(client, HttpMethod.POST, targetURI, reference);
-  }
+  public ODataReferenceAddingRequest getReferenceAddingRequest(final URI serviceRoot, final URI targetURI,
+      final URI reference) {
+    final URI contextURI = client.newURIBuilder(serviceRoot.toASCIIString()).appendMetadataSegment().build();
+    ResWrap<URI> wrappedPayload = new ResWrap<URI>(contextURI, null, reference);
+
+    return new ODataReferenceAddingRequestImpl(client, HttpMethod.POST, targetURI, wrappedPayload);
+   }
+   
+    public ODataReferenceAddingRequest getReferenceSingleChangeRequest(final URI serviceRoot, final URI targetURI,
+      final URI reference) {
+     // See OData Protocol 11.4.6.3
+    final URI contextURI = client.newURIBuilder(serviceRoot.toASCIIString()).appendMetadataSegment().build();
+    ResWrap<URI> wrappedPayload = new ResWrap<URI>(contextURI, null, reference);
+
+    return new ODataReferenceAddingRequestImpl(client, HttpMethod.PUT, targetURI, wrappedPayload);
+   }  
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/ODataReferenceAddingRequestImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/ODataReferenceAddingRequestImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/ODataReferenceAddingRequestImpl.java
index 885e53d..df4fb6d 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/ODataReferenceAddingRequestImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/communication/request/cud/v4/ODataReferenceAddingRequestImpl.java
@@ -1,53 +1,56 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
+ * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
+ * regarding copyright ownership. The ASF licenses this file
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
+ * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
 package org.apache.olingo.client.core.communication.request.cud.v4;
 
-import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
 import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.client.api.communication.request.cud.v4.ODataReferenceAddingRequest;
 import org.apache.olingo.client.api.communication.response.v4.ODataReferenceAddingResponse;
+import org.apache.olingo.client.api.serialization.ODataWriter;
 import org.apache.olingo.client.core.communication.request.AbstractODataBasicRequest;
 import org.apache.olingo.client.core.communication.response.AbstractODataResponse;
-import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.client.core.uri.URIUtils;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.commons.api.http.HttpMethod;
+import org.apache.olingo.commons.api.serialization.ODataSerializerException;
 
 /**
- * This class implements an OData delete request.
+ * See {@link ODataReferenceAddingRequest}
+ * 
+ * Will be used, for single-valued navigation properties as was well as collection navigation properties
  */
 public class ODataReferenceAddingRequestImpl extends AbstractODataBasicRequest<ODataReferenceAddingResponse>
-        implements ODataReferenceAddingRequest {
+    implements ODataReferenceAddingRequest {
 
-  final URI reference;
+  final ResWrap<URI> reference;
 
   ODataReferenceAddingRequestImpl(
-          final CommonODataClient<?> odataClient, final HttpMethod method, final URI uri, final URI reference) {
+      final CommonODataClient<?> odataClient, final HttpMethod method, final URI uri, final ResWrap<URI> reference) {
     super(odataClient, method, uri);
     this.reference = reference;
-
-
   }
 
   @Override
@@ -63,9 +66,10 @@ public class ODataReferenceAddingRequestImpl extends AbstractODataBasicRequest<O
     if (reference == null) {
       return null;
     } else {
+      ODataWriter writer = odataClient.getWriter();
       try {
-        return IOUtils.toInputStream(reference.toASCIIString(), Constants.UTF8);
-      } catch (IOException e) {
+        return writer.writeReference(reference, ODataFormat.fromString(getContentType()));
+      } catch (ODataSerializerException e) {
         LOG.warn("Error serializing reference {}", reference);
         throw new IllegalArgumentException(e);
       }
@@ -74,16 +78,23 @@ public class ODataReferenceAddingRequestImpl extends AbstractODataBasicRequest<O
 
   @Override
   public ODataReferenceAddingResponse execute() {
-    return new ODataReferenceAddingResponseImpl(odataClient, httpClient, doExecute());
+    final InputStream input = getPayload();
+    ((HttpEntityEnclosingRequestBase) request).setEntity(URIUtils.buildInputStreamEntity(odataClient, input));
+
+    try {
+      return new ODataReferenceAddingResponseImpl(odataClient, httpClient, doExecute());
+    } finally {
+      IOUtils.closeQuietly(input);
+    }
   }
 
   /**
-   * Response class about an ODataDeleteRequest.
+   * Response class about an ODataReferenceAddingRequest.
    */
   private class ODataReferenceAddingResponseImpl extends AbstractODataResponse implements ODataReferenceAddingResponse {
 
     private ODataReferenceAddingResponseImpl(
-            final CommonODataClient<?> odataClient, final HttpClient httpClient, final HttpResponse res) {
+        final CommonODataClient<?> odataClient, final HttpClient httpClient, final HttpResponse res) {
 
       super(odataClient, httpClient, res);
       this.close();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java
----------------------------------------------------------------------
diff --git a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java
index 94cec0b..9bc5f34 100644
--- a/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java
+++ b/lib/client-core/src/main/java/org/apache/olingo/client/core/serialization/ODataWriterImpl.java
@@ -23,6 +23,7 @@ import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
+import java.net.URI;
 import java.util.Collection;
 import java.util.Collections;
 
@@ -30,6 +31,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.olingo.client.api.CommonODataClient;
 import org.apache.olingo.client.api.serialization.ODataWriter;
 import org.apache.olingo.commons.api.Constants;
+import org.apache.olingo.commons.api.data.ResWrap;
 import org.apache.olingo.commons.api.domain.CommonODataEntity;
 import org.apache.olingo.commons.api.domain.CommonODataProperty;
 import org.apache.olingo.commons.api.domain.ODataLink;
@@ -107,4 +109,23 @@ public class ODataWriterImpl implements ODataWriter {
       IOUtils.closeQuietly(output);
     }
   }
+
+  @Override
+  public InputStream writeReference(ResWrap<URI> reference, ODataFormat format) throws ODataSerializerException {
+    final ByteArrayOutputStream output = new ByteArrayOutputStream();
+    OutputStreamWriter writer = null;
+    
+    try {
+      writer = new OutputStreamWriter(output, Constants.UTF8);
+    } catch (final UnsupportedEncodingException e) {
+    }
+    
+    try {
+      client.getSerializer(format).write(writer, reference);
+
+      return new ByteArrayInputStream(output.toByteArray());
+    } finally {
+      IOUtils.closeQuietly(output);
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
index 5475064..68b116a 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/AtomSerializer.java
@@ -53,6 +53,7 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
 import java.io.Writer;
+import java.net.URI;
 import java.util.Collections;
 import java.util.List;
 
@@ -526,6 +527,20 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
     }
   }
 
+  private void reference(final Writer outWriter, final ResWrap<URI> container) throws XMLStreamException {
+    final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(outWriter);
+    
+    writer.writeStartDocument();
+    
+    writer.writeStartElement(Constants.ATTR_METADATA, Constants.ATTR_REF);
+    writer.writeNamespace(Constants.ATTR_METADATA, version.getNamespace(NamespaceKey.METADATA));
+    writer.writeAttribute(Constants.ATTR_METADATA, Constants.CONTEXT, container.getContextURL().toASCIIString());
+    writer.writeAttribute(Constants.ATOM_ATTR_ID, container.getPayload().toASCIIString());
+    writer.writeEndElement();
+    
+    writer.writeEndDocument();
+  }
+
   @Override
   @SuppressWarnings("unchecked")
   public <T> void write(final Writer writer, final ResWrap<T> container) throws ODataSerializerException {
@@ -540,6 +555,8 @@ public class AtomSerializer extends AbstractAtomDealer implements ODataSerialize
         property(writer, (Property) obj);
       } else if (obj instanceof Link) {
         link(writer, (Link) obj);
+      } else if(obj instanceof URI) {
+        reference(writer,(ResWrap<URI>) container);
       }
     } catch (final XMLStreamException e) {
       throw new ODataSerializerException(e);

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/1c735e89/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
index 6955b11..3db0ea9 100755
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/serialization/JsonSerializer.java
@@ -20,6 +20,7 @@ package org.apache.olingo.commons.core.serialization;
 
 import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonGenerator;
+
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.olingo.commons.api.Constants;
@@ -47,6 +48,7 @@ import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 
 import java.io.IOException;
 import java.io.Writer;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -100,6 +102,15 @@ public class JsonSerializer implements ODataSerializer {
     }
   }
 
+  private void reference(ResWrap<URI>container, JsonGenerator json) throws IOException {
+    json.writeStartObject();
+    
+    json.writeStringField(Constants.JSON_CONTEXT, container.getContextURL().toASCIIString());
+    json.writeStringField(Constants.JSON_ID, container.getPayload().toASCIIString());
+    
+    json.writeEndObject();
+  }
+
   @SuppressWarnings("unchecked")
   @Override
   public <T> void write(final Writer writer, final ResWrap<T> container) throws ODataSerializerException {
@@ -114,6 +125,8 @@ public class JsonSerializer implements ODataSerializer {
         new JsonPropertySerializer(version, serverMode).doContainerSerialize((ResWrap<Property>) container, json);
       } else if (obj instanceof Link) {
         link((Link) obj, json);
+      } else if(obj instanceof URI) {
+        reference((ResWrap<URI>) container, json);
       }
       json.flush();
     } catch (final IOException e) {