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 2017/01/26 10:10:46 UTC
[2/2] olingo-odata2 git commit: [OLINGO-1054] Inline Consumer
Callback Data handling
[OLINGO-1054] Inline Consumer Callback Data handling
Signed-off-by: Christian Amend <ch...@sap.com>
Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/f24fc8bf
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/f24fc8bf
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/f24fc8bf
Branch: refs/heads/master
Commit: f24fc8bf42aa225afee2913e47423f11dc9fc237
Parents: adda9d5
Author: i050510 <ra...@sap.com>
Authored: Thu Dec 1 13:31:59 2016 +0530
Committer: Christian Amend <ch...@sap.com>
Committed: Thu Jan 26 11:06:21 2017 +0100
----------------------------------------------------------------------
.../odata2/api/ep/callback/ReadEntryResult.java | 11 +-
.../odata2/api/ep/callback/ReadFeedResult.java | 10 +-
.../core/ep/consumer/JsonEntryConsumer.java | 9 +-
.../core/ep/consumer/XmlEntryConsumer.java | 6 +-
.../odata2/core/ep/consumer/FeedCallback.java | 82 +++++++
.../core/ep/consumer/JsonEntryConsumerTest.java | 142 +++++++++++
.../core/ep/consumer/JsonFeedConsumerTest.java | 149 ++++++++++++
.../core/ep/consumer/XmlEntityConsumerTest.java | 141 +++++++++++
.../core/ep/consumer/XmlFeedConsumerTest.java | 151 ++++++++++++
.../resources/Employee_InlineRoomBuilding.xml | 71 ++++++
.../JsonEmployeeInlineRoomBuilding.json | 75 ++++++
.../JsonRoom_EmptyInlineEmployeesToTeam.json | 22 ++
.../JsonRoom_InlineEmployeesToTeam.json | 79 ++++++
.../JsonRoomsToEmployeesWithInlineTeams.json | 118 +++++++++
.../JsonRooms_InlineEmployeesTeams.json | 236 ++++++++++++++++++
...sonRooms_InlineEmployees_InlineBuilding.json | 236 ++++++++++++++++++
.../Room_EmptyInlineEmployeesToTeam.xml | 30 +++
.../resources/Room_InlineEmployeesToTeam.xml | 77 ++++++
.../RoomsToEmployeesWithInlineTeams.xml | 104 ++++++++
.../resources/Rooms_InlineEmployeesTeams.xml | 238 +++++++++++++++++++
.../Rooms_InlineEmployees_InlineBuildings.xml | 197 +++++++++++++++
21 files changed, 2176 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
index e6b8d8c..26968d2 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadEntryResult.java
@@ -35,7 +35,7 @@ import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
public class ReadEntryResult extends ReadResult {
private final ODataEntry entry;
-
+ private final String parentEntryId;
/**
* Constructor.
* Parameters <b>MUST NOT BE NULL</b>.
@@ -45,9 +45,10 @@ public class ReadEntryResult extends ReadResult {
* @param entry read entity as {@link ODataEntry}
*/
public ReadEntryResult(final EntityProviderReadProperties properties, final EdmNavigationProperty navigationProperty,
- final ODataEntry entry) {
+ final ODataEntry entry, final String entryMetadataId) {
super(properties, navigationProperty);
this.entry = entry;
+ this.parentEntryId = entryMetadataId;
}
@Override
@@ -64,4 +65,10 @@ public class ReadEntryResult extends ReadResult {
public String toString() {
return super.toString() + "\n\t" + entry.toString();
}
+ /**
+ * @return the rootEntryId
+ */
+ public String getParentEntryId() {
+ return parentEntryId;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
index 3e58609..011becf 100644
--- a/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
+++ b/odata2-lib/odata-api/src/main/java/org/apache/olingo/odata2/api/ep/callback/ReadFeedResult.java
@@ -35,6 +35,7 @@ import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
public class ReadFeedResult extends ReadResult {
private final ODataFeed feed;
+ private final String parentEntryId;
/**
* Constructor.
@@ -45,9 +46,10 @@ public class ReadFeedResult extends ReadResult {
* @param entry read entities as list of {@link org.apache.olingo.odata2.api.ep.entry.ODataEntry ODataEntry}
*/
public ReadFeedResult(final EntityProviderReadProperties properties, final EdmNavigationProperty navigationProperty,
- final ODataFeed entry) {
+ final ODataFeed entry, final String entryMetadataId) {
super(properties, navigationProperty);
feed = entry;
+ parentEntryId = entryMetadataId;
}
@Override
@@ -64,4 +66,10 @@ public class ReadFeedResult extends ReadResult {
public String toString() {
return super.toString() + "\n\t" + feed.toString();
}
+ /**
+ * @return the rootEntryId
+ */
+ public String getParentEntryId() {
+ return parentEntryId;
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
index 45726ba..fb4977b 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/JsonEntryConsumer.java
@@ -320,7 +320,8 @@ public class JsonEntryConsumer {
properties.put(navigationPropertyName, feed);
resultEntry.setContainsInlineEntry(true);
} else {
- ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty, feed);
+ ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty,
+ feed, entryMetadata.getId());
callback.handleReadFeed(result);
}
} else {
@@ -331,7 +332,8 @@ public class JsonEntryConsumer {
properties.put(navigationPropertyName, entry);
resultEntry.setContainsInlineEntry(true);
} else {
- ReadEntryResult result = new ReadEntryResult(inlineReadProperties, navigationProperty, entry);
+ ReadEntryResult result = new ReadEntryResult(inlineReadProperties, navigationProperty,
+ entry, entryMetadata.getId());
callback.handleReadEntry(result);
}
}
@@ -371,7 +373,8 @@ public class JsonEntryConsumer {
properties.put(navigationPropertyName, feed);
resultEntry.setContainsInlineEntry(true);
} else {
- ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty, feed);
+ ReadFeedResult result = new ReadFeedResult(inlineReadProperties, navigationProperty,
+ feed, entryMetadata.getId());
try {
callback.handleReadFeed(result);
} catch (final ODataApplicationException e) {
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
index a9d8ae1..962fc34 100644
--- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
+++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/ep/consumer/XmlEntryConsumer.java
@@ -405,10 +405,12 @@ public class XmlEntryConsumer {
try {
if (isFeed) {
- ReadFeedResult callbackInfo = new ReadFeedResult(readProperties, navigationProperty, (ODataFeed) content);
+ ReadFeedResult callbackInfo = new ReadFeedResult(readProperties, navigationProperty,
+ (ODataFeed) content, entryMetadata.getId());
callback.handleReadFeed(callbackInfo);
} else {
- ReadEntryResult callbackInfo = new ReadEntryResult(readProperties, navigationProperty, (ODataEntry) content);
+ ReadEntryResult callbackInfo = new ReadEntryResult(readProperties, navigationProperty,
+ (ODataEntry) content, entryMetadata.getId());
callback.handleReadEntry(callbackInfo);
}
} catch (ODataApplicationException e) {
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java
new file mode 100644
index 0000000..a8a9478
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/FeedCallback.java
@@ -0,0 +1,82 @@
+package org.apache.olingo.odata2.core.ep.consumer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.olingo.odata2.api.edm.EdmException;
+import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
+import org.apache.olingo.odata2.api.ep.callback.OnReadInlineContent;
+import org.apache.olingo.odata2.api.ep.callback.ReadEntryResult;
+import org.apache.olingo.odata2.api.ep.callback.ReadFeedResult;
+import org.apache.olingo.odata2.api.ep.callback.ReadResult;
+import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.exception.ODataApplicationException;
+
+public class FeedCallback implements OnReadInlineContent{
+
+ private static Map<String, Object> navigationProp = new HashMap<String, Object>();
+ private String id = "";
+
+ /**
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @return the navigationPropFeed
+ */
+ public Map<String, Object> getNavigationProperties() {
+ return navigationProp;
+ }
+
+ @Override
+ public EntityProviderReadProperties receiveReadProperties(EntityProviderReadProperties readProperties,
+ EdmNavigationProperty navigationProperty) throws ODataApplicationException {
+ Map<String, Object> typeMappings = new HashMap<String, Object>();
+ return EntityProviderReadProperties.init().addTypeMappings(typeMappings).callback(new FeedCallback()).build();
+ }
+
+ @Override
+ public void handleReadEntry(ReadEntryResult context) throws ODataApplicationException {
+ this.id = context.getParentEntryId();
+ handleEntry(context);
+
+ }
+
+ @Override
+ public void handleReadFeed(ReadFeedResult context) throws ODataApplicationException {
+ this.id = context.getParentEntryId();
+ handleFeed(context);
+
+ }
+
+ private void handleEntry(final ReadResult context) {
+ try {
+ String navigationPropertyName = context.getNavigationProperty().getName();
+ if (navigationPropertyName != null) {
+ navigationProp.put(navigationPropertyName + id, (ODataEntry) context.getResult());
+ } else {
+ throw new RuntimeException("Invalid title");
+ }
+ } catch (EdmException e) {
+ throw new RuntimeException("Invalid title");
+ }
+ }
+
+ private void handleFeed(final ReadFeedResult context) {
+ try {
+ String navigationPropertyName = context.getNavigationProperty().getName();
+ if (navigationPropertyName != null) {
+ navigationProp.put(navigationPropertyName + id, (ODataFeed) context.getResult());
+ } else {
+ throw new RuntimeException("Invalid title");
+ }
+ } catch (EdmException e) {
+ throw new RuntimeException("Invalid title");
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/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 4836fd3..4f0d385 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
@@ -29,6 +29,7 @@ import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
+import java.util.Map.Entry;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
@@ -36,6 +37,8 @@ import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
import org.apache.olingo.odata2.api.ep.entry.EntryMetadata;
import org.apache.olingo.odata2.api.ep.entry.MediaMetadata;
import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
+import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.testutil.mock.MockFacade;
import org.junit.Test;
@@ -345,4 +348,143 @@ public class JsonEntryConsumerTest extends AbstractConsumerTest {
InputStream contentBody = createContentAsStream(negativeJsonStart_2);
new JsonEntityConsumer().readEntry(entitySet, contentBody, DEFAULT_PROPERTIES);
}
+ /**
+ * Employee with inline entity Room with inline entity Buildings
+ * Scenario of 1:1:1 navigation
+ * E.g: Employees('1')?$expand=ne_Room/nr_Building
+ * @throws Exception
+ */
+ @Test
+ public void employeesEntryWithEmployeeToRoomToBuilding() throws Exception {
+ InputStream stream = getFileAsStream("JsonEmployeeInlineRoomBuilding.json");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ JsonEntityConsumer xec = new JsonEntityConsumer();
+ ODataEntry result =
+ xec.readEntry(entitySet, stream, readProperties);
+ assertNotNull(result);
+ assertEquals(9, result.getProperties().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, result);
+ assertEquals(10, result.getProperties().size());
+ assertEquals(5, ((ODataEntry)result.getProperties().get("ne_Room")).getProperties().size());
+ assertEquals(3, ((ODataEntry)((ODataEntry)result.getProperties().get("ne_Room")).getProperties()
+ .get("nr_Building")).getProperties().size());
+ }
+
+ /**
+ * Room has inline entity to Employees and has inline entry To Team
+ * Scenario of 1:n:1 navigation
+ * E.g: Rooms('1')?$expand=nr_Employees/ne_Team
+ * @throws Exception
+ */
+ @Test
+ public void RoomEntryWithInlineEmployeeInlineTeam() throws Exception {
+ InputStream stream = getFileAsStream("JsonRoom_InlineEmployeesToTeam.json");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ JsonEntityConsumer xec = new JsonEntityConsumer();
+ ODataEntry result =
+ xec.readEntry(entitySet, stream, readProperties);
+ assertNotNull(result);
+ assertEquals(4, result.getProperties().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, result);
+ assertEquals(5, result.getProperties().size());
+ for (ODataEntry employeeEntry : ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries()) {
+ assertEquals(10, employeeEntry.getProperties().size());
+ assertEquals(3, ((ODataEntry)employeeEntry.getProperties().get("ne_Team")).getProperties().size());
+ }
+ }
+ /**
+ * Room has empty inline entity to Employees and has inline entry To Team
+ * E.g: Rooms('10')?$expand=nr_Employees/ne_Team
+ * @throws Exception
+ */
+ @Test
+ public void RoomEntryWithEmptyInlineEmployeeInlineTeam() throws Exception {
+ InputStream stream = getFileAsStream("JsonRoom_EmptyInlineEmployeesToTeam.json");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ JsonEntityConsumer xec = new JsonEntityConsumer();
+ ODataEntry result =
+ xec.readEntry(entitySet, stream, readProperties);
+ assertNotNull(result);
+ assertEquals(4, result.getProperties().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, result);
+ assertEquals(5, result.getProperties().size());
+ assertEquals(0, ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries().size());
+ }
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataEntry entry) {
+ assertNotNull(entry);
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ entry.getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ entry.getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataFeed feed) {
+ assertNotNull(feed.getEntries());
+ List<ODataEntry> entries = feed.getEntries();
+ for (ODataEntry entry : entries) {
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
index 6495b73..0bad548 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/JsonFeedConsumerTest.java
@@ -26,17 +26,20 @@ import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import junit.framework.Assert;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.ep.EntityProviderException;
+import org.apache.olingo.odata2.api.ep.EntityProviderReadProperties;
import org.apache.olingo.odata2.api.ep.entry.DeletedEntryMetadata;
import org.apache.olingo.odata2.api.ep.entry.MediaMetadata;
import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
import org.apache.olingo.odata2.api.ep.feed.FeedMetadata;
import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.testutil.mock.MockFacade;
import org.junit.Test;
@@ -531,4 +534,150 @@ public class JsonFeedConsumerTest extends AbstractConsumerTest {
assertNull(mediaMetadata.getEtag());
assertNull(mediaMetadata.getSourceLink());
}
+ /**
+ * Room has an Inline Feed Employees and Employee has an inline Entry Team
+ * E.g: Rooms?$expand=nr_Employees/ne_Team
+ * Empty Inline entity is also part of payload
+ * @throws Exception
+ */
+ @Test
+ public void roomsFeedWithRoomInlineEmployeesWithTeams() throws Exception {
+ InputStream stream = getFileAsStream("JsonRooms_InlineEmployeesTeams.json");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ JsonEntityConsumer xec = new JsonEntityConsumer();
+ ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, stream, readProperties);
+ assertNotNull(feed);
+
+ assertEquals(3, feed.getEntries().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, feed);
+ for (ODataEntry entry : feed.getEntries()) {
+ assertEquals(5, entry.getProperties().size());
+ for (ODataEntry innerEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+ assertEquals(10, innerEntry.getProperties().size());
+ assertEquals(3, ((ODataEntry)innerEntry.getProperties().get("ne_Team")).getProperties().size());
+ }
+ }
+ }
+
+ /**
+ * Rooms has an inline feed Employees and Rooms has Inline entry Buildings
+ * E.g: Rooms?$expand=nr_Employees,nr_Building
+ * Empty Inline entity is also part of payload
+ * @throws Exception
+ */
+ @Test
+ public void roomsFeedWithRoomInlineEmployeesInlineBuildings() throws Exception {
+ InputStream stream = getFileAsStream("JsonRooms_InlineEmployees_InlineBuilding.json");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ JsonEntityConsumer xec = new JsonEntityConsumer();
+ ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, stream, readProperties);
+ assertNotNull(feed);
+ assertEquals(3, feed.getEntries().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, feed);
+ for (ODataEntry entry : feed.getEntries()) {
+ assertEquals(6, entry.getProperties().size());
+ for (ODataEntry employeeEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+ assertEquals(9, employeeEntry.getProperties().size());
+ }
+ assertEquals(3, ((ODataEntry)entry.getProperties().get("nr_Building")).getProperties().size());
+ }
+ }
+
+ /**
+ * Rooms navigate to Employees and has inline entry Teams
+ * E.g: Rooms('1')/nr_Employees?$expand=ne_Team
+ * @throws Exception
+ */
+ @Test
+ public void roomsFeedWithRoomsToEmployeesInlineTeams() throws Exception {
+ InputStream stream = getFileAsStream("JsonRoomsToEmployeesWithInlineTeams.json");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ JsonEntityConsumer xec = new JsonEntityConsumer();
+ ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, stream, readProperties);
+ assertNotNull(feed);
+ assertEquals(2, feed.getEntries().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, feed);
+ for (ODataEntry entry : feed.getEntries()) {
+ assertEquals(10, entry.getProperties().size());
+ assertEquals(3, ((ODataEntry)entry.getProperties().get("ne_Team")).getProperties().size());
+ }
+ }
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataEntry entry) {
+ assertNotNull(entry);
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ entry.getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ entry.getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataFeed feed) {
+ assertNotNull(feed.getEntries());
+ List<ODataEntry> entries = feed.getEntries();
+ for (ODataEntry entry : entries) {
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/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 2194619..b8ba340 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
@@ -31,6 +31,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
+import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -2511,4 +2512,144 @@ public class XmlEntityConsumerTest extends AbstractXmlConsumerTest {
Map<String, Object> properties = result.getProperties();
assertEquals(9, properties.size());
}
+ /**
+ * Employee with inline entity Room with inline entity Buildings
+ * Scenario of 1:1:1 navigation
+ * E.g: Employees('1')?$expand=ne_Rooms/nr_Buildings
+ * @throws Exception
+ */
+ @Test
+ public void employeesEntryWithEmployeeToRoomToBuilding() throws Exception {
+ InputStream stream = getFileAsStream("Employee_InlineRoomBuilding.xml");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees");
+ XmlEntityConsumer xec = new XmlEntityConsumer();
+ ODataEntry result =
+ xec.readEntry(entitySet, stream, readProperties);
+ assertNotNull(result);
+ assertEquals(9, result.getProperties().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, result);
+ assertEquals(10, result.getProperties().size());
+ assertEquals(5, ((ODataEntry)result.getProperties().get("ne_Room")).getProperties().size());
+ assertEquals(3, ((ODataEntry)((ODataEntry)result.getProperties().get("ne_Room")).getProperties()
+ .get("nr_Building")).getProperties().size());
+ }
+
+ /**
+ * Room has inline entity to Employees and has inline entry To Team
+ * Scenario of 1:n:1 navigation
+ * E.g: Rooms('1')?$expand=nr_Employees/ne_Team
+ * @throws Exception
+ */
+ @Test
+ public void RoomEntryWithInlineEmployeeInlineTeam() throws Exception {
+ InputStream stream = getFileAsStream("Room_InlineEmployeesToTeam.xml");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ XmlEntityConsumer xec = new XmlEntityConsumer();
+ ODataEntry result =
+ xec.readEntry(entitySet, stream, readProperties);
+ assertNotNull(result);
+ assertEquals(4, result.getProperties().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, result);
+ assertEquals(5, result.getProperties().size());
+ for (ODataEntry employeeEntry : ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries()) {
+ assertEquals(10, employeeEntry.getProperties().size());
+ assertEquals(3, ((ODataEntry)employeeEntry.getProperties().get("ne_Team")).getProperties().size());
+ }
+ }
+
+ /**
+ * Room has empty inline entity to Employees and has inline entry To Team
+ * E.g: Rooms('10')?$expand=nr_Employees/ne_Team
+ * @throws Exception
+ */
+ @Test
+ public void RoomEntryWithEmptyInlineEmployeeInlineTeam() throws Exception {
+ InputStream stream = getFileAsStream("Room_EmptyInlineEmployeesToTeam.xml");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms");
+ XmlEntityConsumer xec = new XmlEntityConsumer();
+ ODataEntry result =
+ xec.readEntry(entitySet, stream, readProperties);
+ assertNotNull(result);
+ assertEquals(4, result.getProperties().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, result);
+ assertEquals(5, result.getProperties().size());
+ assertEquals(0, ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries().size());
+ }
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataEntry entry) {
+ assertNotNull(entry);
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ entry.getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ entry.getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataFeed feed) {
+ assertNotNull(feed.getEntries());
+ List<ODataEntry> entries = feed.getEntries();
+ for (ODataEntry entry : entries) {
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
index ec7ce71..8d22dd7 100644
--- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
+++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/ep/consumer/XmlFeedConsumerTest.java
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertNotNull;
import java.io.InputStream;
import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import junit.framework.Assert;
@@ -35,6 +37,7 @@ import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
import org.apache.olingo.odata2.api.ep.feed.FeedMetadata;
import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed;
import org.apache.olingo.odata2.api.ep.feed.ODataFeed;
+import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.testutil.mock.MockFacade;
import org.junit.Test;
@@ -180,4 +183,152 @@ public class XmlFeedConsumerTest extends AbstractXmlConsumerTest {
assertEquals(1, deltaFeed.getEntries().size());
assertEquals(1, deltaFeed.getDeletedEntries().size());
}
+ /**
+ * Room has an Inline Feed Employees and Employee has an inline Entry Team
+ * E.g: Rooms?$expand=nr_Employees/ne_Team
+ * Empty Inline entity is also part of payload
+ * @throws Exception
+ */
+ @Test
+ public void roomsFeedWithRoomInlineEmployeesWithTeams() throws Exception {
+ InputStream stream = getFileAsStream("Rooms_InlineEmployeesTeams.xml");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ ODataFeed feed =
+ EntityProvider.readFeed("application/atom+xml", MockFacade.getMockEdm().getDefaultEntityContainer()
+ .getEntitySet(
+ "Rooms"), stream, readProperties);
+ assertNotNull(feed);
+ assertEquals(3, feed.getEntries().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, feed);
+ for (ODataEntry entry : feed.getEntries()) {
+ assertEquals(5, entry.getProperties().size());
+ for (ODataEntry innerEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+ assertEquals(10, innerEntry.getProperties().size());
+ assertEquals(3, ((ODataEntry)innerEntry.getProperties().get("ne_Team")).getProperties().size());
+ }
+ }
+ }
+
+ /**
+ * Rooms has an inline feed Employees and Rooms has Inline entry Buildings
+ * E.g: Rooms?$expand=nr_Employees,nr_Building
+ * @throws Exception
+ */
+ @Test
+ public void roomsFeedWithRoomInlineEmployeesInlineBuildings() throws Exception {
+ InputStream stream = getFileAsStream("Rooms_InlineEmployees_InlineBuildings.xml");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ ODataFeed feed =
+ EntityProvider.readFeed("application/atom+xml", MockFacade.getMockEdm().getDefaultEntityContainer()
+ .getEntitySet(
+ "Rooms"), stream, readProperties);
+ assertNotNull(feed);
+ assertEquals(2, feed.getEntries().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, feed);
+ for (ODataEntry entry : feed.getEntries()) {
+ assertEquals(6, entry.getProperties().size());
+ for (ODataEntry employeeEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) {
+ assertEquals(9, employeeEntry.getProperties().size());
+ }
+ assertEquals(3, ((ODataEntry)entry.getProperties().get("nr_Building")).getProperties().size());
+ }
+ }
+
+ /**
+ * Rooms navigate to Employees and has inline entry Teams
+ * E.g: Rooms('1')/nr_Employees?$expand=ne_Team
+ * @throws Exception
+ */
+ @Test
+ public void roomsFeedWithRoomsToEmployeesInlineTeams() throws Exception {
+ InputStream stream = getFileAsStream("RoomsToEmployeesWithInlineTeams.xml");
+ assertNotNull(stream);
+ FeedCallback callback = new FeedCallback();
+
+ EntityProviderReadProperties readProperties = EntityProviderReadProperties.init()
+ .mergeSemantic(false).callback(callback).build();
+
+ ODataFeed feed =
+ EntityProvider.readFeed("application/atom+xml", MockFacade.getMockEdm().getDefaultEntityContainer()
+ .getEntitySet(
+ "Employees"), stream, readProperties);
+ assertNotNull(feed);
+ assertEquals(2, feed.getEntries().size());
+
+ Map<String, Object> inlineEntries = callback.getNavigationProperties();
+ getExpandedData(inlineEntries, feed);
+ for (ODataEntry entry : feed.getEntries()) {
+ assertEquals(10, entry.getProperties().size());
+ assertEquals(3, ((ODataEntry)entry.getProperties().get("ne_Team")).getProperties().size());
+ }
+ }
+
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataEntry entry) {
+ assertNotNull(entry);
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ entry.getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ entry.getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+
+ /**
+ * @param inlineEntries
+ * @param feed
+ * @param entry
+ */
+ private void getExpandedData(Map<String, Object> inlineEntries, ODataFeed feed) {
+ assertNotNull(feed.getEntries());
+ List<ODataEntry> entries = feed.getEntries();
+ for (ODataEntry entry : entries) {
+ Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks();
+ for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) {
+ assertNotNull(expand.getKey());
+ if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) {
+ if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) {
+ ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerFeed);
+ getExpandedData(inlineEntries, innerFeed);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerFeed);
+ } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) {
+ ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId());
+ assertNotNull(innerEntry);
+ getExpandedData(inlineEntries, innerEntry);
+ feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerEntry);
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml b/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml
new file mode 100644
index 0000000..37ca6e8
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/Employee_InlineRoomBuilding.xml
@@ -0,0 +1,71 @@
+<?xml version='1.0' encoding='utf-8'?>
+<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://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/">
+ <id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')</id>
+ <title type="text">Walter Winter</title>
+ <updated>1999-01-01T00:00:00Z</updated>
+ <category term="RefScenario.Employee" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
+ <link href="Employees('1')" rel="edit" title="Employee"/>
+ <link href="Employees('1')/$value" rel="edit-media" type="image/jpeg"/>
+ <link href="Employees('1')/ne_Manager" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager" title="ne_Manager" type="application/atom+xml;type=entry"/>
+ <link href="Employees('1')/ne_Team" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team" title="ne_Team" type="application/atom+xml;type=entry"/>
+ <link href="Employees('1')/ne_Room" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room" title="ne_Room" type="application/atom+xml;type=entry">
+ <m:inline>
+ <entry xml:base="http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/" m:etag="W/"1"">
+ <id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')</id>
+ <title type="text">Room 1</title>
+ <updated>2016-11-30T09:44:42.419+05:30</updated>
+ <category term="RefScenario.Room" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
+ <link href="Rooms('1')" rel="edit" title="Room"/>
+ <link href="Rooms('1')/nr_Employees" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees" title="nr_Employees" type="application/atom+xml;type=feed"/>
+ <link href="Rooms('1')/nr_Building" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Building" title="nr_Building" type="application/atom+xml;type=entry">
+ <m:inline>
+ <entry xml:base="http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/">
+ <id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')</id>
+ <title type="text">Buildings</title>
+ <updated>2016-11-30T09:44:42.426+05:30</updated>
+ <author>
+ <name>Building 1</name>
+ </author>
+ <category term="RefScenario.Building" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
+ <link href="Buildings('1')" rel="edit" title="Building"/>
+ <link href="Buildings('1')/nb_Rooms" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nb_Rooms" title="nb_Rooms" type="application/atom+xml;type=feed"/>
+ <content type="application/xml">
+ <m:properties>
+ <d:Id>1</d:Id>
+ <d:Name>Building 1</d:Name>
+ <d:Image m:null="true"/>
+ </m:properties>
+ </content>
+ </entry>
+ </m:inline>
+ </link>
+ <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>
+ </m:inline>
+ </link>
+ <content type="image/jpeg" src="Employees('1')/$value"/>
+ <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/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json b/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json
new file mode 100644
index 0000000..8f35315
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonEmployeeInlineRoomBuilding.json
@@ -0,0 +1,75 @@
+{
+ "d": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+ },
+ "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://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Team"
+ }
+ },
+ "ne_Room": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"1\""
+ },
+ "Id": "1",
+ "Name": "Room 1",
+ "Seats": 1,
+ "Version": 1,
+ "nr_Employees": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')/nr_Employees"
+ }
+ },
+ "nr_Building": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+ "type": "RefScenario.Building"
+ },
+ "Id": "1",
+ "Name": "Building 1",
+ "Image": null,
+ "nb_Rooms": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')/nb_Rooms"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json b/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json
new file mode 100644
index 0000000..8495fab
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoom_EmptyInlineEmployeesToTeam.json
@@ -0,0 +1,22 @@
+{
+ "d": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"1\""
+ },
+ "Id": "10",
+ "Name": "Room 10",
+ "Seats": 6,
+ "Version": 1,
+ "nr_Employees": {
+ "results": []
+ },
+ "nr_Building": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')/nr_Building"
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json b/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json
new file mode 100644
index 0000000..979e39a
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoom_InlineEmployeesToTeam.json
@@ -0,0 +1,79 @@
+{
+ "d": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"1\""
+ },
+ "Id": "1",
+ "Name": "Room 1",
+ "Seats": 1,
+ "Version": 1,
+ "nr_Employees": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+ },
+ "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://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "type": "RefScenario.Team"
+ },
+ "Id": "1",
+ "Name": "Team 1",
+ "isScrumTeam": false,
+ "nt_Employees": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')/nt_Employees"
+ }
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Room"
+ }
+ }
+ }
+ ]
+ },
+ "nr_Building": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')/nr_Building"
+ }
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json b/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json
new file mode 100644
index 0000000..671dbb6
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRoomsToEmployeesWithInlineTeams.json
@@ -0,0 +1,118 @@
+{
+ "d": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value"
+ },
+ "EmployeeId": "2",
+ "EmployeeName": "Frederic Fall",
+ "ManagerId": "1",
+ "RoomId": "2",
+ "TeamId": "1",
+ "Location": {
+ "__metadata": {
+ "type": "RefScenario.c_Location"
+ },
+ "City": {
+ "__metadata": {
+ "type": "RefScenario.c_City"
+ },
+ "PostalCode": "69190",
+ "CityName": "Walldorf"
+ },
+ "Country": "Germany"
+ },
+ "Age": 32,
+ "EntryDate": "/Date(1057017600000)/",
+ "ImageUrl": "Employees('2')/$value",
+ "ne_Manager": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "type": "RefScenario.Team"
+ },
+ "Id": "1",
+ "Name": "Team 1",
+ "isScrumTeam": false,
+ "nt_Employees": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')/nt_Employees"
+ }
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Room"
+ }
+ }
+ },
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/$value"
+ },
+ "EmployeeId": "6",
+ "EmployeeName": "Susan Bay",
+ "ManagerId": "1",
+ "RoomId": "2",
+ "TeamId": "3",
+ "Location": {
+ "__metadata": {
+ "type": "RefScenario.c_Location"
+ },
+ "City": {
+ "__metadata": {
+ "type": "RefScenario.c_City"
+ },
+ "PostalCode": "69190",
+ "CityName": "Walldorf"
+ },
+ "Country": "Germany"
+ },
+ "Age": 29,
+ "EntryDate": "/Date(1291161600000)/",
+ "ImageUrl": "Employees('6')/$value",
+ "ne_Manager": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('3')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('3')",
+ "type": "RefScenario.Team"
+ },
+ "Id": "3",
+ "Name": "Team 3",
+ "isScrumTeam": false,
+ "nt_Employees": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('3')/nt_Employees"
+ }
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('6')/ne_Room"
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json
new file mode 100644
index 0000000..b466ad2
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployeesTeams.json
@@ -0,0 +1,236 @@
+{
+ "d": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"1\""
+ },
+ "Id": "1",
+ "Name": "Room 1",
+ "Seats": 1,
+ "Version": 1,
+ "nr_Employees": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+ },
+ "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://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "type": "RefScenario.Team"
+ },
+ "Id": "1",
+ "Name": "Team 1",
+ "isScrumTeam": false,
+ "nt_Employees": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')/nt_Employees"
+ }
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Room"
+ }
+ }
+ }
+ ]
+ },
+ "nr_Building": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')/nr_Building"
+ }
+ }
+ },
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"1\""
+ },
+ "Id": "10",
+ "Name": "Room 10",
+ "Seats": 6,
+ "Version": 1,
+ "nr_Employees": {
+ "results": []
+ },
+ "nr_Building": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')/nr_Building"
+ }
+ }
+ },
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"2\""
+ },
+ "Id": "2",
+ "Name": "Room 2",
+ "Seats": 5,
+ "Version": 2,
+ "nr_Employees": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value"
+ },
+ "EmployeeId": "2",
+ "EmployeeName": "Frederic Fall",
+ "ManagerId": "1",
+ "RoomId": "2",
+ "TeamId": "1",
+ "Location": {
+ "__metadata": {
+ "type": "RefScenario.c_Location"
+ },
+ "City": {
+ "__metadata": {
+ "type": "RefScenario.c_City"
+ },
+ "PostalCode": "69190",
+ "CityName": "Walldorf"
+ },
+ "Country": "Germany"
+ },
+ "Age": 32,
+ "EntryDate": "/Date(1057017600000)/",
+ "ImageUrl": "Employees('2')/$value",
+ "ne_Manager": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "type": "RefScenario.Team"
+ },
+ "Id": "1",
+ "Name": "Team 1",
+ "isScrumTeam": false,
+ "nt_Employees": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')/nt_Employees"
+ }
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Room"
+ }
+ }
+ },
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/$value"
+ },
+ "EmployeeId": "3",
+ "EmployeeName": "Jonathan Smith",
+ "ManagerId": "1",
+ "RoomId": "2",
+ "TeamId": "1",
+ "Location": {
+ "__metadata": {
+ "type": "RefScenario.c_Location"
+ },
+ "City": {
+ "__metadata": {
+ "type": "RefScenario.c_City"
+ },
+ "PostalCode": "69190",
+ "CityName": "Walldorf"
+ },
+ "Country": "Germany"
+ },
+ "Age": 56,
+ "EntryDate": null,
+ "ImageUrl": "Employees('3')/$value",
+ "ne_Manager": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')",
+ "type": "RefScenario.Team"
+ },
+ "Id": "1",
+ "Name": "Team 1",
+ "isScrumTeam": false,
+ "nt_Employees": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Teams('1')/nt_Employees"
+ }
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Room"
+ }
+ }
+ }
+ ]
+ },
+ "nr_Building": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')/nr_Building"
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json
new file mode 100644
index 0000000..3d1747f
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/JsonRooms_InlineEmployees_InlineBuilding.json
@@ -0,0 +1,236 @@
+{
+ "d": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('1')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"1\""
+ },
+ "Id": "1",
+ "Name": "Room 1",
+ "Seats": 1,
+ "Version": 1,
+ "nr_Employees": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/$value"
+ },
+ "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://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Team"
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('1')/ne_Room"
+ }
+ }
+ }
+ ]
+ },
+ "nr_Building": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')",
+ "type": "RefScenario.Building"
+ },
+ "Id": "1",
+ "Name": "Building 1",
+ "Image": null,
+ "nb_Rooms": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('1')/nb_Rooms"
+ }
+ }
+ }
+ },
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"1\""
+ },
+ "Id": "10",
+ "Name": "Room 10",
+ "Seats": 6,
+ "Version": 1,
+ "nr_Employees": {
+ "results": []
+ },
+ "nr_Building": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('3')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('3')",
+ "type": "RefScenario.Building"
+ },
+ "Id": "3",
+ "Name": "Building 3",
+ "Image": null,
+ "nb_Rooms": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('3')/nb_Rooms"
+ }
+ }
+ }
+ },
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('2')",
+ "type": "RefScenario.Room",
+ "etag": "W/\"2\""
+ },
+ "Id": "2",
+ "Name": "Room 2",
+ "Seats": 5,
+ "Version": 2,
+ "nr_Employees": {
+ "results": [
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/$value"
+ },
+ "EmployeeId": "2",
+ "EmployeeName": "Frederic Fall",
+ "ManagerId": "1",
+ "RoomId": "2",
+ "TeamId": "1",
+ "Location": {
+ "__metadata": {
+ "type": "RefScenario.c_Location"
+ },
+ "City": {
+ "__metadata": {
+ "type": "RefScenario.c_City"
+ },
+ "PostalCode": "69190",
+ "CityName": "Walldorf"
+ },
+ "Country": "Germany"
+ },
+ "Age": 32,
+ "EntryDate": "/Date(1057017600000)/",
+ "ImageUrl": "Employees('2')/$value",
+ "ne_Manager": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Team"
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('2')/ne_Room"
+ }
+ }
+ },
+ {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')",
+ "type": "RefScenario.Employee",
+ "content_type": "image/jpeg",
+ "media_src": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/$value",
+ "edit_media": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/$value"
+ },
+ "EmployeeId": "3",
+ "EmployeeName": "Jonathan Smith",
+ "ManagerId": "1",
+ "RoomId": "2",
+ "TeamId": "1",
+ "Location": {
+ "__metadata": {
+ "type": "RefScenario.c_Location"
+ },
+ "City": {
+ "__metadata": {
+ "type": "RefScenario.c_City"
+ },
+ "PostalCode": "69190",
+ "CityName": "Walldorf"
+ },
+ "Country": "Germany"
+ },
+ "Age": 56,
+ "EntryDate": null,
+ "ImageUrl": "Employees('3')/$value",
+ "ne_Manager": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Manager"
+ }
+ },
+ "ne_Team": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Team"
+ }
+ },
+ "ne_Room": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees('3')/ne_Room"
+ }
+ }
+ }
+ ]
+ },
+ "nr_Building": {
+ "__metadata": {
+ "id": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('2')",
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('2')",
+ "type": "RefScenario.Building"
+ },
+ "Id": "2",
+ "Name": "Building 2",
+ "Image": null,
+ "nb_Rooms": {
+ "__deferred": {
+ "uri": "http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Buildings('2')/nb_Rooms"
+ }
+ }
+ }
+ }
+ ]
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/f24fc8bf/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml
----------------------------------------------------------------------
diff --git a/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml b/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml
new file mode 100644
index 0000000..6ec35fe
--- /dev/null
+++ b/odata2-lib/odata-core/src/test/resources/Room_EmptyInlineEmployeesToTeam.xml
@@ -0,0 +1,30 @@
+<?xml version='1.0' encoding='utf-8'?>
+<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://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/" m:etag="W/"1"">
+ <id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Rooms('10')</id>
+ <title type="text">Room 10</title>
+ <updated>2016-11-30T14:30:58.658+05:30</updated>
+ <category term="RefScenario.Room" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/>
+ <link href="Rooms('10')" rel="edit" title="Room"/>
+ <link href="Rooms('10')/nr_Employees" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/nr_Employees" title="nr_Employees" type="application/atom+xml;type=feed">
+ <m:inline>
+ <feed xml:base="http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/">
+ <id>http://localhost:8080/olingo-odata2-ref-web/ReferenceScenario.svc/Employees</id>
+ <title type="text">Employees</title>
+ <updated>2016-11-30T14:30:58.658+05:30</updated>
+ <author>
+ <name/>
+ </author>
+ <link href="Rooms('10')/nr_Employees" rel="self" title="Employees"/>
+ </feed>
+ </m:inline>
+ </link>
+ <link href="Rooms('10')/nr_Building" 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>10</d:Id>
+ <d:Name>Room 10</d:Name>
+ <d:Seats>6</d:Seats>
+ <d:Version>1</d:Version>
+ </m:properties>
+ </content>
+</entry>
\ No newline at end of file