olingo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chri...@apache.org
Subject olingo-odata4 git commit: [OLINGO-988] Prevent duplicate ExpandItems in ExpandTreeBuilder
Date Tue, 26 Jul 2016 08:28:10 GMT
Repository: olingo-odata4
Updated Branches:
  refs/heads/master 22a21a28e -> 44d6f5a17


[OLINGO-988] Prevent duplicate ExpandItems in ExpandTreeBuilder


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

Branch: refs/heads/master
Commit: 44d6f5a1714809d89162ec52a8f3846aa19419c2
Parents: 22a21a2
Author: Christian Amend <christian.amend@sap.com>
Authored: Tue Jul 26 10:27:25 2016 +0200
Committer: Christian Amend <christian.amend@sap.com>
Committed: Tue Jul 26 10:27:25 2016 +0200

----------------------------------------------------------------------
 .../deserializer/helper/ExpandTreeBuilder.java  |  4 +
 .../helper/ExpandTreeBuilderImpl.java           | 53 ++++++------
 .../json/ODataJsonDeserializer.java             | 91 +++++++++-----------
 .../json/ODataDeserializerDeepInsertTest.java   | 58 +++++++++++++
 .../json/ODataJsonDeserializerEntityTest.java   |  7 ++
 .../test/resources/UnbalancedESAllPrimFeed.json | 23 +++++
 .../resources/UnbalancedESAllPrimFeed2.json     | 24 ++++++
 7 files changed, 185 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/44d6f5a1/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
index 882213c..afa8d70 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilder.java
@@ -19,13 +19,17 @@
 package org.apache.olingo.server.core.deserializer.helper;
 
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
 import org.apache.olingo.server.core.uri.UriInfoImpl;
 import org.apache.olingo.server.core.uri.UriResourceNavigationPropertyImpl;
 import org.apache.olingo.server.core.uri.queryoption.ExpandItemImpl;
 
 public abstract class ExpandTreeBuilder {
+  
   public abstract ExpandTreeBuilder expand(EdmNavigationProperty edmNavigationProperty);
 
+  public abstract ExpandOption build();
+  
   protected ExpandItemImpl buildExpandItem(final EdmNavigationProperty edmNavigationProperty)
{
     return new ExpandItemImpl()
         .setResourcePath(new UriInfoImpl()

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/44d6f5a1/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilderImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilderImpl.java
b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilderImpl.java
index b0287ff..4232f98 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilderImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/helper/ExpandTreeBuilderImpl.java
@@ -18,6 +18,9 @@
  */
 package org.apache.olingo.server.core.deserializer.helper;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
 import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
 import org.apache.olingo.server.core.uri.queryoption.ExpandItemImpl;
@@ -25,43 +28,41 @@ import org.apache.olingo.server.core.uri.queryoption.ExpandOptionImpl;
 
 public class ExpandTreeBuilderImpl extends ExpandTreeBuilder {
 
+  private final Map<String, ExpandTreeBuilder> childBuilderCache = new HashMap<String,
ExpandTreeBuilder>();
+  private final ExpandItemImpl parentItem;
   private ExpandOptionImpl expandOption = null;
 
+  private ExpandTreeBuilderImpl(final ExpandItemImpl parentItem) {
+    this.parentItem = parentItem;
+  }
+  
+  
   @Override
   public ExpandTreeBuilder expand(final EdmNavigationProperty edmNavigationProperty) {
-    ExpandItemImpl expandItem = buildExpandItem(edmNavigationProperty);
-
     if (expandOption == null) {
       expandOption = new ExpandOptionImpl();
+      if(parentItem != null && parentItem.getExpandOption() == null){
+        parentItem.setSystemQueryOption(expandOption);
+      }
     }
-    expandOption.addExpandItem(expandItem);
-
-    return new ExpandTreeBuilderInner(expandItem);
+    
+    ExpandTreeBuilder builder = childBuilderCache.get(edmNavigationProperty.getName());
+    if(builder == null){
+      ExpandItemImpl expandItem = buildExpandItem(edmNavigationProperty);
+      expandOption.addExpandItem(expandItem);
+      builder = new ExpandTreeBuilderImpl(expandItem);
+      childBuilderCache.put(edmNavigationProperty.getName(), builder);
+    }
+    
+    return builder;
   }
 
+  @Override
   public ExpandOption build() {
     return expandOption;
   }
-
-  private class ExpandTreeBuilderInner extends ExpandTreeBuilder {
-    private ExpandItemImpl parent;
-
-    public ExpandTreeBuilderInner(final ExpandItemImpl expandItem) {
-      parent = expandItem;
-    }
-
-    @Override
-    public ExpandTreeBuilder expand(final EdmNavigationProperty edmNavigationProperty) {
-      if (parent.getExpandOption() == null) {
-        final ExpandOptionImpl expandOption = new ExpandOptionImpl();
-        parent.setSystemQueryOption(expandOption);
-      }
-
-      final ExpandItemImpl expandItem = buildExpandItem(edmNavigationProperty);
-      ((ExpandOptionImpl) parent.getExpandOption()).addExpandItem(expandItem);
-
-      return new ExpandTreeBuilderInner(expandItem);
-    }
-
+  
+  public static ExpandTreeBuilder create(){
+    return new ExpandTreeBuilderImpl(null);
   }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/44d6f5a1/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
index de1fa39..3398dc7 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializer.java
@@ -134,7 +134,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
           throw new DeserializerException("Nested Arrays and primitive values are not allowed
for an entity value.",
               DeserializerException.MessageKeys.INVALID_ENTITY);
         }
-        EdmEntityType derivedEdmEntityType = (EdmEntityType)getDerivedType(edmEntityType,
arrayElement);
+        EdmEntityType derivedEdmEntityType = (EdmEntityType) getDerivedType(edmEntityType,
arrayElement);
         entities.add(consumeEntityNode(derivedEdmEntityType, (ObjectNode) arrayElement, expandBuilder));
       }
       return entities;
@@ -149,9 +149,9 @@ public class ODataJsonDeserializer implements ODataDeserializer {
       throws DeserializerException {
     try {
       final ObjectNode tree = parseJsonTree(stream);
-      final ExpandTreeBuilderImpl expandBuilder = new ExpandTreeBuilderImpl();
+      final ExpandTreeBuilder expandBuilder = ExpandTreeBuilderImpl.create();
 
-      EdmEntityType derivedEdmEntityType = (EdmEntityType)getDerivedType(edmEntityType, tree);
+      EdmEntityType derivedEdmEntityType = (EdmEntityType) getDerivedType(edmEntityType,
tree);
 
       return DeserializerResultImpl.with().entity(consumeEntityNode(derivedEdmEntityType,
tree, expandBuilder))
           .expandOption(expandBuilder.build())
@@ -279,8 +279,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
   public Parameter parameter(final String content, final EdmParameter parameter) throws DeserializerException
{
     try {
       JsonParser parser = new JsonFactory(new ObjectMapper()
-      .configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true))
-      .createParser(content);
+          .configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true))
+              .createParser(content);
       JsonNode node = parser.getCodec().readTree(parser);
       if (node == null) {
         throw new DeserializerException("Invalid JSON syntax.",
@@ -384,30 +384,29 @@ public class ODataJsonDeserializer implements ODataDeserializer {
       final EdmNavigationProperty edmNavigationProperty) throws DeserializerException {
     Link link = new Link();
     link.setTitle(navigationPropertyName);
-    final ExpandTreeBuilder childExpandBuilder = (expandBuilder != null) ?
-        expandBuilder.expand(edmNavigationProperty) : null;
-        EdmEntityType derivedEdmEntityType = (EdmEntityType)getDerivedType(
-            edmNavigationProperty.getType(), jsonNode);
-        if (jsonNode.isArray() && edmNavigationProperty.isCollection()) {
-          link.setType(Constants.ENTITY_SET_NAVIGATION_LINK_TYPE);
-          EntityCollection inlineEntitySet = new EntityCollection();
-          inlineEntitySet.getEntities().addAll(
-              consumeEntitySetArray(derivedEdmEntityType, jsonNode, childExpandBuilder));
-          link.setInlineEntitySet(inlineEntitySet);
-        } else if (!jsonNode.isArray() && (!jsonNode.isValueNode() || jsonNode.isNull())
-            && !edmNavigationProperty.isCollection()) {
-          link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
-          if (!jsonNode.isNull()) {
-            Entity inlineEntity = consumeEntityNode(derivedEdmEntityType, (ObjectNode) jsonNode,
-                childExpandBuilder);
-            link.setInlineEntity(inlineEntity);
-          }
-        } else {
-          throw new DeserializerException("Invalid value: " + jsonNode.getNodeType()
-              + " for expanded navigation property: " + navigationPropertyName,
-              MessageKeys.INVALID_VALUE_FOR_NAVIGATION_PROPERTY, navigationPropertyName);
-        }
-        return link;
+    final ExpandTreeBuilder childExpandBuilder = (expandBuilder != null) ? expandBuilder.expand(edmNavigationProperty)
+        : null;
+    EdmEntityType derivedEdmEntityType = (EdmEntityType) getDerivedType(
+        edmNavigationProperty.getType(), jsonNode);
+    if (jsonNode.isArray() && edmNavigationProperty.isCollection()) {
+      link.setType(Constants.ENTITY_SET_NAVIGATION_LINK_TYPE);
+      EntityCollection inlineEntitySet = new EntityCollection();
+      inlineEntitySet.getEntities().addAll(
+          consumeEntitySetArray(derivedEdmEntityType, jsonNode, childExpandBuilder));
+      link.setInlineEntitySet(inlineEntitySet);
+    } else if (!jsonNode.isArray() && (!jsonNode.isValueNode() || jsonNode.isNull())
+        && !edmNavigationProperty.isCollection()) {
+      link.setType(Constants.ENTITY_NAVIGATION_LINK_TYPE);
+      if (!jsonNode.isNull()) {
+        Entity inlineEntity = consumeEntityNode(derivedEdmEntityType, (ObjectNode) jsonNode,
childExpandBuilder);
+        link.setInlineEntity(inlineEntity);
+      }
+    } else {
+      throw new DeserializerException("Invalid value: " + jsonNode.getNodeType()
+          + " for expanded navigation property: " + navigationPropertyName,
+          MessageKeys.INVALID_VALUE_FOR_NAVIGATION_PROPERTY, navigationPropertyName);
+    }
+    return link;
   }
 
   private Link consumeBindingLink(final String key, final JsonNode jsonNode, final EdmEntityType
edmEntityType)
@@ -477,7 +476,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
   private void consumePropertySingleNode(final String name, final EdmType type,
       final boolean isNullable, final Integer maxLength, final Integer precision, final Integer
scale,
       final boolean isUnicode, final EdmMapping mapping, final JsonNode jsonNode, final Property
property)
-          throws DeserializerException {
+      throws DeserializerException {
     switch (type.getKind()) {
     case PRIMITIVE:
     case DEFINITION:
@@ -504,7 +503,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
 
   private Object readComplexNode(final String name, final EdmType type, final boolean isNullable,
       final JsonNode jsonNode)
-          throws DeserializerException {
+      throws DeserializerException {
     // read and add all complex properties
     ComplexValue value = readComplexValue(name, type, isNullable, jsonNode);
 
@@ -520,7 +519,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
   private void consumePropertyCollectionNode(final String name, final EdmType type,
       final boolean isNullable, final Integer maxLength, final Integer precision, final Integer
scale,
       final boolean isUnicode, final EdmMapping mapping, final JsonNode jsonNode, final Property
property)
-          throws DeserializerException {
+      throws DeserializerException {
     if (!jsonNode.isArray()) {
       throw new DeserializerException("Value for property: " + name + " must be an array
but is not.",
           DeserializerException.MessageKeys.INVALID_JSON_TYPE_FOR_PROPERTY, name);
@@ -537,10 +536,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
             isNullable, maxLength, precision, scale, isUnicode, mapping, arrayElement);
         valueArray.add(value);
       }
-      property.setValue(type.getKind() == EdmTypeKind.ENUM ?
-          ValueType.COLLECTION_ENUM :
-          ValueType.COLLECTION_PRIMITIVE,
-            valueArray);
+      property.setValue(type.getKind() == EdmTypeKind.ENUM ? ValueType.COLLECTION_ENUM :
ValueType.COLLECTION_PRIMITIVE,
+          valueArray);
       break;
     case COMPLEX:
       while (iterator.hasNext()) {
@@ -631,14 +628,10 @@ public class ODataJsonDeserializer implements ODataDeserializer {
    */
   private Class<?> getJavaClassForPrimitiveType(final EdmMapping mapping, final EdmPrimitiveType
type) {
     final EdmPrimitiveType edmPrimitiveType =
-        type.getKind() == EdmTypeKind.ENUM ?
-            ((EdmEnumType) type).getUnderlyingType() :
-            type.getKind() == EdmTypeKind.DEFINITION ?
-                ((EdmTypeDefinition) type).getUnderlyingType() :
-                type;
-                  return mapping == null || mapping.getMappedJavaClass() == null ?
-                      edmPrimitiveType.getDefaultType() :
-                        mapping.getMappedJavaClass();
+        type.getKind() == EdmTypeKind.ENUM ? ((EdmEnumType) type).getUnderlyingType() : type
+            .getKind() == EdmTypeKind.DEFINITION ? ((EdmTypeDefinition) type).getUnderlyingType()
: type;
+    return mapping == null || mapping.getMappedJavaClass() == null ? edmPrimitiveType.getDefaultType()
: mapping
+        .getMappedJavaClass();
   }
 
   /**
@@ -831,7 +824,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
       String odataType = odataTypeNode.asText();
       if (!odataType.isEmpty()) {
         odataType = odataType.substring(1);
-        
+
         if (odataType.equalsIgnoreCase(edmType.getFullQualifiedName().getFullQualifiedNameAsString()))
{
           return edmType;
         } else if (this.serviceMetadata == null) {
@@ -839,14 +832,14 @@ public class ODataJsonDeserializer implements ODataDeserializer {
               "Failed to resolve Odata type " + odataType + " due to metadata is not available",
               DeserializerException.MessageKeys.UNKNOWN_CONTENT);
         }
-        
+
         EdmStructuredType currentEdmType = null;
-        if(edmType instanceof EdmEntityType) {
+        if (edmType instanceof EdmEntityType) {
           currentEdmType = serviceMetadata.getEdm()
-              .getEntityType(new FullQualifiedName(odataType));          
+              .getEntityType(new FullQualifiedName(odataType));
         } else {
           currentEdmType = serviceMetadata.getEdm()
-              .getComplexType(new FullQualifiedName(odataType));          
+              .getComplexType(new FullQualifiedName(odataType));
         }
         if (!isAssignable(edmType, currentEdmType)) {
           throw new DeserializerException(

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/44d6f5a1/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
index 8b87a12..e684c0f 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerDeepInsertTest.java
@@ -30,12 +30,64 @@ import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.Link;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.deserializer.DeserializerResult;
+import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
 import org.apache.olingo.server.core.deserializer.AbstractODataDeserializerTest;
 import org.junit.Test;
 
 public class ODataDeserializerDeepInsertTest extends AbstractODataDeserializerTest {
 
   @Test
+  public void unbalancedESAllPrim() throws Exception {
+    final DeserializerResult result = deserializeWithResult("UnbalancedESAllPrimFeed.json");
+    ExpandOption root = result.getExpandTree();
+    assertEquals(1, root.getExpandItems().size());
+
+    ExpandItem etTwoPrimManyLevel = root.getExpandItems().get(0);
+    assertEquals("NavPropertyETTwoPrimMany", etTwoPrimManyLevel.getResourcePath().getUriResourceParts().get(0)
+        .getSegmentValue());
+    assertEquals(1, etTwoPrimManyLevel.getExpandOption().getExpandItems().size());
+
+    ExpandItem etAllPrimOneLevel = etTwoPrimManyLevel.getExpandOption().getExpandItems().get(0);
+    assertEquals("NavPropertyETAllPrimOne", etAllPrimOneLevel.getResourcePath().getUriResourceParts().get(0)
+        .getSegmentValue());
+    assertEquals(1, etAllPrimOneLevel.getExpandOption().getExpandItems().size());
+
+    ExpandItem etTwoPrimOneLevel = etAllPrimOneLevel.getExpandOption().getExpandItems().get(0);
+    assertEquals("NavPropertyETTwoPrimOne", etTwoPrimOneLevel.getResourcePath().getUriResourceParts().get(0)
+        .getSegmentValue());
+    assertNull(etTwoPrimOneLevel.getExpandOption());
+  }
+
+  @Test
+  public void unbalancedESAllPrim2() throws Exception {
+    final DeserializerResult result = deserializeWithResult("UnbalancedESAllPrimFeed2.json");
+    ExpandOption root = result.getExpandTree();
+    assertEquals(1, root.getExpandItems().size());
+
+    ExpandItem etTwoPrimManyLevel = root.getExpandItems().get(0);
+    assertEquals("NavPropertyETTwoPrimMany", etTwoPrimManyLevel.getResourcePath().getUriResourceParts().get(0)
+        .getSegmentValue());
+    assertEquals(1, etTwoPrimManyLevel.getExpandOption().getExpandItems().size());
+
+    ExpandItem etAllPrimOneLevel = etTwoPrimManyLevel.getExpandOption().getExpandItems().get(0);
+    assertEquals("NavPropertyETAllPrimOne", etAllPrimOneLevel.getResourcePath().getUriResourceParts().get(0)
+        .getSegmentValue());
+    assertEquals(2, etAllPrimOneLevel.getExpandOption().getExpandItems().size());
+
+    ExpandItem etTwoPrimOneLevel = etAllPrimOneLevel.getExpandOption().getExpandItems().get(0);
+    assertEquals("NavPropertyETTwoPrimMany", etTwoPrimOneLevel.getResourcePath().getUriResourceParts().get(0)
+        .getSegmentValue());
+    assertNull(etTwoPrimOneLevel.getExpandOption());
+
+    etTwoPrimOneLevel = etAllPrimOneLevel.getExpandOption().getExpandItems().get(1);
+    assertEquals("NavPropertyETTwoPrimOne", etTwoPrimOneLevel.getResourcePath().getUriResourceParts().get(0)
+        .getSegmentValue());
+    assertNull(etTwoPrimOneLevel.getExpandOption());
+  }
+
+  @Test
   public void esAllPrimExpandedToOne() throws Exception {
     final Entity entity = deserialize("EntityESAllPrimExpandedNavPropertyETTwoPrimOne.json");
 
@@ -152,4 +204,10 @@ public class ODataDeserializerDeepInsertTest extends AbstractODataDeserializerTe
     return ODataJsonDeserializerEntityTest.deserialize(getFileAsStream(resourceName),
         "ETAllPrim", ContentType.JSON);
   }
+
+  private DeserializerResult deserializeWithResult(final String resourceName) throws IOException,
+      DeserializerException {
+    return ODataJsonDeserializerEntityTest.deserializeWithResult(getFileAsStream(resourceName),
+        "ETAllPrim", ContentType.JSON);
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/44d6f5a1/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
index 02453e6..6b46ffd 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerEntityTest.java
@@ -49,6 +49,7 @@ import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmDate;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.deserializer.DeserializerException;
+import org.apache.olingo.server.api.deserializer.DeserializerResult;
 import org.apache.olingo.server.api.deserializer.ODataDeserializer;
 import org.apache.olingo.server.core.deserializer.AbstractODataDeserializerTest;
 import org.junit.Assert;
@@ -1347,6 +1348,12 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
         .entity(stream, edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)))
         .getEntity();
   }
+  
+  protected static DeserializerResult deserializeWithResult(final InputStream stream, final
String entityTypeName,
+      final ContentType contentType) throws DeserializerException {
+    return OData.newInstance().createDeserializer(contentType, metadata)
+        .entity(stream, edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)));
+  }
 
   private static Entity deserialize(final String entityString, final String entityTypeName,
       final ContentType contentType) throws DeserializerException {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/44d6f5a1/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed.json b/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed.json
new file mode 100644
index 0000000..d3fa550
--- /dev/null
+++ b/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed.json
@@ -0,0 +1,23 @@
+{
+  "@odata.context": "$metadata#ESAllPrim\/$entity",
+  "@odata.metadataEtag": "W\/\"4efd6576-89c0-487c-8d6c-584e2acbae16\"",
+  "PropertyInt16": 1,
+  "NavPropertyETTwoPrimMany": [
+    {
+      "PropertyInt16": 2,
+      "NavPropertyETAllPrimOne": {
+        "PropertyInt16": 3
+      }
+    },
+    {
+      "PropertyInt16": 2,
+      "NavPropertyETAllPrimOne": {
+        "PropertyInt16": 3,
+        "NavPropertyETTwoPrimOne": {
+          "PropertyInt16": 32766,
+          "PropertyString": "Innermost Entry"
+        }
+      }
+    }
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/44d6f5a1/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed2.json
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed2.json b/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed2.json
new file mode 100644
index 0000000..678fd3a
--- /dev/null
+++ b/lib/server-test/src/test/resources/UnbalancedESAllPrimFeed2.json
@@ -0,0 +1,24 @@
+{
+  "@odata.context": "$metadata#ESAllPrim\/$entity",
+  "@odata.metadataEtag": "W\/\"4efd6576-89c0-487c-8d6c-584e2acbae16\"",
+  "PropertyInt16": 1,
+  "NavPropertyETTwoPrimMany": [
+    {
+      "PropertyInt16": 2,
+      "NavPropertyETAllPrimOne": {
+          "PropertyInt16": 3,
+          "NavPropertyETTwoPrimMany": []
+        } 
+    },
+    {
+      "PropertyInt16": 2,
+      "NavPropertyETAllPrimOne": {
+          "PropertyInt16": 3,
+          "NavPropertyETTwoPrimOne": {
+            "PropertyInt16": 32766,
+            "PropertyString": "Innermost Entry"
+            }           
+        }      
+    }
+  ]
+}
\ No newline at end of file


Mime
View raw message