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 2014/06/26 09:44:47 UTC

[1/3] git commit: [OLINGO-310] Omit D wrapper in Json payload if needed

Repository: olingo-odata2
Updated Branches:
  refs/heads/master 242d9616e -> 6ac100f51


[OLINGO-310] Omit D wrapper in Json payload if needed


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

Branch: refs/heads/master
Commit: ebc5c79a52c27a68fc4a27adce98d2751c9da3ce
Parents: 242d961
Author: Christian Amend <ch...@apache.org>
Authored: Mon Jun 23 09:59:37 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Wed Jun 25 14:37:31 2014 +0200

----------------------------------------------------------------------
 .../api/ep/EntityProviderWriteProperties.java   | 12 +++++++
 .../ep/producer/JsonEntryEntityProducer.java    |  4 +--
 .../ep/ODataEntityProviderPropertiesTest.java   |  4 +++
 .../producer/JsonEntryEntityProducerTest.java   | 18 +++++++++++
 .../ep/producer/JsonFeedEntityProducerTest.java | 33 ++++++++++++++++++++
 5 files changed, 69 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ebc5c79a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
index 822fc84..df99f21 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
@@ -24,6 +24,7 @@ import java.util.Map;
 
 import org.apache.olingo.odata2.api.ODataCallback;
 import org.apache.olingo.odata2.api.commons.InlineCount;
+import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties.ODataEntityProviderPropertiesBuilder;
 import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
 
 /**
@@ -44,9 +45,14 @@ public class EntityProviderWriteProperties {
   private URI selfLink;
   private boolean includeSimplePropertyType;
   private Map<String, Map<String, Object>> additionalLinks;
+  private boolean omitJsonWrapper;
 
   private EntityProviderWriteProperties() {}
 
+  public final boolean isOmitJsonWrapper() {
+    return omitJsonWrapper;
+  }
+
   /**
    * Returns if type information of simple properties should be in the payload.
    * @return true if information should be in the payload.
@@ -239,6 +245,12 @@ public class EntityProviderWriteProperties {
       this.properties.selfLink = properties.getSelfLink();
       this.properties.includeSimplePropertyType = properties.includeSimplePropertyType;
       this.properties.additionalLinks = properties.additionalLinks;
+      this.properties.omitJsonWrapper = properties.omitJsonWrapper;
+      return this;
+    }
+
+    public ODataEntityProviderPropertiesBuilder omitJsonWrapper(boolean omitJsonWrapper) {
+      properties.omitJsonWrapper = omitJsonWrapper;
       return this;
     }
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ebc5c79a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
index 8ad5d42..1f3693b 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
@@ -70,7 +70,7 @@ public class JsonEntryEntityProducer {
 
     try {
       jsonStreamWriter = new JsonStreamWriter(writer);
-      if (isRootElement) {
+      if (isRootElement && !properties.isOmitJsonWrapper()) {
         jsonStreamWriter.beginObject().name(FormatJson.D);
       }
 
@@ -84,7 +84,7 @@ public class JsonEntryEntityProducer {
 
       jsonStreamWriter.endObject();
 
-      if (isRootElement) {
+      if (isRootElement && !properties.isOmitJsonWrapper()) {
         jsonStreamWriter.endObject();
       }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ebc5c79a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
index 3b0d5ab..51f39a8 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
@@ -74,6 +74,7 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
         .selfLink(selfLink)
         .includeSimplePropertyType(true)
         .additionalLinks(links)
+        .omitJsonWrapper(true)
         .build();
 
     assertEquals("Wrong amount of callbacks.", 1, properties.getCallbacks().size());
@@ -87,6 +88,7 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
     assertEquals("Wrong nextLink", "http://localhost", properties.getNextLink());
     assertTrue("Simple property types should be true", properties.isIncludeSimplePropertyType());
     assertEquals(Collections.emptyMap(), properties.getAdditionalLinks().get("aNavigationProperty"));
+    assertTrue("Json Wrapper should be omitted", properties.isOmitJsonWrapper());
   }
 
   @Test
@@ -118,6 +120,7 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
         .selfLink(selfLink)
         .includeSimplePropertyType(true)
         .additionalLinks(links)
+        .omitJsonWrapper(true)
         .build();
 
     //
@@ -136,5 +139,6 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
     assertEquals("Wrong nextLink", "http://localhost", fromProperties.getNextLink());
     assertTrue("Simple property types should be true", fromProperties.isIncludeSimplePropertyType());
     assertEquals(Collections.emptyMap(), fromProperties.getAdditionalLinks().get("aNavigationProperty"));
+    assertTrue("Json Wrapper should be omitted", properties.isOmitJsonWrapper());
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ebc5c79a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
index 8efd99a..942edf5 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
@@ -87,6 +87,24 @@ public class JsonEntryEntityProducerTest extends BaseTest {
         json);
   }
 
+  @Test
+  public void omitJsonWrapper() throws Exception {
+    final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams");
+    Map<String, Object> teamData = new HashMap<String, Object>();
+    teamData.put("Id", "1");
+    teamData.put("isScrumTeam", true);
+
+    EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.fromProperties(DEFAULT_PROPERTIES).omitJsonWrapper(true).build();
+    final ODataResponse response = new JsonEntityProvider().writeEntry(entitySet, teamData, properties);
+    final String json = verifyResponse(response);
+    assertEquals("{\"__metadata\":{\"id\":\"" + BASE_URI + "Teams('1')\","
+        + "\"uri\":\"" + BASE_URI + "Teams('1')\",\"type\":\"RefScenario.Team\"},"
+        + "\"Id\":\"1\",\"Name\":null,\"isScrumTeam\":true,"
+        + "\"nt_Employees\":{\"__deferred\":{\"uri\":\"" + BASE_URI + "Teams('1')/nt_Employees\"}}}",
+        json);
+  }
+
   @Test(expected = EntityProviderException.class)
   public void entryWithNullData() throws Exception {
     final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams");

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/ebc5c79a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducerTest.java
index a2195ae..418dc8a 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonFeedEntityProducerTest.java
@@ -79,6 +79,39 @@ public class JsonFeedEntityProducerTest extends BaseTest {
   }
 
   @Test
+  public void omitJsonWrapperMustHaveNoEffect() throws Exception {
+    final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams");
+    Map<String, Object> team1Data = new HashMap<String, Object>();
+    team1Data.put("Id", "1");
+    team1Data.put("isScrumTeam", true);
+    Map<String, Object> team2Data = new HashMap<String, Object>();
+    team2Data.put("Id", "2");
+    team2Data.put("isScrumTeam", false);
+    List<Map<String, Object>> teamsData = new ArrayList<Map<String, Object>>();
+    teamsData.add(team1Data);
+    teamsData.add(team2Data);
+
+    EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.fromProperties(DEFAULT_PROPERTIES).omitJsonWrapper(true).build();
+    final ODataResponse response = new JsonEntityProvider().writeFeed(entitySet, teamsData, properties);
+    assertNotNull(response);
+    assertNotNull(response.getEntity());
+    assertNull("EntitypProvider must not set content header", response.getContentHeader());
+
+    final String json = StringHelper.inputStreamToString((InputStream) response.getEntity());
+    assertNotNull(json);
+    assertEquals("{\"d\":{\"results\":[{\"__metadata\":{\"id\":\"" + BASE_URI + "Teams('1')\","
+        + "\"uri\":\"" + BASE_URI + "Teams('1')\",\"type\":\"RefScenario.Team\"},"
+        + "\"Id\":\"1\",\"Name\":null,\"isScrumTeam\":true,"
+        + "\"nt_Employees\":{\"__deferred\":{\"uri\":\"" + BASE_URI + "Teams('1')/nt_Employees\"}}},"
+        + "{\"__metadata\":{\"id\":\"" + BASE_URI + "Teams('2')\","
+        + "\"uri\":\"" + BASE_URI + "Teams('2')\",\"type\":\"RefScenario.Team\"},"
+        + "\"Id\":\"2\",\"Name\":null,\"isScrumTeam\":false,"
+        + "\"nt_Employees\":{\"__deferred\":{\"uri\":\"" + BASE_URI + "Teams('2')/nt_Employees\"}}}]}}",
+        json);
+  }
+
+  @Test
   public void inlineCount() throws Exception {
     final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Buildings");
     final ODataResponse response = new JsonEntityProvider().writeFeed(entitySet, new ArrayList<Map<String, Object>>(),


[2/3] git commit: [OLINGO-310] ContentOnly flag

Posted by ch...@apache.org.
[OLINGO-310] ContentOnly flag


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

Branch: refs/heads/master
Commit: f14dfd46b2a80954fba2feac49405fea5c2cfaf1
Parents: ebc5c79
Author: Christian Amend <ch...@apache.org>
Authored: Wed Jun 25 14:36:38 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Wed Jun 25 14:37:32 2014 +0200

----------------------------------------------------------------------
 .../api/ep/EntityProviderWriteProperties.java   |  22 +-
 .../ep/producer/AtomEntryEntityProducer.java    |  54 +++-
 .../ep/producer/JsonEntryEntityProducer.java    |  58 ++++-
 .../ep/ODataEntityProviderPropertiesTest.java   |   4 +
 .../core/ep/producer/AtomEntryProducerTest.java | 245 +++++++++++++++++++
 .../producer/JsonEntryEntityProducerTest.java   | 139 +++++++++++
 6 files changed, 497 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f14dfd46/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
index df99f21..b4422ee 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/EntityProviderWriteProperties.java
@@ -24,7 +24,6 @@ import java.util.Map;
 
 import org.apache.olingo.odata2.api.ODataCallback;
 import org.apache.olingo.odata2.api.commons.InlineCount;
-import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties.ODataEntityProviderPropertiesBuilder;
 import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
 
 /**
@@ -46,9 +45,14 @@ public class EntityProviderWriteProperties {
   private boolean includeSimplePropertyType;
   private Map<String, Map<String, Object>> additionalLinks;
   private boolean omitJsonWrapper;
+  private boolean contentOnly;
 
   private EntityProviderWriteProperties() {}
 
+  public final boolean isContentOnly() {
+    return contentOnly;
+  }
+
   public final boolean isOmitJsonWrapper() {
     return omitJsonWrapper;
   }
@@ -235,6 +239,17 @@ public class EntityProviderWriteProperties {
       return this;
     }
 
+    public ODataEntityProviderPropertiesBuilder omitJsonWrapper(boolean omitJsonWrapper) {
+      properties.omitJsonWrapper = omitJsonWrapper;
+      return this;
+    }
+
+    public ODataEntityProviderPropertiesBuilder contentOnly(boolean contentOnly) {
+      properties.contentOnly = contentOnly;
+      return this;
+    }
+
+    
     public ODataEntityProviderPropertiesBuilder fromProperties(final EntityProviderWriteProperties properties) {
       this.properties.mediaResourceMimeType = properties.getMediaResourceMimeType();
       this.properties.inlineCountType = properties.getInlineCountType();
@@ -246,13 +261,10 @@ public class EntityProviderWriteProperties {
       this.properties.includeSimplePropertyType = properties.includeSimplePropertyType;
       this.properties.additionalLinks = properties.additionalLinks;
       this.properties.omitJsonWrapper = properties.omitJsonWrapper;
+      this.properties.contentOnly = properties.contentOnly;
       return this;
     }
 
-    public ODataEntityProviderPropertiesBuilder omitJsonWrapper(boolean omitJsonWrapper) {
-      properties.omitJsonWrapper = omitJsonWrapper;
-      return this;
-    }
   }
 
   public static ODataEntityProviderPropertiesBuilder fromProperties(final EntityProviderWriteProperties properties) {

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f14dfd46/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java
index 95702dd..bd519e0 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryEntityProducer.java
@@ -25,6 +25,7 @@ import java.util.Collection;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
@@ -58,6 +59,7 @@ import org.apache.olingo.odata2.core.commons.Encoder;
 import org.apache.olingo.odata2.core.edm.EdmDateTimeOffset;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityInfoAggregator;
 import org.apache.olingo.odata2.core.ep.aggregator.EntityPropertyInfo;
+import org.apache.olingo.odata2.core.ep.util.FormatJson;
 import org.apache.olingo.odata2.core.ep.util.FormatXml;
 
 /**
@@ -94,25 +96,36 @@ public class AtomEntryEntityProducer {
         writer.writeAttribute(Edm.NAMESPACE_M_2007_08, FormatXml.M_ETAG, etag);
       }
 
-      // write all atom infos (mandatory and optional)
-      String selfLink = createSelfLink(eia, data, null);
-      appendAtomMandatoryParts(writer, eia, data, selfLink);
-      appendAtomOptionalParts(writer, eia, data);
-
+      String selfLink = null;
+      if (!properties.isContentOnly()) {
+        // write all atom infos (mandatory and optional)
+        selfLink = createSelfLink(eia, data, null);
+        appendAtomMandatoryParts(writer, eia, data, selfLink);
+        appendAtomOptionalParts(writer, eia, data);
+      }
       if (eia.getEntityType().hasStream()) {
         // write all links
-        appendAtomEditLink(writer, eia, data, selfLink);
-        // TODO: fix
-        appendAtomContentLink(writer, eia, data, selfLink);
-        appendAtomNavigationLinks(writer, eia, data);
+        if (!properties.isContentOnly()) {
+          appendAtomEditLink(writer, eia, data, selfLink);
+          appendAtomContentLink(writer, eia, data, selfLink);
+          appendAtomNavigationLinks(writer, eia, data);
+        } else {
+          appendAdditinalLinks(writer, eia, data);
+        }
         // write properties/content
         appendCustomProperties(writer, eia, data);
-        appendAtomContentPart(writer, eia, data, selfLink);
+        if (!properties.isContentOnly()) {
+          appendAtomContentPart(writer, eia, data, selfLink);
+        }
         appendProperties(writer, eia, data);
       } else {
         // write all links
-        appendAtomEditLink(writer, eia, data, selfLink);
-        appendAtomNavigationLinks(writer, eia, data);
+        if (!properties.isContentOnly()) {
+          appendAtomEditLink(writer, eia, data, selfLink);
+          appendAtomNavigationLinks(writer, eia, data);
+        } else {
+          appendAdditinalLinks(writer, eia, data);
+        }
         // write properties/content
         appendCustomProperties(writer, eia, data);
         writer.writeStartElement(FormatXml.ATOM_CONTENT);
@@ -133,6 +146,23 @@ public class AtomEntryEntityProducer {
     }
   }
 
+  private void appendAdditinalLinks(XMLStreamWriter writer, EntityInfoAggregator eia, Map<String, Object> data)
+      throws EntityProviderException, EdmException, URISyntaxException {
+    final Map<String, Map<String, Object>> links = properties.getAdditionalLinks();
+    if (links != null && !links.isEmpty()) {
+      for (Entry<String, Map<String, Object>> entry : links.entrySet()) {
+        Map<String, Object> navigationKeyMap = entry.getValue();
+        if (navigationKeyMap != null && !navigationKeyMap.isEmpty()) {
+          final EntityInfoAggregator targetEntityInfo = EntityInfoAggregator.create(
+              eia.getEntitySet().getRelatedEntitySet(
+                  (EdmNavigationProperty) eia.getEntityType().getProperty(entry.getKey())));
+          appendAtomNavigationLink(writer, createSelfLink(targetEntityInfo, navigationKeyMap, null), entry.getKey(),
+              null, eia, data);
+        }
+      }
+    }
+  }
+
   private void appendCustomProperties(final XMLStreamWriter writer, final EntityInfoAggregator eia,
       final Map<String, Object> data) throws EntityProviderException {
     List<String> noneSyndicationTargetPaths = eia.getNoneSyndicationTargetPathNames();

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f14dfd46/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
index 1f3693b..5369f95 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducer.java
@@ -23,6 +23,8 @@ import java.io.Writer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
 
 import org.apache.olingo.odata2.api.ODataCallback;
 import org.apache.olingo.odata2.api.edm.Edm;
@@ -76,11 +78,17 @@ public class JsonEntryEntityProducer {
 
       jsonStreamWriter.beginObject();
 
-      writeMetadata(entityInfo, data, type);
+      if (!properties.isContentOnly()) {
+        writeMetadata(entityInfo, data, type);
+      }
 
       writeProperties(entityInfo, data, type);
 
-      writeNavigationProperties(writer, entityInfo, data, type);
+      if (!properties.isContentOnly()) {
+        writeNavigationProperties(writer, entityInfo, data, type);
+      } else {
+        writeAdditonalLinksInContentOnlyCase(entityInfo);
+      }
 
       jsonStreamWriter.endObject();
 
@@ -173,9 +181,17 @@ public class JsonEntryEntityProducer {
 
   private void writeProperties(final EntityInfoAggregator entityInfo, final Map<String, Object> data,
       final EdmEntityType type) throws EdmException, EntityProviderException, IOException {
+    boolean omitComma = false;
+    if (properties.isContentOnly()) {
+      omitComma = true;
+    }
     for (final String propertyName : type.getPropertyNames()) {
       if (entityInfo.getSelectedPropertyNames().contains(propertyName)) {
-        jsonStreamWriter.separator();
+        if (omitComma == true) {
+          omitComma = false;
+        } else {
+          jsonStreamWriter.separator();
+        }
         jsonStreamWriter.name(propertyName);
         JsonPropertyEntityProducer.appendPropertyValue(jsonStreamWriter, entityInfo.getPropertyInfo(propertyName),
             data.get(propertyName));
@@ -250,16 +266,42 @@ public class JsonEntryEntityProducer {
     if (key == null || key.isEmpty()) {
       target = location + "/" + Encoder.encode(navigationPropertyName);
     } else {
-      final EntityInfoAggregator targetEntityInfo = EntityInfoAggregator.create(
-          entityInfo.getEntitySet().getRelatedEntitySet(
-              (EdmNavigationProperty) entityInfo.getEntityType().getProperty(navigationPropertyName)));
-      target = (properties.getServiceRoot() == null ? "" : properties.getServiceRoot().toASCIIString())
-          + AtomEntryEntityProducer.createSelfLink(targetEntityInfo, key, null);
+      target = createCustomTargetLink(entityInfo, navigationPropertyName, key);
     }
     JsonLinkEntityProducer.appendUri(jsonStreamWriter, target);
     jsonStreamWriter.endObject();
   }
 
+  private String createCustomTargetLink(final EntityInfoAggregator entityInfo, final String navigationPropertyName,
+      final Map<String, Object> key) throws EntityProviderException, EdmException {
+    String target;
+    final EntityInfoAggregator targetEntityInfo = EntityInfoAggregator.create(
+        entityInfo.getEntitySet().getRelatedEntitySet(
+            (EdmNavigationProperty) entityInfo.getEntityType().getProperty(navigationPropertyName)));
+    target = (properties.getServiceRoot() == null ? "" : properties.getServiceRoot().toASCIIString())
+        + AtomEntryEntityProducer.createSelfLink(targetEntityInfo, key, null);
+    return target;
+  }
+
+  private void writeAdditonalLinksInContentOnlyCase(final EntityInfoAggregator entityInfo)
+      throws IOException, EntityProviderException, EdmException {
+    final Map<String, Map<String, Object>> links = properties.getAdditionalLinks();
+    if (links != null && !links.isEmpty()) {
+      for (Entry<String, Map<String, Object>> entry : links.entrySet()) {
+        Map<String, Object> navigationKeyMap = entry.getValue();
+        if (navigationKeyMap != null && !navigationKeyMap.isEmpty()) {
+          String target = createCustomTargetLink(entityInfo, entry.getKey(), navigationKeyMap);
+          jsonStreamWriter.separator();
+          jsonStreamWriter.name(entry.getKey());
+          jsonStreamWriter.beginObject()
+              .name(FormatJson.DEFERRED);
+          JsonLinkEntityProducer.appendUri(jsonStreamWriter, target);
+          jsonStreamWriter.endObject();
+        }
+      }
+    }
+  }
+
   public String getETag() {
     return eTag;
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f14dfd46/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
index 51f39a8..73c957a 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/ODataEntityProviderPropertiesTest.java
@@ -75,6 +75,7 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
         .includeSimplePropertyType(true)
         .additionalLinks(links)
         .omitJsonWrapper(true)
+        .contentOnly(true)
         .build();
 
     assertEquals("Wrong amount of callbacks.", 1, properties.getCallbacks().size());
@@ -89,6 +90,7 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
     assertTrue("Simple property types should be true", properties.isIncludeSimplePropertyType());
     assertEquals(Collections.emptyMap(), properties.getAdditionalLinks().get("aNavigationProperty"));
     assertTrue("Json Wrapper should be omitted", properties.isOmitJsonWrapper());
+    assertTrue("ContentOnlyFlag should be set", properties.isContentOnly());
   }
 
   @Test
@@ -121,6 +123,7 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
         .includeSimplePropertyType(true)
         .additionalLinks(links)
         .omitJsonWrapper(true)
+        .contentOnly(true)
         .build();
 
     //
@@ -140,5 +143,6 @@ public class ODataEntityProviderPropertiesTest extends BaseTest {
     assertTrue("Simple property types should be true", fromProperties.isIncludeSimplePropertyType());
     assertEquals(Collections.emptyMap(), fromProperties.getAdditionalLinks().get("aNavigationProperty"));
     assertTrue("Json Wrapper should be omitted", properties.isOmitJsonWrapper());
+    assertTrue("ContentOnlyFlag should be set", properties.isContentOnly());
   }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f14dfd46/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java
index a87698d..db59c1e 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/AtomEntryProducerTest.java
@@ -53,6 +53,7 @@ import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
 import org.apache.olingo.odata2.api.exception.ODataException;
 import org.apache.olingo.odata2.api.exception.ODataMessageException;
 import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
 import org.apache.olingo.odata2.core.commons.ContentType;
 import org.apache.olingo.odata2.core.ep.AbstractProviderTest;
 import org.apache.olingo.odata2.core.ep.AtomEntityProvider;
@@ -75,6 +76,250 @@ public class AtomEntryProducerTest extends AbstractProviderTest {
   }
 
   @Test
+  public void contentOnly() throws Exception {
+    final EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.serviceRoot(BASE_URI).contentOnly(true).build();
+
+    AtomEntityProvider ser = createAtomEntityProvider();
+    ODataResponse response =
+        ser.writeEntry(MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"), employeeData,
+            properties);
+    String xmlString = verifyResponse(response);
+    assertXpathExists("/a:entry", xmlString);
+    assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+    assertXpathNotExists("/a:entry/a:id", xmlString);
+    assertXpathNotExists("/a:entry/a:title", xmlString);
+    assertXpathNotExists("/a:entry/a:updated", xmlString);
+    assertXpathNotExists("/a:entry/a:category", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Team\"and @href=\"Employees('1')/ne_Team\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Room\"and @href=\"Employees('1')/ne_Room\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Manager\" and @href=\"Employees('1')/ne_Manager\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:content", xmlString);
+
+    assertXpathExists("/a:entry/m:properties", xmlString);
+  }
+
+  @Test
+  public void contentOnlyRoom() throws Exception {
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    List<String> selectedPropertyNames = new ArrayList<String>();
+    selectedPropertyNames.add("Name");
+    ExpandSelectTreeNode expandSelectTree =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedPropertyNames).build();
+    final EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.serviceRoot(BASE_URI).contentOnly(true).expandSelectTree(expandSelectTree)
+            .build();
+
+    Map<String, Object> localRoomData = new HashMap<String, Object>();
+    localRoomData.put("Name", "Neu Schwanstein");
+
+    AtomEntityProvider ser = createAtomEntityProvider();
+    ODataResponse response = ser.writeEntry(entitySet, localRoomData, properties);
+    String xmlString = verifyResponse(response);
+    assertXpathExists("/a:entry", xmlString);
+    assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+    assertXpathNotExists("/a:entry/a:id", xmlString);
+    assertXpathNotExists("/a:entry/a:title", xmlString);
+    assertXpathNotExists("/a:entry/a:updated", xmlString);
+    assertXpathNotExists("/a:entry/a:category", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"nr_Employees\"and @href=\"Rooms('1')/nr_Employees\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"nr_Building\"and @href=\"Rooms('1')/nr_Building\"]", xmlString);
+
+    assertXpathExists("/a:entry/a:content/m:properties/d:Name", xmlString);
+  }
+
+  @Test
+  public void contentOnlyRoomSelectedOrExpandedLinksMustBeIgnored() throws Exception {
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    List<String> selectedPropertyNames = new ArrayList<String>();
+    selectedPropertyNames.add("Name");
+    List<String> navigationPropertyNames = new ArrayList<String>();
+    navigationPropertyNames.add("nr_Employees");
+    navigationPropertyNames.add("nr_Building");
+    ExpandSelectTreeNode expandSelectTree =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedPropertyNames).expandedLinks(
+            navigationPropertyNames).build();
+    final EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.serviceRoot(BASE_URI).contentOnly(true).expandSelectTree(expandSelectTree)
+            .build();
+
+    Map<String, Object> localRoomData = new HashMap<String, Object>();
+    localRoomData.put("Name", "Neu Schwanstein");
+
+    AtomEntityProvider ser = createAtomEntityProvider();
+    ODataResponse response = ser.writeEntry(entitySet, localRoomData, properties);
+    String xmlString = verifyResponse(response);
+    assertXpathExists("/a:entry", xmlString);
+    assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+    assertXpathNotExists("/a:entry/a:id", xmlString);
+    assertXpathNotExists("/a:entry/a:title", xmlString);
+    assertXpathNotExists("/a:entry/a:updated", xmlString);
+    assertXpathNotExists("/a:entry/a:category", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"nr_Employees\"and @href=\"Rooms('1')/nr_Employees\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"nr_Building\"and @href=\"Rooms('1')/nr_Building\"]", xmlString);
+
+    assertXpathExists("/a:entry/a:content/m:properties/d:Name", xmlString);
+  }
+
+  @Test
+  public void contentOnlyRoomWithAdditionalLink() throws Exception {
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    List<String> selectedPropertyNames = new ArrayList<String>();
+    selectedPropertyNames.add("Name");
+    ExpandSelectTreeNode expandSelectTree =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedPropertyNames).build();
+    Map<String, Map<String, Object>> additinalLinks = new HashMap<String, Map<String, Object>>();
+    Map<String, Object> buildingLink = new HashMap<String, Object>();
+    buildingLink.put("Id", "1");
+    additinalLinks.put("nr_Building", buildingLink);
+    final EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.serviceRoot(BASE_URI).contentOnly(true).expandSelectTree(expandSelectTree)
+            .additionalLinks(additinalLinks).build();
+
+    Map<String, Object> localRoomData = new HashMap<String, Object>();
+    localRoomData.put("Name", "Neu Schwanstein");
+
+    AtomEntityProvider ser = createAtomEntityProvider();
+    ODataResponse response = ser.writeEntry(entitySet, localRoomData, properties);
+    String xmlString = verifyResponse(response);
+    assertXpathExists("/a:entry", xmlString);
+    assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+    assertXpathNotExists("/a:entry/a:id", xmlString);
+    assertXpathNotExists("/a:entry/a:title", xmlString);
+    assertXpathNotExists("/a:entry/a:updated", xmlString);
+    assertXpathNotExists("/a:entry/a:category", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"nr_Employees\"and @href=\"Rooms('1')/nr_Employees\"]", xmlString);
+
+    assertXpathExists("/a:entry/a:content/m:properties/d:Name", xmlString);
+    assertXpathExists("/a:entry/a:link[@title=\"nr_Building\"and @href=\"Buildings('1')\"]", xmlString);
+  }
+
+  @Test
+  public void contentOnlyWithoutKey() throws Exception {
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    List<String> selectedPropertyNames = new ArrayList<String>();
+    selectedPropertyNames.add("ManagerId");
+    ExpandSelectTreeNode select =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedPropertyNames).build();
+
+    final EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.serviceRoot(BASE_URI).contentOnly(true).expandSelectTree(select).build();
+
+    Map<String, Object> localEmployeeData = new HashMap<String, Object>();
+    localEmployeeData.put("ManagerId", "1");
+
+    AtomEntityProvider ser = createAtomEntityProvider();
+    ODataResponse response =
+        ser.writeEntry(entitySet, localEmployeeData,
+            properties);
+    String xmlString = verifyResponse(response);
+    assertXpathExists("/a:entry", xmlString);
+    assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+    assertXpathNotExists("/a:entry/a:id", xmlString);
+    assertXpathNotExists("/a:entry/a:title", xmlString);
+    assertXpathNotExists("/a:entry/a:updated", xmlString);
+    assertXpathNotExists("/a:entry/a:category", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Manager\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Team\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Room\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:content", xmlString);
+
+    assertXpathExists("/a:entry/m:properties", xmlString);
+    assertXpathNotExists("/a:entry/m:properties/d:EmployeeId", xmlString);
+    assertXpathExists("/a:entry/m:properties/d:ManagerId", xmlString);
+  }
+
+  @Test
+  public void contentOnlySelectedOrExpandedLinksMustBeIgnored() throws Exception {
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    List<String> selectedPropertyNames = new ArrayList<String>();
+    selectedPropertyNames.add("ManagerId");
+
+    List<String> expandedNavigationNames = new ArrayList<String>();
+    expandedNavigationNames.add("ne_Manager");
+    expandedNavigationNames.add("ne_Team");
+    expandedNavigationNames.add("ne_Room");
+
+    ExpandSelectTreeNode select =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedPropertyNames).expandedLinks(
+            expandedNavigationNames).build();
+
+    final EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.serviceRoot(BASE_URI).contentOnly(true).expandSelectTree(select).build();
+
+    Map<String, Object> localEmployeeData = new HashMap<String, Object>();
+    localEmployeeData.put("ManagerId", "1");
+
+    AtomEntityProvider ser = createAtomEntityProvider();
+    ODataResponse response =
+        ser.writeEntry(entitySet, localEmployeeData,
+            properties);
+    String xmlString = verifyResponse(response);
+    assertXpathExists("/a:entry", xmlString);
+    assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+    assertXpathNotExists("/a:entry/a:id", xmlString);
+    assertXpathNotExists("/a:entry/a:title", xmlString);
+    assertXpathNotExists("/a:entry/a:updated", xmlString);
+    assertXpathNotExists("/a:entry/a:category", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Manager\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Team\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Room\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:content", xmlString);
+
+    assertXpathExists("/a:entry/m:properties", xmlString);
+    assertXpathNotExists("/a:entry/m:properties/d:EmployeeId", xmlString);
+    assertXpathExists("/a:entry/m:properties/d:ManagerId", xmlString);
+  }
+
+  @Test
+  public void contentOnlyWithAdditinalLink() throws Exception {
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    List<String> selectedPropertyNames = new ArrayList<String>();
+    selectedPropertyNames.add("ManagerId");
+    ExpandSelectTreeNode select =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedPropertyNames).build();
+
+    Map<String, Map<String, Object>> additinalLinks = new HashMap<String, Map<String, Object>>();
+    Map<String, Object> managerLink = new HashMap<String, Object>();
+    managerLink.put("EmployeeId", "1");
+    additinalLinks.put("ne_Manager", managerLink);
+    final EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.serviceRoot(BASE_URI).contentOnly(true).expandSelectTree(select).additionalLinks(
+            additinalLinks).build();
+
+    Map<String, Object> localEmployeeData = new HashMap<String, Object>();
+    localEmployeeData.put("ManagerId", "1");
+
+    AtomEntityProvider ser = createAtomEntityProvider();
+    ODataResponse response =
+        ser.writeEntry(entitySet, localEmployeeData,
+            properties);
+    String xmlString = verifyResponse(response);
+    assertXpathExists("/a:entry", xmlString);
+    assertXpathEvaluatesTo(BASE_URI.toASCIIString(), "/a:entry/@xml:base", xmlString);
+
+    assertXpathNotExists("/a:entry/a:id", xmlString);
+    assertXpathNotExists("/a:entry/a:title", xmlString);
+    assertXpathNotExists("/a:entry/a:updated", xmlString);
+    assertXpathNotExists("/a:entry/a:category", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Team\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:link[@title=\"ne_Room\"]", xmlString);
+    assertXpathNotExists("/a:entry/a:content", xmlString);
+
+    assertXpathExists("/a:entry/m:properties", xmlString);
+    assertXpathNotExists("/a:entry/m:properties/d:EmployeeId", xmlString);
+    assertXpathExists("/a:entry/m:properties/d:ManagerId", xmlString);
+
+    assertXpathExists("/a:entry/a:link[@href=\"Managers('1')\" and @title=\"ne_Manager\"]", xmlString);
+  }
+
+  @Test
   public void noneSyndicationKeepInContentFalseMustNotShowInProperties() throws Exception {
     // prepare Mock
     EdmEntitySet employeesSet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f14dfd46/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
index 942edf5..7040e2a 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/producer/JsonEntryEntityProducerTest.java
@@ -87,6 +87,145 @@ public class JsonEntryEntityProducerTest extends BaseTest {
         json);
   }
 
+  @SuppressWarnings("unchecked")
+  @Test
+  public void contentOnly() throws Exception {
+    HashMap<String, Object> employeeData = new HashMap<String, Object>();
+    Calendar date = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+    date.clear();
+    date.set(1999, 0, 1);
+    employeeData.put("EmployeeId", "1");
+    employeeData.put("ImmageUrl", null);
+    employeeData.put("ManagerId", "1");
+    employeeData.put("Age", new Integer(52));
+    employeeData.put("RoomId", "1");
+    employeeData.put("EntryDate", date);
+    employeeData.put("TeamId", "42");
+    employeeData.put("EmployeeName", "Walter Winter");
+    Map<String, Object> locationData = new HashMap<String, Object>();
+    Map<String, Object> cityData = new HashMap<String, Object>();
+    cityData.put("PostalCode", "33470");
+    cityData.put("CityName", "Duckburg");
+    locationData.put("City", cityData);
+    locationData.put("Country", "Calisota");
+    employeeData.put("Location", locationData);
+
+    final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.fromProperties(DEFAULT_PROPERTIES).omitJsonWrapper(true).contentOnly(true)
+            .build();
+    final ODataResponse response = new JsonEntityProvider().writeEntry(entitySet, employeeData, properties);
+    Map<String, Object> employee =
+        (Map<String, Object>) new Gson().fromJson(new InputStreamReader((InputStream) response.getEntity()), Map.class);
+    assertNull(employee.get("__metadata"));
+    assertNull(employee.get("ne_Manager"));
+    assertNull(employee.get("ne_Team"));
+    assertNull(employee.get("ne_Room"));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void contentOnlyWithoutKey() throws Exception {
+    HashMap<String, Object> employeeData = new HashMap<String, Object>();
+    employeeData.put("ManagerId", "1");
+    employeeData.put("Age", new Integer(52));
+    employeeData.put("RoomId", "1");
+    employeeData.put("TeamId", "42");
+
+    List<String> selectedProperties = new ArrayList<String>();
+    selectedProperties.add("ManagerId");
+    selectedProperties.add("Age");
+    selectedProperties.add("RoomId");
+    selectedProperties.add("TeamId");
+    final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+
+    ExpandSelectTreeNode expandSelectTreeNode =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedProperties).build();
+    EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.fromProperties(DEFAULT_PROPERTIES).omitJsonWrapper(true).contentOnly(true)
+            .expandSelectTree(expandSelectTreeNode).build();
+    final ODataResponse response = new JsonEntityProvider().writeEntry(entitySet, employeeData, properties);
+    Map<String, Object> employee =
+        (Map<String, Object>) new Gson().fromJson(new InputStreamReader((InputStream) response.getEntity()), Map.class);
+    assertNull(employee.get("__metadata"));
+    assertNull(employee.get("ne_Manager"));
+    assertNull(employee.get("ne_Team"));
+    assertNull(employee.get("ne_Room"));
+
+    assertEquals("1", employee.get("ManagerId"));
+    assertEquals("1", employee.get("RoomId"));
+    assertEquals("42", employee.get("TeamId"));
+    assertEquals(new Double(52), employee.get("Age"));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void contentOnlySelectedOrExpandedLinksMustBeIgnored() throws Exception {
+    final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+
+    HashMap<String, Object> employeeData = new HashMap<String, Object>();
+    employeeData.put("ManagerId", "1");
+
+    List<String> selectedProperties = new ArrayList<String>();
+    selectedProperties.add("ManagerId");
+
+    List<String> expandedLinks = new ArrayList<String>();
+    expandedLinks.add("ne_Manager");
+    expandedLinks.add("ne_Team");
+    expandedLinks.add("ne_Room");
+
+    ExpandSelectTreeNode expandSelectTreeNode =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedProperties).expandedLinks(expandedLinks)
+            .build();
+    EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.fromProperties(DEFAULT_PROPERTIES).omitJsonWrapper(true).contentOnly(true)
+            .expandSelectTree(expandSelectTreeNode).build();
+    final ODataResponse response = new JsonEntityProvider().writeEntry(entitySet, employeeData, properties);
+    Map<String, Object> employee =
+        (Map<String, Object>) new Gson().fromJson(new InputStreamReader((InputStream) response.getEntity()), Map.class);
+    assertNull(employee.get("__metadata"));
+    assertNull(employee.get("ne_Manager"));
+    assertNull(employee.get("ne_Team"));
+    assertNull(employee.get("ne_Room"));
+
+    assertEquals("1", employee.get("ManagerId"));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Test
+  public void contentOnlyWithAdditinalLink() throws Exception {
+    final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    HashMap<String, Object> employeeData = new HashMap<String, Object>();
+    employeeData.put("ManagerId", "1");
+
+    List<String> selectedProperties = new ArrayList<String>();
+    selectedProperties.add("ManagerId");
+
+    ExpandSelectTreeNode expandSelectTreeNode =
+        ExpandSelectTreeNode.entitySet(entitySet).selectedProperties(selectedProperties).build();
+
+    Map<String, Map<String, Object>> additinalLinks = new HashMap<String, Map<String, Object>>();
+    Map<String, Object> managerLink = new HashMap<String, Object>();
+    managerLink.put("EmployeeId", "1");
+    additinalLinks.put("ne_Manager", managerLink);
+
+    EntityProviderWriteProperties properties =
+        EntityProviderWriteProperties.fromProperties(DEFAULT_PROPERTIES).omitJsonWrapper(true).contentOnly(true)
+            .expandSelectTree(expandSelectTreeNode).additionalLinks(additinalLinks).build();
+    final ODataResponse response = new JsonEntityProvider().writeEntry(entitySet, employeeData, properties);
+   //System.out.println(StringHelper.inputStreamToString((InputStream) response.getEntity()));
+    Map<String, Object> employee =
+        (Map<String, Object>) new Gson().fromJson(new InputStreamReader((InputStream) response.getEntity()), Map.class);
+    assertNull(employee.get("__metadata"));
+    assertNull(employee.get("ne_Team"));
+    assertNull(employee.get("ne_Room"));
+
+    assertEquals("1", employee.get("ManagerId"));
+    Map<String, Object> map = (Map<String, Object>) employee.get("ne_Manager");
+    map = (Map<String, Object>) map.get("__deferred");
+    assertEquals("http://host:80/service/Managers('1')", map.get("uri"));
+  }
+
   @Test
   public void omitJsonWrapper() throws Exception {
     final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams");


[3/3] git commit: [OLINGO-310] Confirm consumer can consume content only payload

Posted by ch...@apache.org.
[OLINGO-310] Confirm consumer can consume content only payload


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

Branch: refs/heads/master
Commit: 6ac100f51a0a6bd5c0e8cfce3e650d5ed85d3f6e
Parents: f14dfd4
Author: Christian Amend <ch...@apache.org>
Authored: Wed Jun 25 15:24:14 2014 +0200
Committer: Christian Amend <ch...@apache.org>
Committed: Wed Jun 25 15:31:26 2014 +0200

----------------------------------------------------------------------
 .../core/ep/consumer/JsonEntryConsumerTest.java | 74 ++++++++++++++++++-
 .../core/ep/consumer/XmlEntityConsumerTest.java | 75 +++++++++++++++++++-
 .../src/test/resources/EmployeeContentOnly.xml  | 37 ++++++++++
 .../EmployeeContentOnlyWithAdditionalLink.xml   | 38 ++++++++++
 .../test/resources/JsonEmployeeContentOnly.json | 25 +++++++
 ...onEmployeeContentOnlyWithAdditionalLink.json | 30 ++++++++
 .../src/test/resources/JsonRoomContentOnly.json |  8 +++
 .../JsonRoomContentOnlyWithAdditionalLink.json  | 13 ++++
 .../src/test/resources/RoomContentOnly.xml      | 28 ++++++++
 .../RoomContentOnlyWithAdditionalLink.xml       | 29 ++++++++
 10 files changed, 352 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
index 30539fb..4836fd3 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumerTest.java
@@ -55,6 +55,76 @@ public class JsonEntryConsumerTest extends AbstractConsumerTest {
   private static final String negativeJsonStart_1 = "{ \"abc\": {";
   private static final String negativeJsonStart_2 = "{ \"d\": [a: 1, b: 2] }";
 
+  @Test
+  public void readContentOnlyEmployee() throws Exception {
+    // prepare
+    String content = readFile("JsonEmployeeContentOnly.json");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    JsonEntityConsumer xec = new JsonEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(9, result.getProperties().size());
+  }
+
+  @Test
+  public void readContentOnlyRoom() throws Exception {
+    // prepare
+    String content = readFile("JsonRoomContentOnly.json");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    JsonEntityConsumer xec = new JsonEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(4, result.getProperties().size());
+  }
+
+  @Test
+  public void readContentOnlyEmployeeWithAdditionalLink() throws Exception {
+    // prepare
+    String content = readFile("JsonEmployeeContentOnlyWithAdditionalLink.json");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    JsonEntityConsumer xec = new JsonEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(9, result.getProperties().size());
+    List<String> associationUris = result.getMetadata().getAssociationUris("ne_Manager");
+    assertEquals(1, associationUris.size());
+    assertEquals("http://host:8080/ReferenceScenario.svc/Managers('1')", associationUris.get(0));
+  }
+
+  @Test
+  public void readContentOnlyRoomWithAdditionalLink() throws Exception {
+    // prepare
+    String content = readFile("JsonRoomContentOnlyWithAdditionalLink.json");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    JsonEntityConsumer xec = new JsonEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(4, result.getProperties().size());
+    List<String> associationUris = result.getMetadata().getAssociationUris("nr_Building");
+    assertEquals(1, associationUris.size());
+    assertEquals("http://host:8080/ReferenceScenario.svc/Buildings('1')", associationUris.get(0));
+  }
+
   @Test(expected = EntityProviderException.class)
   public void doubleClosingBracketsAtTheEnd() throws Exception {
     String invalidJson = "{ \"Id\" : \"1\", \"Seats\" : 1, \"Version\" : 1}}";
@@ -65,7 +135,7 @@ public class JsonEntryConsumerTest extends AbstractConsumerTest {
     JsonEntityConsumer xec = new JsonEntityConsumer();
     xec.readEntry(entitySet, contentBody, DEFAULT_PROPERTIES);
   }
-  
+
   @Test
   public void readSimpleRoomEntry() throws Exception {
     ODataEntry roomEntry = prepareAndExecuteEntry(SIMPLE_ENTRY_ROOM, "Rooms", DEFAULT_PROPERTIES);
@@ -88,7 +158,7 @@ public class JsonEntryConsumerTest extends AbstractConsumerTest {
     assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Building", associationUris.get(0));
 
     EntryMetadata metadata = roomEntry.getMetadata();
-    assertEquals("W/\"1\"",metadata.getEtag());
+    assertEquals("W/\"1\"", metadata.getEtag());
   }
 
   @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
index 45e9861..2194619 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntityConsumerTest.java
@@ -433,6 +433,76 @@ public class XmlEntityConsumerTest extends AbstractXmlConsumerTest {
   }
 
   @Test
+  public void readContentOnlyEmployee() throws Exception {
+    // prepare
+    String content = readFile("EmployeeContentOnly.xml");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(9, result.getProperties().size());
+  }
+
+  @Test
+  public void readContentOnlyRoom() throws Exception {
+    // prepare
+    String content = readFile("RoomContentOnly.xml");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(4, result.getProperties().size());
+  }
+
+  @Test
+  public void readContentOnlyEmployeeWithAdditionalLink() throws Exception {
+    // prepare
+    String content = readFile("EmployeeContentOnlyWithAdditionalLink.xml");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(9, result.getProperties().size());
+    List<String> associationUris = result.getMetadata().getAssociationUris("ne_Manager");
+    assertEquals(1, associationUris.size());
+    assertEquals("Managers('1')", associationUris.get(0));
+  }
+
+  @Test
+  public void readContentOnlyRoomWithAdditionalLink() throws Exception {
+    // prepare
+    String content = readFile("RoomContentOnlyWithAdditionalLink.xml");
+    EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+    InputStream contentBody = createContentAsStream(content);
+
+    // execute
+    XmlEntityConsumer xec = new XmlEntityConsumer();
+    ODataEntry result =
+        xec.readEntry(entitySet, contentBody, EntityProviderReadProperties.init().mergeSemantic(true).build());
+
+    // verify
+    assertEquals(4, result.getProperties().size());
+    List<String> associationUris = result.getMetadata().getAssociationUris("nr_Building");
+    assertEquals(1, associationUris.size());
+    assertEquals("Buildings('1')", associationUris.get(0));
+  }
+
+  @Test
   public void readDeltaLink() throws Exception {
     // prepare
     String content = readFile("feed_with_delta_link.xml");
@@ -815,9 +885,8 @@ public class XmlEntityConsumerTest extends AbstractXmlConsumerTest {
     EntryMetadata employeeMetadata = employee.getMetadata();
     assertNotNull(employeeMetadata);
     assertEquals("W/\"1\"", employeeMetadata.getEtag());
-    
-    
-    //Inline
+
+    // Inline
     ODataEntry room = (ODataEntry) properties.get("ne_Room");
     Map<String, Object> roomProperties = room.getProperties();
     assertEquals(4, roomProperties.size());

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/EmployeeContentOnly.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/EmployeeContentOnly.xml b/odata2-lib/odata-core/src/test/resources/EmployeeContentOnly.xml
new file mode 100644
index 0000000..161b730
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/EmployeeContentOnly.xml
@@ -0,0 +1,37 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://host:8080/ReferenceScenario.svc/">
+	<m:properties>
+		<d:EmployeeId>1</d:EmployeeId>
+		<d:EmployeeName>Walter Winter</d:EmployeeName>
+		<d:ManagerId>1</d:ManagerId>
+		<d:RoomId>1</d:RoomId>
+		<d:TeamId>1</d:TeamId>
+		<d:Location m:type="RefScenario.c_Location">
+			<d:City m:type="RefScenario.c_City">
+				<d:PostalCode>69124</d:PostalCode>
+				<d:CityName>Heidelberg</d:CityName>
+			</d:City>
+			<d:Country>Germany</d:Country>
+		</d:Location>
+		<d:Age>52</d:Age>
+		<d:EntryDate>1999-01-01T00:00:00</d:EntryDate>
+		<d:ImageUrl>Employees('1')/$value</d:ImageUrl>
+	</m:properties>
+</entry>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/EmployeeContentOnlyWithAdditionalLink.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/EmployeeContentOnlyWithAdditionalLink.xml b/odata2-lib/odata-core/src/test/resources/EmployeeContentOnlyWithAdditionalLink.xml
new file mode 100644
index 0000000..dfa1b95
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/EmployeeContentOnlyWithAdditionalLink.xml
@@ -0,0 +1,38 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://host:8080/ReferenceScenario.svc/">
+	<link href="Managers('1')" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager" title="ne_Manager" type="application/atom+xml;type=entry"/>
+	<m:properties>
+		<d:EmployeeId>1</d:EmployeeId>
+		<d:EmployeeName>Walter Winter</d:EmployeeName>
+		<d:ManagerId>1</d:ManagerId>
+		<d:RoomId>1</d:RoomId>
+		<d:TeamId>1</d:TeamId>
+		<d:Location m:type="RefScenario.c_Location">
+			<d:City m:type="RefScenario.c_City">
+				<d:PostalCode>69124</d:PostalCode>
+				<d:CityName>Heidelberg</d:CityName>
+			</d:City>
+			<d:Country>Germany</d:Country>
+		</d:Location>
+		<d:Age>52</d:Age>
+		<d:EntryDate>1999-01-01T00:00:00</d:EntryDate>
+		<d:ImageUrl>Employees('1')/$value</d:ImageUrl>
+	</m:properties>
+</entry>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnly.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnly.json b/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnly.json
new file mode 100644
index 0000000..9352a29
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnly.json
@@ -0,0 +1,25 @@
+{
+	"d" : {
+		"EmployeeId" : "1",
+		"EmployeeName" : "Walter Winter",
+		"ManagerId" : "1",
+		"RoomId" : "1",
+		"TeamId" : "1",
+		"Location" : {
+			"__metadata" : {
+				"type" : "RefScenario.c_Location"
+			},
+			"City" : {
+				"__metadata" : {
+					"type" : "RefScenario.c_City"
+				},
+				"PostalCode" : "69124",
+				"CityName" : "Heidelberg"
+			},
+			"Country" : "Germany"
+		},
+		"Age" : 52,
+		"EntryDate" : "\/Date(915148800000)\/",
+		"ImageUrl" : "Employees('1')/$value"
+	}
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnlyWithAdditionalLink.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnlyWithAdditionalLink.json b/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnlyWithAdditionalLink.json
new file mode 100644
index 0000000..fb90c14
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonEmployeeContentOnlyWithAdditionalLink.json
@@ -0,0 +1,30 @@
+{
+	"d" : {
+		"EmployeeId" : "1",
+		"EmployeeName" : "Walter Winter",
+		"ManagerId" : "1",
+		"RoomId" : "1",
+		"TeamId" : "1",
+		"Location" : {
+			"__metadata" : {
+				"type" : "RefScenario.c_Location"
+			},
+			"City" : {
+				"__metadata" : {
+					"type" : "RefScenario.c_City"
+				},
+				"PostalCode" : "69124",
+				"CityName" : "Heidelberg"
+			},
+			"Country" : "Germany"
+		},
+		"Age" : 52,
+		"EntryDate" : "\/Date(915148800000)\/",
+		"ImageUrl" : "Employees('1')/$value",
+		"ne_Manager" : {
+			"__deferred" : {
+				"uri" : "http://host:8080/ReferenceScenario.svc/Managers('1')"
+			}
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnly.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnly.json b/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnly.json
new file mode 100644
index 0000000..f8c741a
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnly.json
@@ -0,0 +1,8 @@
+{
+	"d" : {
+		"Id" : "1",
+		"Name" : "Room 1",
+		"Seats" : 1,
+		"Version" : 1
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnlyWithAdditionalLink.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnlyWithAdditionalLink.json b/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnlyWithAdditionalLink.json
new file mode 100644
index 0000000..7a511b6
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoomContentOnlyWithAdditionalLink.json
@@ -0,0 +1,13 @@
+{
+	"d" : {
+		"Id" : "1",
+		"Name" : "Room 1",
+		"Seats" : 1,
+		"Version" : 1,
+		"nr_Building" : {
+			"__deferred" : {
+				"uri" : "http://host:8080/ReferenceScenario.svc/Buildings('1')"
+			}
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/RoomContentOnly.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/RoomContentOnly.xml b/odata2-lib/odata-core/src/test/resources/RoomContentOnly.xml
new file mode 100644
index 0000000..558e713
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/RoomContentOnly.xml
@@ -0,0 +1,28 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://host:8080/ReferenceScenario.svc/" m:etag="W/&quot;1&quot;">
+	<content type="application/xml">
+		<m:properties>
+			<d:Id>1</d:Id>
+			<d:Name>Room 1</d:Name>
+			<d:Seats>1</d:Seats>
+			<d:Version>1</d:Version>
+		</m:properties>
+	</content>
+</entry>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/6ac100f5/odata2-lib/odata-core/src/test/resources/RoomContentOnlyWithAdditionalLink.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/RoomContentOnlyWithAdditionalLink.xml b/odata2-lib/odata-core/src/test/resources/RoomContentOnlyWithAdditionalLink.xml
new file mode 100644
index 0000000..a7d039e
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/RoomContentOnlyWithAdditionalLink.xml
@@ -0,0 +1,29 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+         or more contributor license agreements.  See the NOTICE file
+         distributed with this work for additional information
+         regarding copyright ownership.  The ASF licenses this file
+         to you under the Apache License, Version 2.0 (the
+         "License"); you may not use this file except in compliance
+         with the License.  You may obtain a copy of the License at
+  
+           http://www.apache.org/licenses/LICENSE-2.0
+  
+         Unless required by applicable law or agreed to in writing,
+         software distributed under the License is distributed on an
+         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+         KIND, either express or implied.  See the License for the
+         specific language governing permissions and limitations
+         under the License.
+-->
+<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="http://host:8080/ReferenceScenario.svc/" m:etag="W/&quot;1&quot;">
+	<link href="Buildings('1')" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building" title="nr_Building" type="application/atom+xml;type=entry"/>
+	<content type="application/xml">
+		<m:properties>
+			<d:Id>1</d:Id>
+			<d:Name>Room 1</d:Name>
+			<d:Seats>1</d:Seats>
+			<d:Version>1</d:Version>
+		</m:properties>
+	</content>
+</entry>
\ No newline at end of file