You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ra...@apache.org on 2016/02/08 22:46:21 UTC

[1/2] olingo-odata4 git commit: OLINGO-865: fixing the bug with extended complex types during serilization

Repository: olingo-odata4
Updated Branches:
  refs/heads/master 280bc019c -> b7005b774


OLINGO-865: fixing the bug with extended complex types during serilization


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

Branch: refs/heads/master
Commit: 8468308aeb2920e52d56b23101e59b3cf6b0e6f8
Parents: 280bc01
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Sun Feb 7 17:06:22 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Sun Feb 7 17:06:22 2016 -0600

----------------------------------------------------------------------
 .../serializer/json/ODataJsonSerializer.java    | 42 +++++++----
 .../core/serializer/xml/ODataXmlSerializer.java | 18 +++--
 .../olingo/server/tecsvc/data/DataCreator.java  | 17 ++++-
 .../tecsvc/provider/ComplexTypeProvider.java    |  8 ++
 .../json/ODataJsonSerializerTest.java           | 34 ++++++++-
 .../serializer/xml/ODataXmlSerializerTest.java  | 77 +++++++++++++++++++-
 6 files changed, 166 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
index a912862..3f3ba26 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializer.java
@@ -264,7 +264,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
       if (!isODataMetadataNone && !resolvedType.equals(entityType)) {
         json.writeStringField(Constants.JSON_TYPE, "#" + entity.getType());
       }
-      writeProperties(resolvedType, entity.getProperties(), select, json);
+      writeProperties(metadata, resolvedType, entity.getProperties(), select, json);
       writeNavigationProperties(metadata, resolvedType, entity, expand, json);
       json.writeEndObject();
     }
@@ -318,7 +318,8 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
         .getFullQualifiedName().getFullQualifiedNameAsString());
   }
 
-  protected void writeProperties(final EdmStructuredType type, final List<Property> properties,
+  protected void writeProperties(final ServiceMetadata metadata, final EdmStructuredType type,
+      final List<Property> properties,
       final SelectOption select, final JsonGenerator json)
           throws IOException, SerializerException {
     final boolean all = ExpandSelectHelper.isAll(select);
@@ -330,7 +331,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
         final Property property = findProperty(propertyName, properties);
         final Set<List<String>> selectedPaths = all || edmProperty.isPrimitive() ? null :
           ExpandSelectHelper.getSelectedPaths(select.getSelectItems(), propertyName);
-        writeProperty(edmProperty, property, selectedPaths, json);
+        writeProperty(metadata, edmProperty, property, selectedPaths, json);
       }
     }
   }
@@ -382,7 +383,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
     }
   }
 
-  protected void writeProperty(final EdmProperty edmProperty, final Property property,
+  protected void writeProperty(final ServiceMetadata metadata, final EdmProperty edmProperty, final Property property,
       final Set<List<String>> selectedPaths, final JsonGenerator json)
           throws IOException, SerializerException {
     json.writeFieldName(edmProperty.getName());
@@ -399,11 +400,11 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
         }
       }
     } else {
-      writePropertyValue(edmProperty, property, selectedPaths, json);
+      writePropertyValue(metadata, edmProperty, property, selectedPaths, json);
     }
   }
 
-  private void writePropertyValue(final EdmProperty edmProperty,
+  private void writePropertyValue(final ServiceMetadata metadata, final EdmProperty edmProperty,
       final Property property, final Set<List<String>> selectedPaths, final JsonGenerator json)
           throws IOException, SerializerException {
     final EdmType type = edmProperty.getType();
@@ -421,9 +422,10 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
         }
       } else if (property.isComplex()) {
         if (edmProperty.isCollection()) {
-          writeComplexCollection((EdmComplexType) type, property, selectedPaths, json);
+          writeComplexCollection(metadata, (EdmComplexType) type, property, selectedPaths, json);
         } else {
-          writeComplexValue((EdmComplexType) type, property.asComplex().getValue(), selectedPaths, json);
+          writeComplexValue(metadata, property, (EdmComplexType) type, property.asComplex().getValue(), selectedPaths,
+              json);
         }
       } else {
         throw new SerializerException("Property type not yet supported!",
@@ -464,14 +466,15 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
     json.writeEndArray();
   }
 
-  private void writeComplexCollection(final EdmComplexType type, final Property property,
+  private void writeComplexCollection(final ServiceMetadata metadata, final EdmComplexType type,
+      final Property property,
       final Set<List<String>> selectedPaths, final JsonGenerator json)
           throws IOException, SerializerException {
     json.writeStartArray();
     for (Object value : property.asCollection()) {
       switch (property.getValueType()) {
       case COLLECTION_COMPLEX:
-        writeComplexValue(type, ((ComplexValue) value).getValue(), selectedPaths, json);
+        writeComplexValue(metadata, property, type, ((ComplexValue) value).getValue(), selectedPaths, json);
         break;
       default:
         throw new SerializerException("Property type not yet supported!",
@@ -524,14 +527,23 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
     }
   }
 
-  protected void writeComplexValue(final EdmComplexType type, final List<Property> properties,
+  protected void writeComplexValue(final ServiceMetadata metadata, final Property complexProperty,
+      final EdmComplexType type, final List<Property> properties,
       final Set<List<String>> selectedPaths, final JsonGenerator json)
           throws IOException, SerializerException {
     json.writeStartObject();
-    for (final String propertyName : type.getPropertyNames()) {
+
+    final EdmComplexType resolvedType = resolveComplexType(metadata,
+        type, complexProperty.getType());
+    if (!isODataMetadataNone && !resolvedType.equals(type)) {
+      json.writeStringField(Constants.JSON_TYPE,
+          "#" + complexProperty.getType());
+    }
+
+    for (final String propertyName : resolvedType.getPropertyNames()) {
       final Property property = findProperty(propertyName, properties);
       if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
-        writeProperty((EdmProperty) type.getProperty(propertyName), property,
+        writeProperty(metadata, (EdmProperty) resolvedType.getProperty(propertyName), property,
             selectedPaths == null ? null : ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, propertyName),
                 json);
       }
@@ -610,7 +622,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
       }
       final List<Property> values =
           property.isNull() ? Collections.<Property> emptyList() : property.asComplex().getValue();
-          writeProperties(type, values, options == null ? null : options.getSelect(), json);
+          writeProperties(metadata, type, values, options == null ? null : options.getSelect(), json);
           if (!property.isNull() && property.isComplex()) {
             writeNavigationProperties(metadata, type, property.asComplex(),
                 options == null ? null : options.getExpand(), json);
@@ -677,7 +689,7 @@ public class ODataJsonSerializer extends AbstractODataSerializer {
       writeContextURL(contextURL, json);
       writeMetadataETag(metadata, json);
       json.writeFieldName(Constants.VALUE);
-      writeComplexCollection(type, property, null, json);
+      writeComplexCollection(metadata, type, property, null, json);
       json.writeEndObject();
 
       json.close();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
index 52d12e4..0057db4 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializer.java
@@ -635,8 +635,8 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
 
   private String derivedComplexType(final EdmComplexType baseType,
       final String definedType) throws SerializerException {
-    String derived = baseType.getFullQualifiedName().getFullQualifiedNameAsString();
-    if (derived.equals(definedType)) {
+    String base = baseType.getFullQualifiedName().getFullQualifiedNameAsString();
+    if (base.equals(definedType)) {
       return null;
     }
     return definedType;
@@ -671,7 +671,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
         } else {
           writer.writeAttribute(METADATA, NS_METADATA, Constants.ATTR_TYPE,
               "#" + complexType(metadata, (EdmComplexType) edmProperty.getType(), property.getType()));
-          writeComplexValue(metadata, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
+          writeComplexValue(metadata, property, (EdmComplexType) edmProperty.getType(), property.asComplex().getValue(),
               selectedPaths, writer);
         }
       } else {
@@ -717,7 +717,7 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
       }
       switch (property.getValueType()) {
       case COLLECTION_COMPLEX:
-        writeComplexValue(metadata, type, ((ComplexValue) value).getValue(), selectedPaths, writer);
+        writeComplexValue(metadata, property, type, ((ComplexValue) value).getValue(), selectedPaths, writer);
         break;
       default:
         throw new SerializerException("Property type not yet supported!",
@@ -767,13 +767,17 @@ public class ODataXmlSerializer extends AbstractODataSerializer {
     }
   }
 
-  protected void writeComplexValue(final ServiceMetadata metadata, final EdmComplexType type,
+  protected void writeComplexValue(final ServiceMetadata metadata, Property complexProperty, final EdmComplexType type,
       final List<Property> properties, final Set<List<String>> selectedPaths, final XMLStreamWriter writer)
       throws XMLStreamException, SerializerException {
-    for (final String propertyName : type.getPropertyNames()) {
+
+    final EdmComplexType resolvedType = resolveComplexType(metadata,
+        type, complexProperty.getType());
+    
+    for (final String propertyName : resolvedType.getPropertyNames()) {
       final Property property = findProperty(propertyName, properties);
       if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
-        writeProperty(metadata, (EdmProperty) type.getProperty(propertyName), property,
+        writeProperty(metadata, (EdmProperty) resolvedType.getProperty(propertyName), property,
             selectedPaths == null ? null : ExpandSelectHelper.getReducedSelectedPaths(selectedPaths, propertyName),
             writer);
       }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
index 5c60b38..80a3146 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataCreator.java
@@ -44,6 +44,7 @@ import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriHelper;
+import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider;
 import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
 
 public class DataCreator {
@@ -1003,10 +1004,12 @@ public class DataCreator {
 
     entity = new Entity();
     entity.addProperty(createPrimitive("PropertyInt16", (short) 2));
-    entity.addProperty(createComplex("PropertyComp",
-        createComplex("PropertyComp",
+    entity.addProperty(createComplex("PropertyComp", 
+        ComplexTypeProvider.nameCTCompCompExtended.getFullQualifiedNameAsString(), 
+        createComplex("PropertyComp",  
             createPrimitive("PropertyInt16", (short) 987),
-            createPrimitive("PropertyString", "String 2"))));
+            createPrimitive("PropertyString", "String 2")),
+        createPrimitive("PropertyDate", getDateTime(2012, 12, 3, 0, 0, 0))));
     entityCollection.getEntities().add(entity);
 
     setEntityType(entityCollection, edm.getEntityType(EntityTypeProvider.nameETCompComp));
@@ -1174,6 +1177,14 @@ public class DataCreator {
     }
     return new Property(null, name, ValueType.COMPLEX, complexValue);
   }
+  
+  protected static Property createComplex(final String name, final String type, final Property... properties) {
+    ComplexValue complexValue = new ComplexValue();
+    for (final Property property : properties) {
+      complexValue.getValue().add(property);
+    }
+    return new Property(type, name, ValueType.COMPLEX, complexValue);
+  }  
 
   protected static Property createComplexCollection(final String name, final List<Property>... propertiesList) {
     List<ComplexValue> complexCollection = new ArrayList<ComplexValue>();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
index 502f83a..7d539b6 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/provider/ComplexTypeProvider.java
@@ -38,6 +38,8 @@ public class ComplexTypeProvider {
   public static final FullQualifiedName nameCTCompCollComp = new FullQualifiedName(SchemaProvider.NAMESPACE,
       "CTCompCollComp");
   public static final FullQualifiedName nameCTCompComp = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTCompComp");
+  public static final FullQualifiedName nameCTCompCompExtended = new FullQualifiedName(
+      SchemaProvider.NAMESPACE, "CTCompCompExtended");
   public static final FullQualifiedName nameCTCompNav = new FullQualifiedName(SchemaProvider.NAMESPACE, "CTCompNav");
 
   public static final FullQualifiedName nameCTMixPrimCollComp = new FullQualifiedName(SchemaProvider.NAMESPACE,
@@ -125,6 +127,12 @@ public class ComplexTypeProvider {
           .setName("CTCompComp")
           .setProperties(Arrays.asList(PropertyProvider.propertyComp_CTTwoPrim));
 
+    } else if (complexTypeName.equals(nameCTCompCompExtended)) {
+      return new CsdlComplexType()
+        .setName("CTCompCompExtended")
+        .setBaseType(nameCTCompComp)
+        .setProperties(Arrays.asList(PropertyProvider.propertyDate));
+      
     } else if (complexTypeName.equals(nameCTCompCollComp)) {
       return new CsdlComplexType()
           .setName("CTCompCollComp")

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
index 7761b1d..0ad7ac5 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/json/ODataJsonSerializerTest.java
@@ -560,9 +560,38 @@ public class ODataJsonSerializerTest {
         + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
         + "\"value\":["
         + "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyString\":\"String 1\"}}},"
-        + "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyString\":\"String 2\"}}}]}",
+        + "{\"PropertyComp\":{\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\","
+        + "\"PropertyComp\":{\"PropertyString\":\"String 2\"}}}]}",
         resultString);
   }
+  
+  @Test
+  public void selectExtendedComplexType() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
+    final EntityCollection entitySet = data.readAll(edmEntitySet);
+    InputStream result = serializer
+        .entityCollection(metadata, entityType, entitySet,
+            EntityCollectionSerializerOptions.with()
+                .contextURL(ContextURL.with().entitySet(edmEntitySet)
+                    .selectList(helper.buildContextURLSelectList(entityType, null, null))
+                    .build())
+                .build()).getContent();
+    final String resultString = IOUtils.toString(result);
+    
+    String expected = "{" + 
+        "\"@odata.context\":\"$metadata#ESCompComp\"," + 
+        "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\"," + 
+        "\"value\":[" + 
+        "{\"PropertyInt16\":1," +
+        "\"PropertyComp\":{\"PropertyComp\":{" + 
+        "\"PropertyInt16\":123,\"PropertyString\":\"String 1\"}}}," + 
+        "{\"PropertyInt16\":2," + 
+        "\"PropertyComp\":{\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\"," + 
+        "\"PropertyComp\":{\"PropertyInt16\":987,\"PropertyString\":\"String 2\"},\"PropertyDate\":\"2012-12-03\"}}]}";
+    Assert.assertEquals(expected, resultString);
+
+  }  
 
   @Test
   public void selectComplexTwice() throws Exception {
@@ -585,7 +614,8 @@ public class ODataJsonSerializerTest {
         + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
         + "\"value\":["
         + "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyInt16\":123,\"PropertyString\":\"String 1\"}}},"
-        + "{\"PropertyComp\":{\"PropertyComp\":{\"PropertyInt16\":987,\"PropertyString\":\"String 2\"}}}]}",
+        + "{\"PropertyComp\":{\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\","
+        + "\"PropertyComp\":{\"PropertyInt16\":987,\"PropertyString\":\"String 2\"}}}]}",
         resultString);
   }
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/8468308a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
index 9611500..c904ea7 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerTest.java
@@ -1044,7 +1044,7 @@ public class ODataXmlSerializerTest {
         "      term=\"#olingo.odata.test1.ETCompComp\" />\n" +
         "    <a:content type=\"application/xml\">\n" +
         "      <m:properties>\n" +
-        "        <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+        "        <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompCompExtended\">\n" +
         "          <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
         "            <d:PropertyString>String 2</d:PropertyString>\n" +
         "          </d:PropertyComp>\n" +
@@ -1057,6 +1057,77 @@ public class ODataXmlSerializerTest {
   }
 
   @Test
+  public void selectComplexExtended() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
+    final EntityCollection entitySet = data.readAll(edmEntitySet);
+    long currentTimeMillis = System.currentTimeMillis();
+    InputStream result = serializer
+        .entityCollection(metadata, entityType, entitySet,
+            EntityCollectionSerializerOptions.with()
+                .contextURL(ContextURL.with().entitySet(edmEntitySet)
+                    .selectList(helper.buildContextURLSelectList(entityType, null, null))
+                    .build())
+                .id("http://host/svc/ESCompComp")
+                .build()).getContent();
+    final String resultString = IOUtils.toString(result);
+    String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
+        "<a:feed xmlns:a=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" "
+        + "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" m:context=\"$metadata#ESCompComp\" "
+        + "m:metadata-etag=\"metadataETag\">\n" + 
+        "   <a:id>http://host/svc/ESCompComp</a:id>\n" + 
+        "   <a:entry>\n" + 
+        "      <a:id>ESCompComp(1)</a:id>\n" + 
+        "      <a:title />\n" + 
+        "      <a:summary />\n" + 
+        "      <a:updated>"+ UPDATED_FORMAT.format(new Date(currentTimeMillis)) +"</a:updated>\n" + 
+        "      <a:author>\n" + 
+        "         <a:name />\n" + 
+        "      </a:author>\n" + 
+        "      <a:link rel=\"edit\" href=\"ESCompComp(1)\" />\n" + 
+        "      <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" "
+        + "term=\"#olingo.odata.test1.ETCompComp\" />\n" + 
+        "      <a:content type=\"application/xml\">\n" + 
+        "         <m:properties>\n" + 
+        "            <d:PropertyInt16 m:type=\"Int16\">1</d:PropertyInt16>\n" + 
+        "            <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" + 
+        "               <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" + 
+        "                  <d:PropertyInt16 m:type=\"Int16\">123</d:PropertyInt16>\n" + 
+        "                  <d:PropertyString>String 1</d:PropertyString>\n" + 
+        "               </d:PropertyComp>\n" + 
+        "            </d:PropertyComp>\n" + 
+        "         </m:properties>\n" + 
+        "      </a:content>\n" + 
+        "   </a:entry>\n" + 
+        "   <a:entry>\n" + 
+        "      <a:id>ESCompComp(2)</a:id>\n" + 
+        "      <a:title />\n" + 
+        "      <a:summary />\n" + 
+        "      <a:updated>"+ UPDATED_FORMAT.format(new Date(currentTimeMillis)) +"</a:updated>\n" + 
+        "      <a:author>\n" + 
+        "         <a:name />\n" + 
+        "      </a:author>\n" + 
+        "      <a:link rel=\"edit\" href=\"ESCompComp(2)\" />\n" + 
+        "      <a:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" "
+        + "term=\"#olingo.odata.test1.ETCompComp\" />\n" + 
+        "      <a:content type=\"application/xml\">\n" + 
+        "         <m:properties>\n" + 
+        "            <d:PropertyInt16 m:type=\"Int16\">2</d:PropertyInt16>\n" + 
+        "            <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompCompExtended\">\n" + 
+        "               <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" + 
+        "                  <d:PropertyInt16 m:type=\"Int16\">987</d:PropertyInt16>\n" + 
+        "                  <d:PropertyString>String 2</d:PropertyString>\n" + 
+        "               </d:PropertyComp>\n" + 
+        "               <d:PropertyDate m:type=\"Date\">2012-12-03</d:PropertyDate>\n" + 
+        "            </d:PropertyComp>\n" + 
+        "         </m:properties>\n" + 
+        "      </a:content>\n" + 
+        "   </a:entry>\n" + 
+        "</a:feed>";
+    checkXMLEqual(expected, resultString);
+  }
+  
+  @Test
   public void selectComplexTwice() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
     final EdmEntityType entityType = edmEntitySet.getEntityType();
@@ -1117,7 +1188,7 @@ public class ODataXmlSerializerTest {
         "      term=\"#olingo.odata.test1.ETCompComp\" />\n" +
         "    <a:content type=\"application/xml\">\n" +
         "      <m:properties>\n" +
-        "        <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompComp\">\n" +
+        "        <d:PropertyComp m:type=\"#olingo.odata.test1.CTCompCompExtended\">\n" +
         "          <d:PropertyComp m:type=\"#olingo.odata.test1.CTTwoPrim\">\n" +
         "            <d:PropertyInt16 m:type=\"Int16\">987</d:PropertyInt16>\n" +
         "            <d:PropertyString>String 2</d:PropertyString>\n" +
@@ -1127,7 +1198,7 @@ public class ODataXmlSerializerTest {
         "    </a:content>\n" +
         "  </a:entry>\n" +
         "</a:feed>\n";
-    checkXMLEqual(expected, resultString);
+    checkXMLEqual(resultString, expected);
   }
 
   @Test


[2/2] olingo-odata4 git commit: OLINGO-825: Adding the support for odata.type such that the extended entity and complex types are correctly de-serilized

Posted by ra...@apache.org.
OLINGO-825: Adding the support for odata.type such that the extended entity and complex types are correctly de-serilized


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

Branch: refs/heads/master
Commit: b7005b774f9172b00ee90773e2f32ed84a9597cd
Parents: 8468308
Author: Ramesh Reddy <ra...@jboss.org>
Authored: Mon Feb 8 15:41:32 2016 -0600
Committer: Ramesh Reddy <ra...@jboss.org>
Committed: Mon Feb 8 15:41:32 2016 -0600

----------------------------------------------------------------------
 .../olingo/fit/tecsvc/client/BasicITCase.java   | 34 ++++----
 .../fit/tecsvc/client/BatchClientITCase.java    |  8 +-
 .../olingo/fit/tecsvc/client/BindingITCase.java | 10 +--
 .../fit/tecsvc/client/DeepInsertITCase.java     | 31 ++++----
 .../tecsvc/client/FilterSystemQueryITCase.java  |  4 +-
 .../org/apache/olingo/server/api/OData.java     | 10 +++
 .../server/core/requests/ActionRequest.java     |  2 +-
 .../server/core/requests/DataRequest.java       |  6 +-
 .../olingo/server/example/TripPinDataModel.java |  2 +-
 .../apache/olingo/server/core/ODataImpl.java    | 13 +++
 .../json/ODataJsonDeserializer.java             | 77 +++++++++++++++++-
 .../deserializer/xml/ODataXmlDeserializer.java  | 84 ++++++++++++++++++--
 .../AbstractODataDeserializerTest.java          |  5 +-
 .../ODataDeserializerEntityCollectionTest.java  |  4 +-
 ...ataJsonDeserializerActionParametersTest.java |  2 +-
 .../json/ODataJsonDeserializerEntityTest.java   | 46 ++++++++++-
 ...DataXMLDeserializerActionParametersTest.java |  2 +-
 .../xml/ODataXmlDeserializerTest.java           | 43 +++++++++-
 18 files changed, 320 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
index c8e4848..a45f548 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BasicITCase.java
@@ -391,7 +391,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
         getFactory().newPrimitiveValueBuilder().buildString("Test")));
     newEntity.getProperties().add(
         getFactory().newComplexProperty("PropertyCompTwoPrim",
-            getFactory().newComplexValue("CTTwoPrim")
+            getFactory().newComplexValue(SERVICE_NAMESPACE+".CTTwoPrim")
                 .add(getFactory().newPrimitiveProperty(
                     PROPERTY_INT16,
                     getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))
@@ -537,19 +537,19 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
 
     entity.getProperties().add(
         getFactory().newCollectionProperty("CollPropertyComp",
-            getFactory().newCollectionValue("CTPrimComp")
-                .add(getFactory().newComplexValue("CTPrimComp")
+            getFactory().newCollectionValue(SERVICE_NAMESPACE+".CTPrimComp")
+                .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
                     .add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
                         getFactory().newPrimitiveValueBuilder().buildInt16((short) 42)))
                     .add(getFactory().newComplexProperty(PROPERTY_COMP,
-                        getFactory().newComplexValue("CTAllPrim")
+                        getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
                             .add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
                                 getFactory().newPrimitiveValueBuilder().buildString("42"))))))
-                .add(getFactory().newComplexValue("CTPrimComp")
+                .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
                     .add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
                         getFactory().newPrimitiveValueBuilder().buildInt16((short) 43)))
                     .add(getFactory().newComplexProperty(PROPERTY_COMP,
-                        getFactory().newComplexValue("CTAllPrim")
+                        getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
                             .add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
                                 getFactory().newPrimitiveValueBuilder().buildString("43"))))))));
 
@@ -597,22 +597,24 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
         getFactory().newPrimitiveProperty(PROPERTY_STRING,
             getFactory().newPrimitiveValueBuilder().buildString("Complex collection test")));
     entity.getProperties().add(getFactory().newComplexProperty("PropertyCompTwoPrim",
-        getFactory().newComplexValue("CTTwoPrim")
+        getFactory().newComplexValue(SERVICE_NAMESPACE+".CTTwoPrim")
             .add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
                 getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))
             .add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
                 getFactory().newPrimitiveValueBuilder().buildString("1")))));
 
     entity.getProperties().add(getFactory().newCollectionProperty("CollPropertyComp",
-        getFactory().newCollectionValue("CTPrimComp")
-            .add(getFactory().newComplexValue("CTPrimComp")
+        getFactory().newCollectionValue(SERVICE_NAMESPACE+".CTPrimComp")
+            .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
                 .add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
                     getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))
-                .add(getFactory().newComplexProperty(PROPERTY_COMP, getFactory().newComplexValue("CTAllPrim")
+                .add(getFactory().newComplexProperty(PROPERTY_COMP, 
+                    getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
                     .add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
                         getFactory().newPrimitiveValueBuilder().buildString("1"))))))
-            .add(getFactory().newComplexValue("CTPrimComp")
-                .add(getFactory().newComplexProperty(PROPERTY_COMP, getFactory().newComplexValue("CTAllPrim")
+            .add(getFactory().newComplexValue(SERVICE_NAMESPACE+".CTPrimComp")
+                .add(getFactory().newComplexProperty(PROPERTY_COMP, 
+                    getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
                     .add(getFactory().newPrimitiveProperty(PROPERTY_STRING,
                         getFactory().newPrimitiveValueBuilder().buildString("2")))
                     .add(getFactory().newPrimitiveProperty(PROPERTY_INT16,
@@ -789,7 +791,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
         factory.newCollectionValue("Edm.String").add(
             factory.newPrimitiveValueBuilder().buildString("Single entry!"))));
     entity.getProperties().add(factory.newComplexProperty(PROPERTY_COMP_ALL_PRIM,
-        factory.newComplexValue("CTAllPrim")
+        factory.newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
             .add(factory.newPrimitiveProperty(PROPERTY_STRING,
                 factory.newPrimitiveValueBuilder().buildString("Changed")))));
 
@@ -883,7 +885,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
         .newPrimitiveValueBuilder()
         .buildString("Must not be null")));
     entity.getProperties().add(factory.newComplexProperty("PropertyCompTwoPrim", factory.newComplexValue
-        ("CTTwoPrim")
+        (SERVICE_NAMESPACE+".CTTwoPrim")
         .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder()
             .buildString("Must not be null")))
         .add(factory.newPrimitiveProperty(PROPERTY_INT16,
@@ -892,7 +894,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
         factory.newCollectionValue("Edm.String")
             .add(factory.newPrimitiveValueBuilder().buildString("Single entry!"))));
     entity.getProperties().add(factory.newComplexProperty(PROPERTY_COMP_ALL_PRIM,
-        factory.newComplexValue("CTAllPrim").add(
+        factory.newComplexValue(SERVICE_NAMESPACE+".CTAllPrim").add(
             factory.newPrimitiveProperty(PROPERTY_STRING,
                 factory.newPrimitiveValueBuilder().buildString("Changed")))));
 
@@ -1165,7 +1167,7 @@ public class BasicITCase extends AbstractParamTecSvcITCase {
     final ODataPropertyUpdateRequest requestUpdate = getEdmEnabledClient().getCUDRequestFactory()
         .getPropertyComplexValueUpdateRequest(uri, UpdateType.PATCH,
             getFactory().newComplexProperty(PROPERTY_COMP_ALL_PRIM,
-                getFactory().newComplexValue("CTAllPrim")
+                getFactory().newComplexValue(SERVICE_NAMESPACE+".CTAllPrim")
                     .add(getFactory().newPrimitiveProperty(PROPERTY_INT64,
                         getFactory().newPrimitiveValueBuilder().buildInt64(Long.MIN_VALUE)))
                     .add(getFactory().newPrimitiveProperty(PROPERTY_DECIMAL,

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
index 273779c..913d9f9 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BatchClientITCase.java
@@ -358,7 +358,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
     final BatchManager streamManager = request.payloadManager();
 
     final ODataChangeset changeset = streamManager.addChangeset();
-    final ClientEntity entityESAllPrim = getFactory().newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+    final ClientEntity entityESAllPrim = getFactory().newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
 
     entityESAllPrim.getProperties().add(getFactory().newPrimitiveProperty("PropertyDouble",
         getFactory().newPrimitiveValueBuilder().buildDouble(3.1415)));
@@ -446,7 +446,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
     URI editLink = targetURI.build();
 
     ClientObjectFactory factory = getFactory();
-    ClientEntity postEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+    ClientEntity postEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
     postEntity.addLink(factory.newEntityNavigationLink("NavPropertyETTwoPrimOne", getClient().newURIBuilder
             (SERVICE_URI)
             .appendEntitySetSegment("ESTwoPrim")
@@ -467,7 +467,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
     targetURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(0);
     editLink = targetURI.build();
 
-    ClientEntity patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+    ClientEntity patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
     patchEntity.setEditLink(editLink);
 
     patchEntity.getProperties().add(factory.newPrimitiveProperty("PropertyDouble",
@@ -483,7 +483,7 @@ public class BatchClientITCase extends AbstractParamTecSvcITCase {
     targetURI = getClient().newURIBuilder(SERVICE_URI).appendEntitySetSegment("ESAllPrim").appendKeySegment(15);
     editLink = targetURI.build();
 
-    patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ESAllPrim"));
+    patchEntity = factory.newEntity(new FullQualifiedName(SERVICE_NAMESPACE, "ETAllPrim"));
     patchEntity.setEditLink(editLink);
 
     patchEntity.getProperties().add(factory.newPrimitiveProperty("PropertyDouble",

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
index 25e9c13..9caab23 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java
@@ -50,10 +50,10 @@ public class BindingITCase extends AbstractParamTecSvcITCase {
   private static final String ES_TWO_KEY_NAV = "ESTwoKeyNav";
   private static final String ET_KEY_NAV_NAME = "ETKeyNav";
   private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
-  private static final String CT_PRIM_COMP = "CTPrimComp";
-  private static final String CT_TWO_PRIM = "CTTwoPrim";
-  private static final String CT_ALL_PRIM = "CTAllPrim";
-  private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
+  private static final String CT_COMP_NAV = SERVICE_NAMESPACE+"."+"CTCompNav";
+  private static final String CT_TWO_PRIM = SERVICE_NAMESPACE+"."+"CTTwoPrim";
+  private static final String CT_ALL_PRIM = SERVICE_NAMESPACE+"."+"CTAllPrim";
+  private static final String CT_NAV_FIVE_PROP = SERVICE_NAMESPACE+"."+"CTNavFiveProp";
   private static final String PROPERTY_INT16 = "PropertyInt16";
   private static final String PROPERTY_STRING = "PropertyString";
   private static final String PROPERTY_COMP_NAV = "PropertyCompNav";
@@ -92,7 +92,7 @@ public class BindingITCase extends AbstractParamTecSvcITCase {
                     42)))
             .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("42")))));
     entity.getProperties()
-    .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV, factory.newComplexValue(CT_PRIM_COMP)
+    .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV, factory.newComplexValue(CT_COMP_NAV)
             .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder()
                     .buildString("42")))
             .add(factory.newComplexProperty(PROPERTY_COMP_NAV, factory.newComplexValue(CT_NAV_FIVE_PROP)

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
index d8a467a..53cf52c 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/DeepInsertITCase.java
@@ -64,11 +64,12 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
   private static final String ET_TWO_KEY_NAV_NAME = "ETTwoKeyNav";
   private static final FullQualifiedName ET_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_KEY_NAV_NAME);
   private static final FullQualifiedName ET_TWO_KEY_NAV = new FullQualifiedName(SERVICE_NAMESPACE, ET_TWO_KEY_NAV_NAME);
-  private static final String CT_PRIM_COMP = "CTPrimComp";
-  private static final String CT_TWO_PRIM = "CTTwoPrim";
-  private static final String CT_ALL_PRIM = "CTAllPrim";
-  private static final String CT_NAV_FIVE_PROP = "CTNavFiveProp";
-  private static final String CT_BASE_PRIM_COMP_NAV = "CTBasePrimCompNav";
+  private static final String CT_PRIM_COMP = SERVICE_NAMESPACE+"."+"CTPrimComp";
+  private static final String CT_COMP_NAV = SERVICE_NAMESPACE+"."+"CTCompNav";
+  private static final String CT_TWO_PRIM = SERVICE_NAMESPACE+"."+"CTTwoPrim";
+  private static final String CT_ALL_PRIM = SERVICE_NAMESPACE+"."+"CTAllPrim";
+  private static final String CT_NAV_FIVE_PROP = SERVICE_NAMESPACE+"."+"CTNavFiveProp";
+  private static final String CT_BASE_PRIM_COMP_NAV = SERVICE_NAMESPACE+"."+"CTBasePrimCompNav";
   private static final String PROPERTY_INT16 = "PropertyInt16";
   private static final String PROPERTY_STRING = "PropertyString";
   private static final String PROPERTY_COMP = "PropertyComp";
@@ -308,7 +309,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
                     factory.newPrimitiveValueBuilder().buildString("42")))));
     entity.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_STRING,
                     factory.newPrimitiveValueBuilder().buildString("42")))
                 .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -330,7 +331,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
                     factory.newPrimitiveValueBuilder().buildInt16((short) 430)))));
     inlineEntitySingle.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_INT16,
                     factory.newPrimitiveValueBuilder().buildInt16((short) 431)))));
     inlineEntitySingle.getProperties()
@@ -351,7 +352,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
         .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("44")));
     inlineEntityCol1.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_INT16,
                     factory.newPrimitiveValueBuilder().buildInt16((short) 441)))));
     inlineEntityCol1.getProperties()
@@ -374,7 +375,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
         .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("45")));
     inlineEntityCol2.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_INT16,
                     factory.newPrimitiveValueBuilder().buildInt16((short) 451)))));
     inlineEntityCol2.getProperties()
@@ -538,7 +539,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
                     factory.newPrimitiveValueBuilder().buildString("42")))));
     entity.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_STRING,
                     factory.newPrimitiveValueBuilder().buildString("42")))
                 .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -580,7 +581,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
                     factory.newPrimitiveValueBuilder().buildString("431")))));
     innerEntity.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_STRING,
                     factory.newPrimitiveValueBuilder().buildString("431")))
                 .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -804,7 +805,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
                     factory.newPrimitiveValueBuilder().buildString("42")))));
     entity.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_STRING,
                     factory.newPrimitiveValueBuilder().buildString("42")))
                 .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
@@ -825,7 +826,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
                 factory.newPrimitiveValueBuilder().buildInt16((short) 43)))));
     inlineEntitySingle.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_INT16,
                     factory.newPrimitiveValueBuilder().buildInt16((short) 431)))));
     inlineEntitySingle.getProperties()
@@ -846,7 +847,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
         .add(factory.newPrimitiveProperty(PROPERTY_STRING, factory.newPrimitiveValueBuilder().buildString("44")));
     inlineEntityCol1.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_INT16,
                     factory.newPrimitiveValueBuilder().buildInt16((short) 441)))));
     inlineEntityCol1.getProperties()
@@ -871,7 +872,7 @@ public class DeepInsertITCase extends AbstractParamTecSvcITCase {
             factory.newPrimitiveValueBuilder().buildString("45")));
     inlineEntityCol2.getProperties()
         .add(factory.newComplexProperty(PROPERTY_COMP_NAV,
-            factory.newComplexValue(CT_PRIM_COMP)
+            factory.newComplexValue(CT_BASE_PRIM_COMP_NAV)
                 .add(factory.newPrimitiveProperty(PROPERTY_INT16,
                     factory.newPrimitiveValueBuilder().buildInt16((short) 451)))));
     inlineEntityCol2.getProperties()

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
index 6865a65..ca66db5 100644
--- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
+++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java
@@ -911,14 +911,14 @@ public class FilterSystemQueryITCase extends AbstractParamTecSvcITCase {
         getFactory().newPrimitiveValueBuilder().buildString("Test")));
     newEntity.getProperties().add(
         getFactory().newComplexProperty("PropertyCompAllPrim",
-            getFactory().newComplexValue("CTAllPrim")
+            getFactory().newComplexValue(SERVICE_NAMESPACE+"."+"CTAllPrim")
             .add(getFactory().newPrimitiveProperty(
                 "PropertyString",
                 getFactory().newPrimitiveValueBuilder().buildString("Test 3")))));
 
     newEntity.getProperties().add(
         getFactory().newComplexProperty("PropertyCompTwoPrim",
-            getFactory().newComplexValue("CTTwoPrim")
+            getFactory().newComplexValue(SERVICE_NAMESPACE+"."+"CTTwoPrim")
             .add(getFactory().newPrimitiveProperty(
                 "PropertyInt16",
                 getFactory().newPrimitiveValueBuilder().buildInt16((short) 1)))

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
index 8e90c57..26f5f61 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/OData.java
@@ -132,6 +132,16 @@ public abstract class OData {
   public abstract ODataDeserializer createDeserializer(ContentType contentType) throws DeserializerException;
 
   /**
+   * Creates a new deserializer object for reading content in the specified format.
+   * Deserializers are used in Processor implementations.
+   *
+   * @param contentType any content type supported by Olingo (XML, JSON ...)
+   * @param metadata ServiceMetada of the service
+   */
+  public abstract ODataDeserializer createDeserializer(ContentType contentType,
+      ServiceMetadata metadata) throws DeserializerException;
+  
+  /**
    * Creates a primitive-type instance.
    * @param kind the kind of the primitive type
    * @return an {@link EdmPrimitiveType} instance for the type kind

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
index 9ff4cde..501b110 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/ActionRequest.java
@@ -145,7 +145,7 @@ public class ActionRequest extends OperationRequest {
   }
   
   public List<Parameter> getParameters() throws DeserializerException {
-    ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+    ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), this.serviceMetadata);
     return new ArrayList<Parameter>(deserializer.actionParameters(getPayload(), getAction()).getActionParameters()
         .values());
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
index 44c45bf..42fbdea 100644
--- a/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
+++ b/lib/server-core-ext/src/main/java/org/apache/olingo/server/core/requests/DataRequest.java
@@ -333,7 +333,7 @@ public class DataRequest extends ServiceRequest {
     }
 
     private Entity getEntityFromClient() throws DeserializerException {
-      ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+      ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), getServiceMetaData());
       return deserializer.entity(getODataRequest().getBody(), getEntitySet().getEntityType()).getEntity();
     }
 
@@ -460,7 +460,7 @@ public class DataRequest extends ServiceRequest {
     // /odata-json-format-v4.0-errata02-os-complete.html#_Toc403940643
     // The below code reads as property and converts to an URI
     private List<URI> getPayload() throws DeserializerException {
-      ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+      ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), getServiceMetaData());
       return deserializer.entityReferences(getODataRequest().getBody()).getEntityReferences();
     }
 
@@ -701,7 +701,7 @@ public class DataRequest extends ServiceRequest {
 
   private org.apache.olingo.commons.api.data.Property getPropertyValueFromClient(
       EdmProperty edmProperty) throws DeserializerException {
-    ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType());
+    ODataDeserializer deserializer = odata.createDeserializer(getRequestContentType(), getServiceMetaData());
     return deserializer.property(getODataRequest().getBody(), edmProperty).getProperty();
   }
   

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
----------------------------------------------------------------------
diff --git a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
index c58d9ce..562eac0 100644
--- a/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
+++ b/lib/server-core-ext/src/test/java/org/apache/olingo/server/example/TripPinDataModel.java
@@ -116,7 +116,7 @@ public class TripPinDataModel {
 
   private EntityCollection loadEnities(String entitySetName, EdmEntityType type) {
     try {
-      ODataJsonDeserializer deserializer = new ODataJsonDeserializer(ContentType.JSON);
+      ODataJsonDeserializer deserializer = new ODataJsonDeserializer(ContentType.JSON, this.metadata);
 
       EntityCollection set = deserializer.entityCollection(new FileInputStream(new File(
           "src/test/resources/" + entitySetName.toLowerCase() + ".json")), type).getEntityCollection();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
index 4c2642c..e5c5437 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/ODataImpl.java
@@ -121,6 +121,19 @@ public class ODataImpl extends OData {
       throw new DeserializerException("Unsupported format: " + contentType.toContentTypeString(),
           DeserializerException.MessageKeys.UNSUPPORTED_FORMAT, contentType.toContentTypeString());
     }
+  }  
+  @Override
+  public ODataDeserializer createDeserializer(final ContentType contentType,
+      ServiceMetadata metadata) throws DeserializerException {
+    if (contentType.isCompatible(ContentType.JSON)) {
+      return new ODataJsonDeserializer(contentType, metadata);
+    } else if (contentType.isCompatible(ContentType.APPLICATION_XML)
+        || contentType.isCompatible(ContentType.APPLICATION_ATOM_XML)) {
+      return new ODataXmlDeserializer(metadata);
+    } else {
+      throw new DeserializerException("Unsupported format: " + contentType.toContentTypeString(),
+          DeserializerException.MessageKeys.UNSUPPORTED_FORMAT, contentType.toContentTypeString());
+    }
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/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 7bbc4a0..da57309 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
@@ -48,10 +48,13 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.EdmType;
 import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
 import org.apache.olingo.commons.api.format.ContentType;
+import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.deserializer.DeserializerException;
 import org.apache.olingo.server.api.deserializer.DeserializerException.MessageKeys;
 import org.apache.olingo.server.api.deserializer.DeserializerResult;
@@ -76,10 +79,20 @@ public class ODataJsonDeserializer implements ODataDeserializer {
   private static final String ODATA_CONTROL_INFORMATION_PREFIX = "@odata.";
 
   private final boolean isIEEE754Compatible;
+  private ServiceMetadata serviceMetadata;
 
   public ODataJsonDeserializer(final ContentType contentType) {
     isIEEE754Compatible = isODataIEEE754Compatible(contentType);
   }
+  
+  public ODataJsonDeserializer(final ContentType contentType, final ServiceMetadata serviceMetadata) {
+    isIEEE754Compatible = isODataIEEE754Compatible(contentType);
+    this.serviceMetadata = serviceMetadata;
+  }
+  
+  public void setMetadata(ServiceMetadata metadata) {
+    this.serviceMetadata = metadata;
+  }
 
   @Override
   public DeserializerResult entityCollection(final InputStream stream, final EdmEntityType edmEntityType)
@@ -124,7 +137,8 @@ public class ODataJsonDeserializer implements ODataDeserializer {
           throw new DeserializerException("Nested Arrays and primitive values are not allowed for an entity value.",
               DeserializerException.MessageKeys.INVALID_ENTITY);
         }
-        entities.add(consumeEntityNode(edmEntityType, (ObjectNode) arrayElement, expandBuilder));
+        EdmEntityType derivedEdmEntityType = (EdmEntityType)getDerivedType(edmEntityType, arrayElement);
+        entities.add(consumeEntityNode(derivedEdmEntityType, (ObjectNode) arrayElement, expandBuilder));
       }
       return entities;
     } else {
@@ -140,7 +154,9 @@ public class ODataJsonDeserializer implements ODataDeserializer {
       final ObjectNode tree = parseJsonTree(stream);
       final ExpandTreeBuilderImpl expandBuilder = new ExpandTreeBuilderImpl();
 
-      return DeserializerResultImpl.with().entity(consumeEntityNode(edmEntityType, tree, expandBuilder))
+      EdmEntityType derivedEdmEntityType = (EdmEntityType)getDerivedType(edmEntityType, tree);
+
+      return DeserializerResultImpl.with().entity(consumeEntityNode(derivedEdmEntityType, tree, expandBuilder))
           .expandOption(expandBuilder.build())
           .build();
     } catch (final IOException e) {
@@ -257,6 +273,7 @@ public class ODataJsonDeserializer implements ODataDeserializer {
               edmParameter.isNullable(), edmParameter.getMaxLength(),
               edmParameter.getPrecision(), edmParameter.getScale(), true, edmParameter.getMapping(), node);
       parameter.setValue(property.getValueType(), property.getValue());
+      parameter.setType(property.getType());
     }
     return parameter;
   }
@@ -472,7 +489,12 @@ public class ODataJsonDeserializer implements ODataDeserializer {
           value);
       break;
     case COMPLEX:
-      value = readComplexNode(name, type, isNullable, jsonNode);
+      EdmType derivedType = getDerivedType((EdmComplexType) type,
+          jsonNode);
+      property.setType(derivedType.getFullQualifiedName()
+          .getFullQualifiedNameAsString());
+
+      value = readComplexNode(name, derivedType, isNullable, jsonNode);
       property.setValue(ValueType.COMPLEX, value);
       break;
     default:
@@ -808,4 +830,53 @@ public class ODataJsonDeserializer implements ODataDeserializer {
         && Boolean.TRUE.toString().equalsIgnoreCase(
             contentType.getParameter(ContentType.PARAMETER_IEEE754_COMPATIBLE));
   }
+
+  private EdmType getDerivedType(final EdmStructuredType edmType, final JsonNode jsonNode)
+      throws DeserializerException {
+    JsonNode odataTypeNode = jsonNode.get(Constants.JSON_TYPE);
+    if (odataTypeNode != null) {
+      String odataType = odataTypeNode.asText();
+      if (!odataType.isEmpty()) {
+        odataType = odataType.substring(1);
+        
+        if (odataType.equalsIgnoreCase(edmType.getFullQualifiedName().getFullQualifiedNameAsString())) {
+          return edmType;
+        } else if (this.serviceMetadata == null) {
+          throw new DeserializerException(
+              "Failed to resolve Odata type " + odataType + " due to metadata is not available",
+              DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+        }
+        
+        EdmStructuredType currentEdmType = null;
+        if(edmType instanceof EdmEntityType) {
+          currentEdmType = serviceMetadata.getEdm()
+              .getEntityType(new FullQualifiedName(odataType));          
+        } else {
+          currentEdmType = serviceMetadata.getEdm()
+              .getComplexType(new FullQualifiedName(odataType));          
+        }
+        if (!isAssignable(edmType, currentEdmType)) {
+          throw new DeserializerException(
+              "Odata type " + odataType + " not allowed here",
+              DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+        }
+
+        return currentEdmType;
+      }
+    }
+    return edmType;
+  }
+
+  private boolean isAssignable(final EdmStructuredType edmStructuredType,
+      final EdmStructuredType edmStructuredTypeToAssign) {
+    if (edmStructuredTypeToAssign == null) {
+      return false;
+    } else if (edmStructuredType.getFullQualifiedName()
+        .equals(edmStructuredTypeToAssign.getFullQualifiedName())) {
+      return true;
+    } else {
+      return isAssignable(edmStructuredType,
+          edmStructuredTypeToAssign.getBaseType());
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
index b556d8e..c8b5f96 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializer.java
@@ -52,10 +52,13 @@ import org.apache.olingo.commons.api.edm.EdmParameter;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.api.edm.EdmType;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.core.edm.EdmTypeInfo;
 import org.apache.olingo.commons.core.edm.primitivetype.AbstractGeospatialType;
+import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.deserializer.DeserializerException;
 import org.apache.olingo.server.api.deserializer.DeserializerException.MessageKeys;
 import org.apache.olingo.server.api.deserializer.DeserializerResult;
@@ -75,7 +78,21 @@ public class ODataXmlDeserializer implements ODataDeserializer {
   private static final QName etagQName = new QName(Constants.NS_METADATA, Constants.ATOM_ATTR_ETAG);
   private static final QName countQName = new QName(Constants.NS_METADATA, Constants.ATOM_ELEM_COUNT);
   private static final QName parametersQName = new QName(Constants.NS_METADATA, "parameters");
+  private static final QName typeQName = new QName(Constants.NS_METADATA, Constants.ATTR_TYPE);
+  
+  private ServiceMetadata serviceMetadata;
 
+  public ODataXmlDeserializer() {
+  }
+
+  public ODataXmlDeserializer(final ServiceMetadata serviceMetadata) {
+    this.serviceMetadata = serviceMetadata;
+  }
+  
+  public void setMetadata(ServiceMetadata metadata) {
+    this.serviceMetadata = metadata;
+  }
+  
   protected XMLEventReader getReader(final InputStream input) throws XMLStreamException {
     return FACTORY.createXMLEventReader(input);
   }
@@ -178,7 +195,17 @@ public class ODataXmlDeserializer implements ODataDeserializer {
     } else {
       property.setName(start.getName().getLocalPart());
     }
-    valuable(property, reader, start, edmType, isNullable, maxLength, precision, scale, isUnicode, isCollection);
+    
+    EdmType resolvedType = edmType;
+    final Attribute attrType = start.getAttributeByName(typeQName);
+    if (attrType != null && (edmType instanceof EdmComplexType)) {
+      String type = new EdmTypeInfo.Builder().setTypeExpression(attrType.getValue()).build().internal();
+      if (type.startsWith("Collection(") && type.endsWith(")")) {
+        type = type.substring(11, type.length()-1);
+      }
+      resolvedType = getDerivedType((EdmComplexType)edmType, type);
+    }
+    valuable(property, reader, start, resolvedType, isNullable, maxLength, precision, scale, isUnicode, isCollection);
     return property;
   }
 
@@ -431,6 +458,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
   private Entity entity(final XMLEventReader reader, final StartElement start, final EdmEntityType edmEntityType)
       throws XMLStreamException, EdmPrimitiveTypeException, DeserializerException {
     Entity entity = null;
+    EdmEntityType resolvedType = edmEntityType;
     if (entryRefQName.equals(start.getName())) {
       entity = entityRef(start);
     } else if (Constants.QNAME_ATOM_ELEM_ENTRY.equals(start.getName())) {
@@ -455,7 +483,9 @@ public class ODataXmlDeserializer implements ODataDeserializer {
           } else if (Constants.QNAME_ATOM_ELEM_CATEGORY.equals(event.asStartElement().getName())) {
             final Attribute term = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_TERM));
             if (term != null) {
-              entity.setType(new EdmTypeInfo.Builder().setTypeExpression(term.getValue()).build().internal());
+              String type = new EdmTypeInfo.Builder().setTypeExpression(term.getValue()).build().internal();
+              entity.setType(type);
+              resolvedType = (EdmEntityType)getDerivedType(edmEntityType, type);
             }
           } else if (Constants.QNAME_ATOM_ELEM_LINK.equals(event.asStartElement().getName())) {
             final Link link = new Link();
@@ -485,7 +515,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
                 entity.setMediaETag(mediaETag.getValue());
               }
             } else if (link.getRel().startsWith(Constants.NS_NAVIGATION_LINK_REL)) {
-              inline(reader, event.asStartElement(), link, edmEntityType);
+              inline(reader, event.asStartElement(), link, resolvedType);
               if (link.getInlineEntity() == null && link.getInlineEntitySet() == null) {
                 entity.getNavigationBindings().add(link);
               } else {
@@ -525,7 +555,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
                 .getAttributeByName(QName.valueOf(Constants.ATTR_TYPE));
             if (contenttype == null || ContentType.APPLICATION_XML.toContentTypeString()
                 .equals(contenttype.getValue())) {
-              properties(reader, skipBeforeFirstStartElement(reader), entity, edmEntityType);
+              properties(reader, skipBeforeFirstStartElement(reader), entity, resolvedType);
             } else {
               entity.setMediaContentType(contenttype.getValue());
               final Attribute src = event.asStartElement().getAttributeByName(QName.valueOf(Constants.ATOM_ATTR_SRC));
@@ -534,7 +564,7 @@ public class ODataXmlDeserializer implements ODataDeserializer {
               }
             }
           } else if (propertiesQName.equals(event.asStartElement().getName())) {
-            properties(reader, event.asStartElement(), entity, edmEntityType);
+            properties(reader, event.asStartElement(), entity, resolvedType);
           }
         }
 
@@ -799,4 +829,48 @@ public class ODataXmlDeserializer implements ODataDeserializer {
     }
     return parameter;
   }
+  
+  private EdmType getDerivedType(final EdmStructuredType edmType, String odataType)
+      throws DeserializerException {
+    if (odataType != null && !odataType.isEmpty()) {
+      
+      if (odataType.equalsIgnoreCase(edmType.getFullQualifiedName().getFullQualifiedNameAsString())) {
+        return edmType;
+      } else if (this.serviceMetadata == null) {
+        throw new DeserializerException(
+            "Failed to resolve Odata type " + odataType + " due to metadata is not available",
+            DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+      }
+      
+      EdmStructuredType currentEdmType = null;
+      if(edmType instanceof EdmEntityType) {
+        currentEdmType = serviceMetadata.getEdm()
+            .getEntityType(new FullQualifiedName(odataType));          
+      } else {
+        currentEdmType = serviceMetadata.getEdm()
+            .getComplexType(new FullQualifiedName(odataType));          
+      }
+      if (!isAssignable(edmType, currentEdmType)) {
+        throw new DeserializerException(
+            "Odata type " + odataType + " not allowed here",
+            DeserializerException.MessageKeys.UNKNOWN_CONTENT);
+      }
+
+      return currentEdmType;
+    }
+    return edmType;
+  }
+
+  private boolean isAssignable(final EdmStructuredType edmStructuredType,
+      final EdmStructuredType edmStructuredTypeToAssign) {
+    if (edmStructuredTypeToAssign == null) {
+      return false;
+    } else if (edmStructuredType.getFullQualifiedName()
+        .equals(edmStructuredTypeToAssign.getFullQualifiedName())) {
+      return true;
+    } else {
+      return isAssignable(edmStructuredType,
+          edmStructuredTypeToAssign.getBaseType());
+    }
+  }  
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
index c90ad6d..49c4ac9 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/AbstractODataDeserializerTest.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
 
@@ -33,7 +34,9 @@ public class AbstractODataDeserializerTest {
   protected static final Edm edm = OData.newInstance()
       .createServiceMetadata(new EdmTechProvider(), Collections.<EdmxReference> emptyList())
       .getEdm();
-
+  protected static final ServiceMetadata metadata = OData.newInstance()
+      .createServiceMetadata(new EdmTechProvider(), Collections.<EdmxReference> emptyList());
+  
   protected InputStream getFileAsStream(final String filename) throws IOException {
     InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);
     if (in == null) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
index 4b2c6c3..db65c78 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataDeserializerEntityCollectionTest.java
@@ -165,14 +165,14 @@ public class ODataDeserializerEntityCollectionTest extends AbstractODataDeserial
 
   private EntityCollection deserialize(final InputStream stream, final String entityTypeName)
       throws DeserializerException {
-    return OData.newInstance().createDeserializer(ContentType.JSON)
+    return OData.newInstance().createDeserializer(ContentType.JSON, metadata)
         .entityCollection(stream, edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)))
         .getEntityCollection();
   }
 
   private EntityCollection deserialize(final String input, final String entityTypeName)
       throws DeserializerException {
-    return OData.newInstance().createDeserializer(ContentType.JSON)
+    return OData.newInstance().createDeserializer(ContentType.JSON, metadata)
         .entityCollection(new ByteArrayInputStream(input.getBytes()),
             edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)))
         .getEntityCollection();

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
index 20d4fa2..b1f020e 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/json/ODataJsonDeserializerActionParametersTest.java
@@ -254,7 +254,7 @@ public class ODataJsonDeserializerActionParametersTest extends AbstractODataDese
 
   private Map<String, Parameter> deserialize(final String input, final String actionName, final String bindingTypeName)
       throws DeserializerException {
-    return OData.newInstance().createDeserializer(ContentType.JSON)
+    return OData.newInstance().createDeserializer(ContentType.JSON, metadata)
         .actionParameters(new ByteArrayInputStream(input.getBytes()),
             bindingTypeName == null ?
                 edm.getUnboundAction(new FullQualifiedName(NAMESPACE, actionName)) :

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/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 01e61f3..48dc870 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
@@ -46,10 +46,12 @@ import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.edm.provider.CsdlMapping;
 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.ODataDeserializer;
 import org.apache.olingo.server.core.deserializer.AbstractODataDeserializerTest;
+import org.junit.Assert;
 import org.junit.Test;
 
 public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTest {
@@ -218,6 +220,46 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
   }
 
   @Test
+  public void extendedComplexProperty() throws Exception {
+    
+    final String payload = "{"
+        + "\"@odata.context\":\"$metadata#ESCompComp/$entity\","
+        + "\"@odata.metadataEtag\":\"W/\\\"metadataETag\\\"\","
+        + "\"@odata.etag\":\"W/\\\"32767\\\"\","
+        + "\"PropertyInt16\":32767,"
+        + "\"PropertyComp\":{"
+        + "\"@odata.type\":\"#olingo.odata.test1.CTCompCompExtended\","
+        +   "\"PropertyComp\":{"
+        +   "\"@odata.type\":\"#olingo.odata.test1.CTTwoPrim\","
+        +   "\"PropertyInt16\":32767,"
+        +   "\"PropertyString\":\"First Resource - first\""
+        +   "},"
+        +   "\"PropertyDate\":\"2012-10-03\""
+        + "}}";
+    final Entity result = deserialize(payload, "ETCompComp");
+    
+    Assert.assertNotNull(result);
+    Property property = result.getProperty("PropertyComp");
+    Assert.assertEquals("PropertyComp", property.getName());    
+    Assert.assertTrue(property.isComplex());
+    final ComplexValue cv = property.asComplex();
+    Assert.assertEquals("olingo.odata.test1.CTCompCompExtended", property.getType());
+    Assert.assertEquals(
+        "2012-10-03",
+        EdmDate.getInstance().valueToString(getCVProperty(cv, "PropertyDate").asPrimitive(), false, 10, 3, 0,
+        false));
+  }  
+  
+  private Property getCVProperty(ComplexValue cv, String name) {
+    for (Property p : cv.getValue()) {
+      if (p.getName().equals(name)) {
+        return p;
+      }
+    }
+    return null;
+  }
+  
+  @Test
   public void simpleEntityETCollAllPrim() throws Exception {
     final String entityString = "{"
         + "\"PropertyInt16\":1,"
@@ -606,7 +648,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
         "{\"PropertyDate\":\"2012-12-03\","
             + "\"PropertyDateTimeOffset\":\"2012-12-03T07:16:23Z\"}";
     InputStream stream = new ByteArrayInputStream(entityString.getBytes());
-    ODataDeserializer deserializer = OData.newInstance().createDeserializer(ContentType.JSON);
+    ODataDeserializer deserializer = OData.newInstance().createDeserializer(ContentType.JSON, metadata);
     Entity entity = deserializer.entity(stream, entityType).getEntity();
     assertNotNull(entity);
     List<Property> properties = entity.getProperties();
@@ -1272,7 +1314,7 @@ public class ODataJsonDeserializerEntityTest extends AbstractODataDeserializerTe
 
   protected static Entity deserialize(final InputStream stream, final String entityTypeName,
       final ContentType contentType) throws DeserializerException {
-    return OData.newInstance().createDeserializer(contentType)
+    return OData.newInstance().createDeserializer(contentType, metadata)
         .entity(stream, edm.getEntityType(new FullQualifiedName(NAMESPACE, entityTypeName)))
         .getEntity();
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
index 18162da..539b70f 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXMLDeserializerActionParametersTest.java
@@ -234,7 +234,7 @@ public class ODataXMLDeserializerActionParametersTest extends AbstractODataDeser
 
   private Map<String, Parameter> deserialize(final String input, final String actionName, final String bindingTypeName)
       throws DeserializerException {
-    return OData.newInstance().createDeserializer(ContentType.APPLICATION_XML)
+    return OData.newInstance().createDeserializer(ContentType.APPLICATION_XML, metadata)
         .actionParameters(new ByteArrayInputStream(input.getBytes()),
             bindingTypeName == null ?
                 edm.getUnboundAction(new FullQualifiedName(NAMESPACE, actionName)) :

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/b7005b77/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
index dcde3f2..416c219 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/deserializer/xml/ODataXmlDeserializerTest.java
@@ -36,6 +36,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
 import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
 import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDate;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.deserializer.ODataDeserializer;
 import org.apache.olingo.server.core.deserializer.AbstractODataDeserializerTest;
@@ -47,7 +48,7 @@ import org.junit.Test;
 public class ODataXmlDeserializerTest extends AbstractODataDeserializerTest {
 
   private static final EdmEntityContainer entityContainer = edm.getEntityContainer();
-  private final ODataDeserializer deserializer = new ODataXmlDeserializer();
+  private final ODataDeserializer deserializer = new ODataXmlDeserializer(metadata);
 
   @BeforeClass
   public static void setup() {
@@ -535,6 +536,46 @@ public class ODataXmlDeserializerTest extends AbstractODataDeserializerTest {
   }
 
   @Test
+  public void extendedComplexProperty() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+    
+    String payload = "<?xml version='1.0' encoding='UTF-8'?>"
+        + "<atom:entry xmlns:atom=\"http://www.w3.org/2005/Atom\" "
+        + "xmlns:metadata=\"http://docs.oasis-open.org/odata/ns/metadata\" "
+        + "xmlns:data=\"http://docs.oasis-open.org/odata/ns/data\" "
+        + "metadata:etag=\"W/&quot;32767&quot;\">"
+          + "<atom:category scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" "
+          + "term=\"#olingo.odata.test1.ETCompComp\"/>"
+          + "<atom:content type=\"application/xml\">"
+            + "<metadata:properties>"
+              + "<data:PropertyInt16>32767</data:PropertyInt16>"
+              + "<data:PropertyComp metadata:type=\"#olingo.odata.test1.CTCompCompExtended\">"
+                + "<data:PropertyComp metadata:type=\"#olingo.odata.test1.CTTwoPrim\">"
+                  + "<data:PropertyInt16>32767</data:PropertyInt16>"
+                  + "<data:PropertyString>First Resource - first</data:PropertyString>"
+                  + "</data:PropertyComp>"
+                  + "<data:PropertyDate>2012-10-03</data:PropertyDate>"
+              + "</data:PropertyComp>"
+            + "</metadata:properties>"
+          + "</atom:content>"
+        + "</atom:entry>";
+    
+    Entity result = deserializer.entity(new ByteArrayInputStream(payload.getBytes()), 
+        edmEntitySet.getEntityType()).getEntity();
+
+    Assert.assertNotNull(result);
+    Property property = result.getProperty("PropertyComp");
+    Assert.assertEquals("PropertyComp", property.getName());    
+    Assert.assertTrue(property.isComplex());
+    final ComplexValue cv = property.asComplex();
+    Assert.assertEquals("olingo.odata.test1.CTCompCompExtended", property.getType());
+    Assert.assertEquals(
+        "2012-10-03",
+        EdmDate.getInstance().valueToString(getCVProperty(cv, "PropertyDate").asPrimitive(), false, 10, 3, 0,
+        false));
+  }
+  
+  @Test
   public void complexCollectionProperty() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
     final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp");