You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/11/13 10:58:20 UTC

[1/2] olingo-odata4 git commit: [OLINGO-485] refactored server serializers

Repository: olingo-odata4
Updated Branches:
  refs/heads/master dd2275694 -> c2c8bf196


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java
index 8a7c9c6..0e8e8bd 100644
--- a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilderTest.java
@@ -119,9 +119,10 @@ public class ContextURLBuilderTest {
     contextURL = ContextURL.with().serviceRoot(URI.create("http://host/service/"))
         .entitySet(entitySet)
         .keyPath("one=1,two='two'")
-        .navOrPropertyPath("Name")
+        .navOrPropertyPath("ComplexName")
+        .selectList("Part1")
         .build();
-    assertEquals("http://host/service/$metadata#Customers(one=1,two='two')/Name",
+    assertEquals("http://host/service/$metadata#Customers(one=1,two='two')/ComplexName(Part1)",
         ContextURLBuilder.create(contextURL).toASCIIString());
   }  
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
index 34da317..971c50a 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalEntityProcessor.java
@@ -18,7 +18,6 @@
  */
 package org.apache.olingo.server.tecsvc.processor;
 
-import java.io.ByteArrayInputStream;
 import java.util.List;
 import java.util.Locale;
 
@@ -37,8 +36,9 @@ import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
 import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
 import org.apache.olingo.server.api.processor.EntityProcessor;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriInfo;
 import org.apache.olingo.server.api.uri.UriResource;
@@ -76,8 +76,8 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
       ODataSerializer serializer = odata.createSerializer(format);
       final ExpandOption expand = uriInfo.getExpandOption();
       final SelectOption select = uriInfo.getSelectOption();
-      response.setContent(serializer.entitySet(edmEntitySet, entitySet,
-          ODataSerializerOptions.with()
+      response.setContent(serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
+          EntityCollectionSerializerOptions.with()
               .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
                   getContextUrl(serializer, edmEntitySet, false, expand, select))
               .count(uriInfo.getCountOption())
@@ -103,7 +103,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
     if (entitySet == null) {
       throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
     } else {
-      response.setContent(new ByteArrayInputStream(entitySet.getCount().toString().getBytes()));
+      response.setContent(odata.createFixedFormatSerializer().count(entitySet.getCount()));
       response.setStatusCode(HttpStatusCode.OK.getStatusCode());
       response.setHeader(HttpHeader.CONTENT_TYPE, requestedContentType.toContentTypeString());
     }
@@ -129,11 +129,10 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
       ODataSerializer serializer = odata.createSerializer(format);
       final ExpandOption expand = uriInfo.getExpandOption();
       final SelectOption select = uriInfo.getSelectOption();
-      response.setContent(serializer.entity(edmEntitySet, entity,
-          ODataSerializerOptions.with()
+      response.setContent(serializer.entity(edmEntitySet.getEntityType(), entity,
+          EntitySerializerOptions.with()
               .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
                   getContextUrl(serializer, edmEntitySet, true, expand, select))
-              .count(uriInfo.getCountOption())
               .expand(expand).select(select)
               .build()));
       response.setStatusCode(HttpStatusCode.OK.getStatusCode());
@@ -155,7 +154,7 @@ public class TechnicalEntityProcessor extends TechnicalProcessor
       final EdmEntitySet entitySet, final boolean isSingleEntity,
       final ExpandOption expand, final SelectOption select) throws SerializerException {
     return ContextURL.with().entitySet(entitySet)
-        .selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
+        .selectList(serializer.buildContextURLSelectList(entitySet.getEntityType(), expand, select))
         .suffix(isSingleEntity ? Suffix.ENTITY : null)
         .build();
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
----------------------------------------------------------------------
diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
index 037ffcb..09e9e8f 100644
--- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
+++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/TechnicalPrimitiveComplexProcessor.java
@@ -18,8 +18,6 @@
  */
 package org.apache.olingo.server.tecsvc.processor;
 
-import java.io.ByteArrayInputStream;
-import java.io.UnsupportedEncodingException;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
@@ -27,11 +25,12 @@ import java.util.Locale;
 import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
 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.format.ContentType;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.commons.api.http.HttpHeader;
@@ -44,8 +43,12 @@ import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
 import org.apache.olingo.server.api.processor.ComplexProcessor;
 import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
 import org.apache.olingo.server.api.processor.PrimitiveProcessor;
+import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
+import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
+import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
+import org.apache.olingo.server.api.serializer.RepresentationType;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriInfo;
 import org.apache.olingo.server.api.uri.UriInfoResource;
@@ -53,14 +56,15 @@ import org.apache.olingo.server.api.uri.UriResource;
 import org.apache.olingo.server.api.uri.UriResourceEntitySet;
 import org.apache.olingo.server.api.uri.UriResourceKind;
 import org.apache.olingo.server.api.uri.UriResourceProperty;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
 import org.apache.olingo.server.tecsvc.data.DataProvider;
 
 /**
  * Technical Processor which provides functionality related to primitive and complex types and collections thereof.
  */
 public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
-    implements PrimitiveProcessor, PrimitiveCollectionProcessor,
-    ComplexProcessor, ComplexCollectionProcessor {
+    implements PrimitiveProcessor, PrimitiveCollectionProcessor, ComplexProcessor, ComplexCollectionProcessor {
 
   public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider) {
     super(dataProvider);
@@ -69,29 +73,29 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
   @Override
   public void readPrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
       final ContentType contentType) throws ODataApplicationException, SerializerException {
-    readProperty(response, uriInfo, contentType);
+    readProperty(response, uriInfo, contentType, RepresentationType.PRIMITIVE);
   }
 
   @Override
   public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
       final ContentType contentType) throws ODataApplicationException, SerializerException {
-    readProperty(response, uriInfo, contentType);
+    readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE);
   }
 
   @Override
   public void readComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
       final ContentType contentType) throws ODataApplicationException, SerializerException {
-    readProperty(response, uriInfo, contentType);
+    readProperty(response, uriInfo, contentType, RepresentationType.COMPLEX);
   }
 
   @Override
   public void readComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
       final ContentType contentType) throws ODataApplicationException, SerializerException {
-    readProperty(response, uriInfo, contentType);
+    readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX);
   }
 
-  private void readProperty(ODataResponse response, final UriInfo uriInfo, final ContentType contentType)
-      throws ODataApplicationException, SerializerException {
+  private void readProperty(ODataResponse response, final UriInfo uriInfo, final ContentType contentType,
+      final RepresentationType representationType) throws ODataApplicationException, SerializerException {
     final UriInfoResource resource = uriInfo.asUriInfoResource();
     validateOptions(resource);
     validatePath(resource);
@@ -113,14 +117,40 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
 
         final ODataFormat format = ODataFormat.fromContentType(contentType);
         ODataSerializer serializer = odata.createSerializer(format);
-        response.setContent(serializer.entityProperty(edmProperty, property,
-            ODataSerializerOptions.with().contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
-                ContextURL.with().entitySet(edmEntitySet)
-                    .keyPath(serializer.buildContextURLKeyPredicate(
-                        ((UriResourceEntitySet) resourceParts.get(0)).getKeyPredicates()))
-                    .navOrPropertyPath(buildPropertyPath(path))
-                    .build())
-                .build()));
+        final ExpandOption expand = uriInfo.getExpandOption();
+        final SelectOption select = uriInfo.getSelectOption();
+        final ContextURL contextURL = format == ODataFormat.JSON_NO_METADATA ? null :
+            ContextURL.with().entitySet(edmEntitySet)
+                .keyPath(serializer.buildContextURLKeyPredicate(
+                    ((UriResourceEntitySet) resourceParts.get(0)).getKeyPredicates()))
+                .navOrPropertyPath(buildPropertyPath(path))
+                .selectList(edmProperty.isPrimitive() ? null :
+                    serializer.buildContextURLSelectList((EdmStructuredType) edmProperty.getType(), expand, select))
+                .build();
+        switch (representationType) {
+        case PRIMITIVE:
+          response.setContent(serializer.primitive((EdmPrimitiveType) edmProperty.getType(), property,
+              PrimitiveSerializerOptions.with().contextURL(contextURL).facetsFrom(edmProperty).build()));
+          break;
+        case COMPLEX:
+          response.setContent(serializer.complex((EdmComplexType) edmProperty.getType(), property,
+              ComplexSerializerOptions.with().contextURL(contextURL)
+                  .expand(expand).select(select)
+                  .build()));
+          break;
+        case COLLECTION_PRIMITIVE:
+          response.setContent(serializer.primitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
+              PrimitiveSerializerOptions.with().contextURL(contextURL).facetsFrom(edmProperty).build()));
+          break;
+        case COLLECTION_COMPLEX:
+          response.setContent(serializer.complexCollection((EdmComplexType) edmProperty.getType(), property,
+              ComplexSerializerOptions.with().contextURL(contextURL)
+                  .expand(expand).select(select)
+                  .build()));
+          break;
+        default:
+          break;
+        }
         response.setStatusCode(HttpStatusCode.OK.getStatusCode());
         response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
       }
@@ -187,22 +217,11 @@ public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
     } else {
       final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
       final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
-      if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary)) {
-        response.setContent(new ByteArrayInputStream((byte[]) property.getValue()));
-      } else {
-        try {
-          final String value = type.valueToString(property.getValue(),
-              edmProperty.isNullable(), edmProperty.getMaxLength(),
-              edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
-          response.setContent(new ByteArrayInputStream(value.getBytes("UTF-8")));
-        } catch (final EdmPrimitiveTypeException e) {
-          throw new ODataApplicationException("Error in value formatting.",
-              HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
-        } catch (final UnsupportedEncodingException e) {
-          throw new ODataApplicationException("Encoding exception.",
-              HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT, e);
-        }
-      }
+      final FixedFormatSerializer serializer = odata.createFixedFormatSerializer();
+      response.setContent(type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
+          serializer.binary((byte[]) property.getValue()) :
+          serializer.primitiveValue(type, property.getValue(),
+              PrimitiveValueSerializerOptions.with().facetsFrom(edmProperty).build()));
       response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
       response.setStatusCode(HttpStatusCode.OK.getStatusCode());
     }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/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 fc65245..f0801d8 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
@@ -31,16 +31,22 @@ import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.data.ValueType;
 import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
 import org.apache.olingo.commons.api.edm.EdmEntityContainer;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.commons.core.data.PropertyImpl;
 import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.edmx.EdmxReference;
+import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.queryoption.CountOption;
 import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
@@ -58,7 +64,7 @@ import org.mockito.Mockito;
 public class ODataJsonSerializerTest {
 
   private static final Edm edm = OData.newInstance().createServiceMetadata(
-          new EdmTechProvider(), Collections.<EdmxReference>emptyList()).getEdm();
+      new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
   private static final EdmEntityContainer entityContainer = edm.getEntityContainer(
       new FullQualifiedName("olingo.odata.test1", "Container"));
   private final DataProvider data = new DataProvider();
@@ -68,8 +74,8 @@ public class ODataJsonSerializerTest {
   public void entitySimple() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build());
     final String resultString = IOUtils.toString(result);
@@ -100,8 +106,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
-    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESAllPrim/$entity\","
@@ -121,8 +127,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().clear();
-    serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build());
   }
@@ -133,8 +139,8 @@ public class ODataJsonSerializerTest {
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().get(0).setValue(ValueType.PRIMITIVE, false);
     try {
-      serializer.entity(edmEntitySet, entity,
-          ODataSerializerOptions.with()
+      serializer.entity(edmEntitySet.getEntityType(), entity,
+          EntitySerializerOptions.with()
               .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
               .build());
       Assert.fail("Expected exception not thrown!");
@@ -154,8 +160,8 @@ public class ODataJsonSerializerTest {
     entitySet.setNext(URI.create("/next"));
     CountOption countOption = Mockito.mock(CountOption.class);
     Mockito.when(countOption.getValue()).thenReturn(true);
-    InputStream result = serializer.entitySet(edmEntitySet, entitySet,
-        ODataSerializerOptions.with()
+    InputStream result = serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
+        EntityCollectionSerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).build())
             .count(countOption)
             .build());
@@ -179,8 +185,8 @@ public class ODataJsonSerializerTest {
   public void entityCollAllPrim() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCollAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().serviceRoot(URI.create("http://host/service/"))
                 .entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build());
@@ -215,8 +221,8 @@ public class ODataJsonSerializerTest {
   public void entityCompAllPrim() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build());
     final String resultString = IOUtils.toString(result);
@@ -248,8 +254,8 @@ public class ODataJsonSerializerTest {
   public void entityMixPrimCollComp() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
-    InputStream result = serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build());
     final String resultString = IOUtils.toString(result);
@@ -271,8 +277,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.getProperties().retainAll(Arrays.asList(entity.getProperties().get(0)));
-    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESMixPrimCollComp/$entity\","
@@ -286,7 +292,7 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
-        .entity(edmEntitySet, entity, null);
+        .entity(edmEntitySet.getEntityType(), entity, null);
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{\"PropertyInt16\":32766,\"PropertyString\":\"Test String1\"}";
     Assert.assertEquals(expectedResult, resultString);
@@ -297,8 +303,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
     final EntitySet entitySet = data.readAll(edmEntitySet);
     InputStream result = new ODataJsonSerializer(ODataFormat.JSON_NO_METADATA)
-        .entitySet(edmEntitySet, entitySet,
-            ODataSerializerOptions.with()
+        .entityCollection(edmEntitySet.getEntityType(), entitySet,
+            EntityCollectionSerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet).build()).build());
     final String resultString = IOUtils.toString(result);
     final String expectedResult = "{\"value\":["
@@ -314,8 +320,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
     Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     entity.setMediaETag("theMediaETag");
-    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    final String resultString = IOUtils.toString(serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia/$entity\","
@@ -328,8 +334,8 @@ public class ODataJsonSerializerTest {
   public void entitySetMedia() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMedia");
     final EntitySet entitySet = data.readAll(edmEntitySet);
-    final String resultString = IOUtils.toString(serializer.entitySet(edmEntitySet, entitySet,
-        ODataSerializerOptions.with()
+    final String resultString = IOUtils.toString(serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
+        EntityCollectionSerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).build()).build()));
     final String expectedResult = "{\"@odata.context\":\"$metadata#ESMedia\",\"value\":["
         + "{\"@odata.mediaContentType\":\"image/png\",\"PropertyInt16\":1},"
@@ -342,16 +348,17 @@ public class ODataJsonSerializerTest {
   @Test
   public void select() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     final SelectItem selectItem1 = ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyDate");
     final SelectItem selectItem2 = ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyBoolean");
     final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
         selectItem1, selectItem2, selectItem2));
     InputStream result = serializer
-        .entity(edmEntitySet, entity,
-            ODataSerializerOptions.with()
+        .entity(entityType, entity,
+            EntitySerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet)
-                    .selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
+                    .selectList(serializer.buildContextURLSelectList(entityType, null, select))
                     .suffix(Suffix.ENTITY).build())
                 .select(select)
                 .build());
@@ -370,8 +377,8 @@ public class ODataJsonSerializerTest {
     SelectItem selectItem2 = Mockito.mock(SelectItem.class);
     Mockito.when(selectItem2.isStar()).thenReturn(true);
     final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(selectItem1, selectItem2));
-    InputStream result = serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .select(select)
             .build());
@@ -384,14 +391,15 @@ public class ODataJsonSerializerTest {
   @Test
   public void selectComplex() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
     final EntitySet entitySet = data.readAll(edmEntitySet);
     final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
         ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString")));
     InputStream result = serializer
-        .entitySet(edmEntitySet, entitySet,
-            ODataSerializerOptions.with()
+        .entityCollection(entityType, entitySet,
+            EntityCollectionSerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet)
-                    .selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
+                    .selectList(serializer.buildContextURLSelectList(entityType, null, select))
                     .build())
                 .select(select)
                 .build());
@@ -407,15 +415,16 @@ public class ODataJsonSerializerTest {
   @Test
   public void selectComplexTwice() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESCompComp");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
     final EntitySet entitySet = data.readAll(edmEntitySet);
     final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
         ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp", "PropertyString"),
         ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyComp", "PropertyComp")));
     final String resultString = IOUtils.toString(serializer
-        .entitySet(edmEntitySet, entitySet,
-            ODataSerializerOptions.with()
+        .entityCollection(entityType, entitySet,
+            EntityCollectionSerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet)
-                    .selectList(serializer.buildContextURLSelectList(edmEntitySet, null, select))
+                    .selectList(serializer.buildContextURLSelectList(entityType, null, select))
                     .build())
                 .select(select)
                 .build()));
@@ -433,8 +442,8 @@ public class ODataJsonSerializerTest {
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(3);
     final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(
         ExpandSelectMock.mockExpandItem(edmEntitySet, "NavPropertyETAllPrimOne")));
-    InputStream result = serializer.entity(edmEntitySet, entity,
-        ODataSerializerOptions.with()
+    InputStream result = serializer.entity(edmEntitySet.getEntityType(), entity,
+        EntitySerializerOptions.with()
             .contextURL(ContextURL.with().entitySet(edmEntitySet).suffix(Suffix.ENTITY).build())
             .expand(expand)
             .build());
@@ -464,6 +473,7 @@ public class ODataJsonSerializerTest {
   @Test
   public void expandSelect() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(3);
     final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
         ExpandSelectMock.mockSelectItem(entityContainer.getEntitySet("ESAllPrim"), "PropertyDate")));
@@ -471,10 +481,10 @@ public class ODataJsonSerializerTest {
     Mockito.when(expandItem.getSelectOption()).thenReturn(select);
     final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(expandItem));
     final String resultString = IOUtils.toString(serializer
-        .entity(edmEntitySet, entity,
-            ODataSerializerOptions.with()
+        .entity(entityType, entity,
+            EntitySerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet)
-                    .selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
+                    .selectList(serializer.buildContextURLSelectList(entityType, expand, select))
                     .suffix(Suffix.ENTITY).build())
                 .expand(expand)
                 .build()));
@@ -488,6 +498,7 @@ public class ODataJsonSerializerTest {
   @Test
   public void expandAll() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(0);
     final ExpandItem expandItem = ExpandSelectMock.mockExpandItem(edmEntitySet, "NavPropertyETTwoPrimOne");
     ExpandItem expandItemAll = Mockito.mock(ExpandItem.class);
@@ -497,10 +508,10 @@ public class ODataJsonSerializerTest {
     final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
         ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertySByte")));
     final String resultString = IOUtils.toString(serializer
-        .entity(edmEntitySet, entity,
-            ODataSerializerOptions.with()
+        .entity(entityType, entity,
+            EntitySerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet)
-                    .selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
+                    .selectList(serializer.buildContextURLSelectList(entityType, expand, select))
                     .suffix(Suffix.ENTITY).build())
                 .expand(expand)
                 .select(select)
@@ -516,6 +527,7 @@ public class ODataJsonSerializerTest {
   @Test
   public void expandNoData() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(1);
     ExpandItem expandItemAll = Mockito.mock(ExpandItem.class);
     Mockito.when(expandItemAll.isStar()).thenReturn(true);
@@ -523,10 +535,10 @@ public class ODataJsonSerializerTest {
     final SelectOption select = ExpandSelectMock.mockSelectOption(Arrays.asList(
         ExpandSelectMock.mockSelectItem(edmEntitySet, "PropertyTimeOfDay")));
     final String resultString = IOUtils.toString(serializer
-        .entity(edmEntitySet, entity,
-            ODataSerializerOptions.with()
+        .entity(entityType, entity,
+            EntitySerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet)
-                    .selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
+                    .selectList(serializer.buildContextURLSelectList(entityType, expand, select))
                     .suffix(Suffix.ENTITY).build())
                 .expand(expand)
                 .select(select)
@@ -541,6 +553,7 @@ public class ODataJsonSerializerTest {
   @Test
   public void expandTwoLevels() throws Exception {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESTwoPrim");
+    final EdmEntityType entityType = edmEntitySet.getEntityType();
     final EdmEntitySet innerEntitySet = entityContainer.getEntitySet("ESAllPrim");
     final Entity entity = data.readAll(edmEntitySet).getEntities().get(1);
     ExpandItem expandItemSecond = Mockito.mock(ExpandItem.class);
@@ -553,10 +566,10 @@ public class ODataJsonSerializerTest {
     Mockito.when(expandItemFirst.getSelectOption()).thenReturn(select);
     final ExpandOption expand = ExpandSelectMock.mockExpandOption(Arrays.asList(expandItemFirst));
     final String resultString = IOUtils.toString(serializer
-        .entity(edmEntitySet, entity,
-            ODataSerializerOptions.with()
+        .entity(entityType, entity,
+            EntitySerializerOptions.with()
                 .contextURL(ContextURL.with().entitySet(edmEntitySet)
-                    .selectList(serializer.buildContextURLSelectList(edmEntitySet, expand, select))
+                    .selectList(serializer.buildContextURLSelectList(entityType, expand, select))
                     .suffix(Suffix.ENTITY).build())
                 .expand(expand)
                 .build()));
@@ -579,8 +592,8 @@ public class ODataJsonSerializerTest {
     final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString");
     final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName());
     final String resultString = IOUtils.toString(serializer
-        .entityProperty(edmProperty, property,
-            ODataSerializerOptions.with()
+        .primitive((EdmPrimitiveType) edmProperty.getType(), property,
+            PrimitiveSerializerOptions.with()
                 .contextURL(ContextURL.with()
                     .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName())
                     .build())
@@ -596,8 +609,8 @@ public class ODataJsonSerializerTest {
     final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESAllPrim");
     final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("PropertyString");
     final Property property = new PropertyImpl("Edm.String", edmProperty.getName(), ValueType.PRIMITIVE, null);
-    serializer.entityProperty(edmProperty, property,
-        ODataSerializerOptions.with()
+    serializer.primitive((EdmPrimitiveType) edmProperty.getType(), property,
+        PrimitiveSerializerOptions.with()
             .contextURL(ContextURL.with()
                 .entitySet(edmEntitySet).keyPath("4242").navOrPropertyPath(edmProperty.getName())
                 .build())
@@ -611,8 +624,8 @@ public class ODataJsonSerializerTest {
     final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName());
 
     final String resultString = IOUtils.toString(serializer
-        .entityProperty(edmProperty, property,
-            ODataSerializerOptions.with()
+        .primitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
+            PrimitiveSerializerOptions.with()
                 .contextURL(ContextURL.with()
                     .entitySet(edmEntitySet).keyPath("1").navOrPropertyPath(edmProperty.getName())
                     .build())
@@ -630,8 +643,8 @@ public class ODataJsonSerializerTest {
     final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty("PropertyComp");
 
     final String resultString = IOUtils.toString(serializer
-        .entityProperty(edmProperty, property,
-            ODataSerializerOptions.with()
+        .complex((EdmComplexType) edmProperty.getType(), property,
+            ComplexSerializerOptions.with()
                 .contextURL(ContextURL.with()
                     .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName())
                     .build())
@@ -641,4 +654,25 @@ public class ODataJsonSerializerTest {
             + "\"PropertyInt16\":111,\"PropertyString\":\"TEST A\"}",
         resultString);
   }
+
+  @Test
+  public void complexCollectionProperty() throws Exception {
+    final EdmEntitySet edmEntitySet = entityContainer.getEntitySet("ESMixPrimCollComp");
+    final EdmProperty edmProperty = (EdmProperty) edmEntitySet.getEntityType().getProperty("CollPropertyComp");
+    final Property property = data.readAll(edmEntitySet).getEntities().get(0).getProperty(edmProperty.getName());
+
+    final String resultString = IOUtils.toString(serializer
+        .complexCollection((EdmComplexType) edmProperty.getType(), property,
+            ComplexSerializerOptions.with()
+                .contextURL(ContextURL.with()
+                    .entitySet(edmEntitySet).keyPath("32767").navOrPropertyPath(edmProperty.getName())
+                    .build())
+                .build()));
+    Assert.assertEquals("{"
+            + "\"@odata.context\":\"$metadata#ESMixPrimCollComp(32767)/CollPropertyComp\","
+            + "\"value\":[{\"PropertyInt16\":123,\"PropertyString\":\"TEST 1\"},"
+            + "{\"PropertyInt16\":456,\"PropertyString\":\"TEST 2\"},"
+            + "{\"PropertyInt16\":789,\"PropertyString\":\"TEST 3\"}]}",
+        resultString);
+  }
 }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/samples/server/src/main/java/org/apache/olingo/server/sample/data/DataProvider.java
----------------------------------------------------------------------
diff --git a/samples/server/src/main/java/org/apache/olingo/server/sample/data/DataProvider.java b/samples/server/src/main/java/org/apache/olingo/server/sample/data/DataProvider.java
index 80609aa..d59d251 100644
--- a/samples/server/src/main/java/org/apache/olingo/server/sample/data/DataProvider.java
+++ b/samples/server/src/main/java/org/apache/olingo/server/sample/data/DataProvider.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 
 import org.apache.olingo.commons.api.ODataException;
 import org.apache.olingo.commons.api.data.Entity;
@@ -41,8 +40,6 @@ import org.apache.olingo.server.api.uri.UriParameter;
 
 public class DataProvider {
 
-  private static final UUID GUID = UUID.fromString("01234567-89ab-cdef-0123-456789abcdef");
-
   private Map<String, EntitySet> data;
 
   public DataProvider() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java
----------------------------------------------------------------------
diff --git a/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java b/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java
index bf3aa17..5cfce31 100644
--- a/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java
+++ b/samples/server/src/main/java/org/apache/olingo/server/sample/processor/CarsProcessor.java
@@ -27,7 +27,9 @@ import org.apache.olingo.commons.api.data.ContextURL.Suffix;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
 import org.apache.olingo.commons.api.edm.EdmEntitySet;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
 import org.apache.olingo.commons.api.edm.EdmProperty;
 import org.apache.olingo.commons.api.format.ContentType;
 import org.apache.olingo.commons.api.format.ODataFormat;
@@ -38,14 +40,15 @@ import org.apache.olingo.server.api.ODataApplicationException;
 import org.apache.olingo.server.api.ODataRequest;
 import org.apache.olingo.server.api.ODataResponse;
 import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
 import org.apache.olingo.server.api.processor.ComplexProcessor;
 import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
 import org.apache.olingo.server.api.processor.EntityProcessor;
-import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
 import org.apache.olingo.server.api.processor.PrimitiveProcessor;
+import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriInfo;
 import org.apache.olingo.server.api.uri.UriInfoResource;
@@ -62,8 +65,8 @@ import org.apache.olingo.server.sample.data.DataProvider.DataProviderException;
  * This is a very simple example which should give you a rough guideline on how to implement such an processor.
  * See the JavaDoc of the server.api interfaces for more information.
  */
-public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor, PrimitiveProcessor,
-    PrimitiveCollectionProcessor, ComplexProcessor, ComplexCollectionProcessor {
+public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor,
+    PrimitiveProcessor, ComplexProcessor {
 
   private OData odata;
   private DataProvider dataProvider;
@@ -97,8 +100,8 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor
     // Now the content is serialized using the serializer.
     final ExpandOption expand = uriInfo.getExpandOption();
     final SelectOption select = uriInfo.getSelectOption();
-    InputStream serializedContent = serializer.entitySet(edmEntitySet, entitySet,
-        ODataSerializerOptions.with()
+    InputStream serializedContent = serializer.entityCollection(edmEntitySet.getEntityType(), entitySet,
+        EntityCollectionSerializerOptions.with()
             .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
                 getContextUrl(serializer, edmEntitySet, false, expand, select, null))
             .count(uriInfo.getCountOption())
@@ -135,11 +138,10 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor
       ODataSerializer serializer = odata.createSerializer(format);
       final ExpandOption expand = uriInfo.getExpandOption();
       final SelectOption select = uriInfo.getSelectOption();
-      InputStream serializedContent = serializer.entity(edmEntitySet, entity,
-          ODataSerializerOptions.with()
+      InputStream serializedContent = serializer.entity(edmEntitySet.getEntityType(), entity,
+          EntitySerializerOptions.with()
               .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
                   getContextUrl(serializer, edmEntitySet, true, expand, select, null))
-              .count(uriInfo.getCountOption())
               .expand(expand).select(select)
               .build());
       response.setContent(serializedContent);
@@ -148,8 +150,8 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor
     }
   }
 
-  private void readProperty(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType contentType)
-      throws ODataApplicationException, SerializerException {
+  private void readProperty(ODataResponse response, UriInfo uriInfo, ContentType contentType,
+      boolean complex) throws ODataApplicationException, SerializerException {
     // To read a property we have to first get the entity out of the entity set
     final EdmEntitySet edmEntitySet = getEdmEntitySet(uriInfo.asUriInfoResource());
     Entity entity;
@@ -178,11 +180,13 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor
         } else {
           final ODataFormat format = ODataFormat.fromContentType(contentType);
           ODataSerializer serializer = odata.createSerializer(format);
-          InputStream serializerContent = serializer.entityProperty(edmProperty, property,
-              ODataSerializerOptions.with()
-                  .contextURL(format == ODataFormat.JSON_NO_METADATA ? null :
-                      getContextUrl(serializer, edmEntitySet, true, null, null, edmProperty.getName()))
-                  .build());
+          final ContextURL contextURL = format == ODataFormat.JSON_NO_METADATA ? null :
+              getContextUrl(serializer, edmEntitySet, true, null, null, edmProperty.getName());
+          InputStream serializerContent = complex ?
+              serializer.complex((EdmComplexType) edmProperty.getType(), property,
+                  ComplexSerializerOptions.with().contextURL(contextURL).build()) :
+              serializer.primitive((EdmPrimitiveType) edmProperty.getType(), property,
+                  PrimitiveSerializerOptions.with().contextURL(contextURL).build());
           response.setContent(serializerContent);
           response.setStatusCode(HttpStatusCode.OK.getStatusCode());
           response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
@@ -222,41 +226,28 @@ public class CarsProcessor implements EntityCollectionProcessor, EntityProcessor
       throws SerializerException {
 
     return ContextURL.with().entitySet(entitySet)
-        .selectList(serializer.buildContextURLSelectList(entitySet, expand, select))
+        .selectList(serializer.buildContextURLSelectList(entitySet.getEntityType(), expand, select))
         .suffix(isSingleEntity ? Suffix.ENTITY : null)
         .navOrPropertyPath(navOrPropertyPath)
         .build();
   }
 
   @Override
-  public void readComplexCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
-      ContentType format) throws ODataApplicationException, SerializerException {
-    readProperty(request, response, uriInfo, format);
+  public void readPrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+      throws ODataApplicationException, SerializerException {
+    readProperty(response, uriInfo, format, false);
   }
 
   @Override
   public void readComplex(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
       throws ODataApplicationException, SerializerException {
-    readProperty(request, response, uriInfo, format);
-  }
-
-  @Override
-  public void readPrimitiveCollection(ODataRequest request, ODataResponse response, UriInfo uriInfo,
-      ContentType format) throws ODataApplicationException, SerializerException {
-    readProperty(request, response, uriInfo, format);
+    readProperty(response, uriInfo, format, true);
   }
 
   @Override
-  public void readPrimitive(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
+  public void readPrimitiveAsValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
       throws ODataApplicationException, SerializerException {
-    readProperty(request, response, uriInfo, format);
-  }
-
-  @Override
-  public void
-      readPrimitiveAsValue(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType format)
-          throws ODataApplicationException, SerializerException {
-    throw new ODataApplicationException("Not implemented for this sample", HttpStatusCode.NOT_IMPLEMENTED
-     .getStatusCode(), Locale.ENGLISH);
+    throw new ODataApplicationException("Not implemented for this sample",
+        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ENGLISH);
   }
 }


[2/2] olingo-odata4 git commit: [OLINGO-485] refactored server serializers

Posted by mi...@apache.org.
[OLINGO-485] refactored server serializers

Change-Id: Ida1f2b24885d2a43063bed766d93223c96079d9a

Signed-off-by: Michael Bolz <mi...@sap.com>


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

Branch: refs/heads/master
Commit: c2c8bf1960882d4ccb25de2c07cd9ff2be4c3553
Parents: dd22756
Author: Klaus Straubinger <kl...@sap.com>
Authored: Thu Nov 13 09:56:41 2014 +0100
Committer: Michael Bolz <mi...@sap.com>
Committed: Thu Nov 13 10:57:28 2014 +0100

----------------------------------------------------------------------
 .../org/apache/olingo/server/api/OData.java     |   9 +-
 .../serializer/ComplexSerializerOptions.java    |  86 +++++++
 .../EntityCollectionSerializerOptions.java      |  97 +++++++
 .../api/serializer/EntitySerializerOptions.java |  85 +++++++
 .../api/serializer/FixedFormatSerializer.java   |  48 ++++
 .../server/api/serializer/ODataSerializer.java  |  75 ++++--
 .../api/serializer/ODataSerializerOptions.java  |  99 --------
 .../serializer/PrimitiveSerializerOptions.java  | 131 ++++++++++
 .../PrimitiveValueSerializerOptions.java        | 118 +++++++++
 .../api/serializer/SerializerException.java     |   3 +-
 .../apache/olingo/server/core/ODataImpl.java    |   9 +-
 .../serializer/FixedFormatSerializerImpl.java   |  59 +++++
 .../core/serializer/ODataXmlSerializerImpl.java | 126 ----------
 .../serializer/json/ODataJsonSerializer.java    | 250 +++++++++++++------
 .../serializer/utils/ContextURLBuilder.java     |   6 +-
 .../core/serializer/utils/ContextURLHelper.java |  26 +-
 .../serializer/xml/ODataXmlSerializerImpl.java  | 154 ++++++++++++
 .../server-core-exceptions-i18n.properties      |   1 +
 .../serializer/FixedFormatSerializerTest.java   |  57 +++++
 .../serializer/utils/ContextURLBuilderTest.java |   5 +-
 .../processor/TechnicalEntityProcessor.java     |  17 +-
 .../TechnicalPrimitiveComplexProcessor.java     |  91 ++++---
 .../json/ODataJsonSerializerTest.java           | 154 +++++++-----
 .../olingo/server/sample/data/DataProvider.java |   3 -
 .../server/sample/processor/CarsProcessor.java  |  67 +++--
 25 files changed, 1291 insertions(+), 485 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/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 67408d1..2a6eb1b 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
@@ -22,6 +22,7 @@ import org.apache.olingo.commons.api.ODataRuntimeException;
 import org.apache.olingo.server.api.edmx.EdmxReference;
 import org.apache.olingo.commons.api.format.ODataFormat;
 import org.apache.olingo.server.api.edm.provider.EdmProvider;
+import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.api.serializer.SerializerException;
 
@@ -57,11 +58,17 @@ public abstract class OData {
    * Creates a new serializer object for rendering content in the specified format.
    * Serializers are used in Processor implementations.
    *
-   * @param format - any format supported by Olingo (XML, JSON ...)
+   * @param format any format supported by Olingo (XML, JSON ...)
    */
   public abstract ODataSerializer createSerializer(ODataFormat format) throws SerializerException;
 
   /**
+   * Creates a new serializer object for rendering content in a fixed format, e.g., for binary output.
+   * Serializers are used in Processor implementations.
+   */
+  public abstract FixedFormatSerializer createFixedFormatSerializer() throws SerializerException;
+
+  /**
    * Creates a new ODataHttpHandler for handling OData requests in an HTTP context.
    *
    * @param serviceMetadata - metadata object required to handle an OData request

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java
new file mode 100644
index 0000000..d6788e5
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ComplexSerializerOptions.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.serializer;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+
+/** Options for the OData serializer. */
+public class ComplexSerializerOptions {
+
+  private ContextURL contextURL;
+  private ExpandOption expand;
+  private SelectOption select;
+
+  /** Gets the {@link ContextURL}. */
+  public ContextURL getContextURL() {
+    return contextURL;
+  }
+
+  /** Gets the $expand system query option. */
+  public ExpandOption getExpand() {
+    return expand;
+  }
+
+  /** Gets the $select system query option. */
+  public SelectOption getSelect() {
+    return select;
+  }
+
+  private ComplexSerializerOptions() {}
+
+  /** Initializes the options builder. */
+  public static Builder with() {
+    return new Builder();
+  }
+
+  /** Builder of OData serializer options. */
+  public static final class Builder {
+
+    private ComplexSerializerOptions options;
+
+    private Builder() {
+      options = new ComplexSerializerOptions();
+    }
+
+    /** Sets the {@link ContextURL}. */
+    public Builder contextURL(final ContextURL contextURL) {
+      options.contextURL = contextURL;
+      return this;
+    }
+
+    /** Sets the $expand system query option. */
+    public Builder expand(final ExpandOption expand) {
+      options.expand = expand;
+      return this;
+    }
+
+    /** Sets the $select system query option. */
+    public Builder select(final SelectOption select) {
+      options.select = select;
+      return this;
+    }
+
+    /** Builds the OData serializer options. */
+    public ComplexSerializerOptions build() {
+      return options;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
new file mode 100644
index 0000000..14c588d
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntityCollectionSerializerOptions.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.serializer;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.server.api.uri.queryoption.CountOption;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+
+/** Options for the OData serializer. */
+public class EntityCollectionSerializerOptions {
+
+  private ContextURL contextURL;
+  private CountOption count;
+  private ExpandOption expand;
+  private SelectOption select;
+
+  /** Gets the {@link ContextURL}. */
+  public ContextURL getContextURL() {
+    return contextURL;
+  }
+
+  /** Gets the $count system query option. */
+  public CountOption getCount() {
+    return count;
+  }
+
+  /** Gets the $expand system query option. */
+  public ExpandOption getExpand() {
+    return expand;
+  }
+
+  /** Gets the $select system query option. */
+  public SelectOption getSelect() {
+    return select;
+  }
+
+  /** Initializes the options builder. */
+  public static Builder with() {
+    return new Builder();
+  }
+
+  /** Builder of OData serializer options. */
+  public static final class Builder {
+
+    private EntityCollectionSerializerOptions options;
+
+    private Builder() {
+      options = new EntityCollectionSerializerOptions();
+    }
+
+    /** Sets the {@link ContextURL}. */
+    public Builder contextURL(final ContextURL contextURL) {
+      options.contextURL = contextURL;
+      return this;
+    }
+
+    /** Sets the $count system query option. */
+    public Builder count(final CountOption count) {
+      options.count = count;
+      return this;
+    }
+
+    /** Sets the $expand system query option. */
+    public Builder expand(final ExpandOption expand) {
+      options.expand = expand;
+      return this;
+    }
+
+    /** Sets the $select system query option. */
+    public Builder select(final SelectOption select) {
+      options.select = select;
+      return this;
+    }
+
+    /** Builds the OData serializer options. */
+    public EntityCollectionSerializerOptions build() {
+      return options;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
new file mode 100644
index 0000000..7805fb0
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/EntitySerializerOptions.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.serializer;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+
+/** Options for the OData serializer. */
+public class EntitySerializerOptions {
+  private ContextURL contextURL;
+  private ExpandOption expand;
+  private SelectOption select;
+
+  /** Gets the {@link ContextURL}. */
+  public ContextURL getContextURL() {
+    return contextURL;
+  }
+
+  /** Gets the $expand system query option. */
+  public ExpandOption getExpand() {
+    return expand;
+  }
+
+  /** Gets the $select system query option. */
+  public SelectOption getSelect() {
+    return select;
+  }
+
+  private EntitySerializerOptions() {}
+
+  /** Initializes the options builder. */
+  public static final Builder with() {
+    return new Builder();
+  }
+
+  /** Builder of OData serializer options. */
+  public static final class Builder {
+
+    private EntitySerializerOptions options;
+
+    private Builder() {
+      options = new EntitySerializerOptions();
+    }
+
+    /** Sets the {@link ContextURL}. */
+    public Builder contextURL(final ContextURL contextURL) {
+      options.contextURL = contextURL;
+      return this;
+    }
+
+    /** Sets the $expand system query option. */
+    public Builder expand(final ExpandOption expand) {
+      options.expand = expand;
+      return this;
+    }
+
+    /** Sets the $select system query option. */
+    public Builder select(final SelectOption select) {
+      options.select = select;
+      return this;
+    }
+
+    /** Builds the OData serializer options. */
+    public EntitySerializerOptions build() {
+      return options;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/FixedFormatSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/FixedFormatSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/FixedFormatSerializer.java
new file mode 100644
index 0000000..22416b3
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/FixedFormatSerializer.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.serializer;
+
+import java.io.InputStream;
+
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+
+/** OData serializer for fixed output formats. */
+public interface FixedFormatSerializer {
+
+  /**
+   * Writes binary output into an InputStream.
+   * @param binary the binary data 
+   */
+  InputStream binary(byte[] binary) throws SerializerException;
+
+  /**
+   * Writes a count into an InputStream as plain text.
+   * @param count the count
+   */
+  InputStream count(Integer count) throws SerializerException;
+
+  /**
+   * Writes the raw value of a primitive-type instance into an InputStream.
+   * @param type    the primitive type
+   * @param value   the value
+   * @param options options for the serializer
+   */
+  InputStream primitiveValue(EdmPrimitiveType type, Object value, PrimitiveValueSerializerOptions options)
+      throws SerializerException;
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
index 2072798..2f16be1 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializer.java
@@ -25,8 +25,10 @@ import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.uri.UriParameter;
@@ -53,47 +55,74 @@ public interface ODataSerializer {
   InputStream metadataDocument(ServiceMetadata serviceMetadata) throws SerializerException;
 
   /**
+   * Writes an ODataError into an InputStream.
+   * @param error the main error
+   * @return inputStream containing the OData-formatted error
+   */
+  InputStream error(ODataServerError error) throws SerializerException;
+
+  /**
+   * Writes entity-collection data into an InputStream.
+   * @param entityType the {@link EdmEntityType}
+   * @param entitySet  the data of the entity set
+   * @param options    options for the serializer
+   */
+  InputStream entityCollection(EdmEntityType entityType, EntitySet entitySet,
+      EntityCollectionSerializerOptions options) throws SerializerException;
+
+  /**
    * Writes entity data into an InputStream.
-   * @param edmEntitySet the {@link EdmEntitySet}
-   * @param entity       the data of the entity
-   * @param options      options for the serializer
+   * @param entityType the {@link EdmEntityType}
+   * @param entity     the data of the entity
+   * @param options    options for the serializer
    */
-  InputStream entity(EdmEntitySet edmEntitySet, Entity entity, ODataSerializerOptions options)
+  InputStream entity(EdmEntityType entityType, Entity entity, EntitySerializerOptions options)
       throws SerializerException;
 
   /**
-   * Writes entity data into an InputStream.
-   * @param edmProperty property definition
+   * Writes primitive-type instance data into an InputStream.
+   * @param type     primitive type
    * @param property property value
    * @param options options for the serializer
    */
-  InputStream entityProperty(EdmProperty edmProperty, Property property, ODataSerializerOptions options)
-          throws SerializerException;
+  InputStream primitive(EdmPrimitiveType type, Property property, PrimitiveSerializerOptions options)
+      throws SerializerException;
 
   /**
-   * Writes entity-set data into an InputStream.
-   * @param edmEntitySet the {@link EdmEntitySet}
-   * @param entitySet    the data of the entity set
-   * @param options      options for the serializer
+   * Writes complex-type instance data into an InputStream.
+   * @param type     complex type
+   * @param property property value
+   * @param options options for the serializer
    */
-  InputStream entitySet(EdmEntitySet edmEntitySet, EntitySet entitySet, ODataSerializerOptions options)
+  InputStream complex(EdmComplexType type, Property property, ComplexSerializerOptions options)
       throws SerializerException;
 
   /**
-   * Writes an ODataError into an InputStream.
-   * @param error the main error
-   * @return inputStream containing the OData-formatted error
+   * Writes data of a collection of primitive-type instances into an InputStream.
+   * @param type     primitive type
+   * @param property property value
+   * @param options options for the serializer
    */
-  InputStream error(ODataServerError error) throws SerializerException;
+  InputStream primitiveCollection(EdmPrimitiveType type, Property property, PrimitiveSerializerOptions options)
+      throws SerializerException;
+
+  /**
+   * Writes data of a collection of complex-type instances into an InputStream.
+   * @param type     complex type
+   * @param property property value
+   * @param options options for the serializer
+   */
+  InputStream complexCollection(EdmComplexType type, Property property, ComplexSerializerOptions options)
+      throws SerializerException;
 
   /**
    * Builds the select-list part of a {@link org.apache.olingo.commons.api.data.ContextURL ContextURL}.
-   * @param edmEntitySet the Entity Set
-   * @param expand       the $expand option
-   * @param select       the $select option
+   * @param type   the {@link EdmStructuredType}
+   * @param expand the $expand option
+   * @param select the $select option
    * @return a String with the select list
    */
-  String buildContextURLSelectList(EdmEntitySet edmEntitySet, ExpandOption expand, SelectOption select)
+  String buildContextURLSelectList(EdmStructuredType type, ExpandOption expand, SelectOption select)
       throws SerializerException;
 
   /**

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializerOptions.java
deleted file mode 100644
index e4ac767..0000000
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/ODataSerializerOptions.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.server.api.serializer;
-
-import org.apache.olingo.commons.api.data.ContextURL;
-import org.apache.olingo.server.api.uri.queryoption.CountOption;
-import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
-import org.apache.olingo.server.api.uri.queryoption.SelectOption;
-
-/** Options for the OData serializer. */
-public class ODataSerializerOptions {
-
-  private ContextURL contextURL;
-  private CountOption count;
-  private ExpandOption expand;
-  private SelectOption select;
-
-  /** Gets the {@link ContextURL}. */
-  public ContextURL getContextURL() {
-    return contextURL;
-  }
-
-  /** Gets the $count system query option. */
-  public CountOption getCount() {
-    return count;
-  }
-
-  /** Gets the $expand system query option. */
-  public ExpandOption getExpand() {
-    return expand;
-  }
-
-  /** Gets the $select system query option. */
-  public SelectOption getSelect() {
-    return select;
-  }
-
-  private ODataSerializerOptions() {}
-
-  /** Initializes the options builder. */
-  public static Builder with() {
-    return new Builder();
-  }
-
-  /** Builder of OData serializer options. */
-  public static final class Builder {
-
-    private ODataSerializerOptions options;
-
-    private Builder() {
-      options = new ODataSerializerOptions();
-    }
-
-    /** Sets the {@link ContextURL}. */
-    public Builder contextURL(final ContextURL contextURL) {
-      options.contextURL = contextURL;
-      return this;
-    }
-
-    /** Sets the $count system query option. */
-    public Builder count(final CountOption count) {
-      options.count = count;
-      return this;
-    }
-
-    /** Sets the $expand system query option. */
-    public Builder expand(final ExpandOption expand) {
-      options.expand = expand;
-      return this;
-    }
-
-    /** Sets the $select system query option. */
-    public Builder select(final SelectOption select) {
-      options.select = select;
-      return this;
-    }
-
-    /** Builds the OData serializer options. */
-    public ODataSerializerOptions build() {
-      return options;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java
new file mode 100644
index 0000000..9339592
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveSerializerOptions.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.serializer;
+
+import org.apache.olingo.commons.api.data.ContextURL;
+import org.apache.olingo.commons.api.edm.EdmProperty;
+
+/** Options for the OData serializer. */
+public class PrimitiveSerializerOptions {
+
+  private ContextURL contextURL;
+  private Boolean isNullable;
+  private Integer maxLength;
+  private Integer precision;
+  private Integer scale;
+  private Boolean isUnicode;
+
+  /** Gets the {@link ContextURL}. */
+  public ContextURL getContextURL() {
+    return contextURL;
+  }
+
+  /** Gets the nullable facet. */
+  public Boolean isNullable() {
+    return isNullable;
+  }
+
+  /** Gets the maxLength facet. */
+  public Integer getMaxLength() {
+    return maxLength;
+  }
+
+  /** Gets the precision facet. */
+  public Integer getPrecision() {
+    return precision;
+  }
+
+  /** Gets the scale facet. */
+  public Integer getScale() {
+    return scale;
+  }
+
+  /** Gets the unicode facet. */
+  public Boolean isUnicode() {
+    return isUnicode;
+  }
+
+  private PrimitiveSerializerOptions() {}
+
+  /** Initializes the options builder. */
+  public static Builder with() {
+    return new Builder();
+  }
+
+  /** Builder of OData serializer options. */
+  public static final class Builder {
+
+    private PrimitiveSerializerOptions options;
+
+    private Builder() {
+      options = new PrimitiveSerializerOptions();
+    }
+
+    /** Sets the {@link ContextURL}. */
+    public Builder contextURL(final ContextURL contextURL) {
+      options.contextURL = contextURL;
+      return this;
+    }
+
+    /** Sets the nullable facet. */
+    public Builder nullable(final Boolean isNullable) {
+      options.isNullable = isNullable;
+      return this;
+    }
+
+    /** Sets the maxLength facet. */
+    public Builder maxLength(final Integer maxLength) {
+      options.maxLength = maxLength;
+      return this;
+    }
+
+    /** Sets the precision facet. */
+    public Builder precision(final Integer precision) {
+      options.precision = precision;
+      return this;
+    }
+
+    /** Sets the scale facet. */
+    public Builder scale(final Integer scale) {
+      options.scale = scale;
+      return this;
+    }
+
+    /** Sets the unicode facet. */
+    public Builder unicode(final Boolean isUnicode) {
+      options.isUnicode = isUnicode;
+      return this;
+    }
+
+    /** Sets all facets from an EDM property. */
+    public Builder facetsFrom(final EdmProperty property) {
+      options.isNullable = property.isNullable();
+      options.maxLength = property.getMaxLength();
+      options.precision = property.getPrecision();
+      options.scale = property.getScale();
+      options.isUnicode = property.isUnicode();
+      return this;
+    }
+
+    /** Builds the OData serializer options. */
+    public PrimitiveSerializerOptions build() {
+      return options;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java
new file mode 100644
index 0000000..e84aaa4
--- /dev/null
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/PrimitiveValueSerializerOptions.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.api.serializer;
+
+import org.apache.olingo.commons.api.edm.EdmProperty;
+
+/** Options for the OData serializer. */
+public class PrimitiveValueSerializerOptions {
+
+  private Boolean isNullable;
+  private Integer maxLength;
+  private Integer precision;
+  private Integer scale;
+  private Boolean isUnicode;
+
+  /** Gets the nullable facet. */
+  public Boolean isNullable() {
+    return isNullable;
+  }
+
+  /** Gets the maxLength facet. */
+  public Integer getMaxLength() {
+    return maxLength;
+  }
+
+  /** Gets the precision facet. */
+  public Integer getPrecision() {
+    return precision;
+  }
+
+  /** Gets the scale facet. */
+  public Integer getScale() {
+    return scale;
+  }
+
+  /** Gets the unicode facet. */
+  public Boolean isUnicode() {
+    return isUnicode;
+  }
+
+  private PrimitiveValueSerializerOptions() {}
+
+  /** Initializes the options builder. */
+  public static Builder with() {
+    return new Builder();
+  }
+
+  /** Builder of OData serializer options. */
+  public static final class Builder {
+
+    private PrimitiveValueSerializerOptions options;
+
+    private Builder() {
+      options = new PrimitiveValueSerializerOptions();
+    }
+
+    /** Sets the nullable facet. */
+    public Builder nullable(final Boolean isNullable) {
+      options.isNullable = isNullable;
+      return this;
+    }
+
+    /** Sets the maxLength facet. */
+    public Builder maxLength(final Integer maxLength) {
+      options.maxLength = maxLength;
+      return this;
+    }
+
+    /** Sets the precision facet. */
+    public Builder precision(final Integer precision) {
+      options.precision = precision;
+      return this;
+    }
+
+    /** Sets the scale facet. */
+    public Builder scale(final Integer scale) {
+      options.scale = scale;
+      return this;
+    }
+
+    /** Sets the unicode facet. */
+    public Builder unicode(final Boolean isUnicode) {
+      options.isUnicode = isUnicode;
+      return this;
+    }
+
+    /** Sets all facets from an EDM property. */
+    public Builder facetsFrom(final EdmProperty property) {
+      options.isNullable = property.isNullable();
+      options.maxLength = property.getMaxLength();
+      options.precision = property.getPrecision();
+      options.scale = property.getScale();
+      options.isUnicode = property.isUnicode();
+      return this;
+    }
+
+    /** Builds the OData serializer options. */
+    public PrimitiveValueSerializerOptions build() {
+      return options;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
index 5617a79..1583241 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/serializer/SerializerException.java
@@ -36,7 +36,8 @@ public class SerializerException extends ODataTranslatedException {
     /** parameter: property name */ UNSUPPORTED_PROPERTY_TYPE,
     /** parameter: property name */ INCONSISTENT_PROPERTY_TYPE,
     /** parameter: property name */ MISSING_PROPERTY,
-    /** parameters: property name, property value */ WRONG_PROPERTY_VALUE;
+    /** parameters: property name, property value */ WRONG_PROPERTY_VALUE,
+    /** parameters: primitive-type name, value */ WRONG_PRIMITIVE_VALUE;
 
     @Override
     public String getKey() {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/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 9171839..12e3b14 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
@@ -25,10 +25,12 @@ import org.apache.olingo.server.api.OData;
 import org.apache.olingo.server.api.ODataHttpHandler;
 import org.apache.olingo.server.api.ServiceMetadata;
 import org.apache.olingo.server.api.edm.provider.EdmProvider;
+import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
 import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.core.serializer.ODataXmlSerializerImpl;
+import org.apache.olingo.server.core.serializer.FixedFormatSerializerImpl;
 import org.apache.olingo.server.core.serializer.json.ODataJsonSerializer;
+import org.apache.olingo.server.core.serializer.xml.ODataXmlSerializerImpl;
 
 import java.util.List;
 
@@ -55,6 +57,11 @@ public class ODataImpl extends OData {
   }
 
   @Override
+  public FixedFormatSerializer createFixedFormatSerializer() throws SerializerException {
+    return new FixedFormatSerializerImpl();
+  }
+
+  @Override
   public ODataHttpHandler createHandler(final ServiceMetadata edm) {
     return new ODataHttpHandlerImpl(this, edm);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerImpl.java
new file mode 100644
index 0000000..01951ae
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerImpl.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.serializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+
+public class FixedFormatSerializerImpl implements FixedFormatSerializer {
+
+  @Override
+  public InputStream binary(final byte[] binary) throws SerializerException {
+    return new ByteArrayInputStream(binary);
+  }
+
+  @Override
+  public InputStream count(final Integer count) throws SerializerException {
+    return new ByteArrayInputStream(count.toString().getBytes());
+  }
+
+  @Override
+  public InputStream primitiveValue(final EdmPrimitiveType type, final Object value,
+      final PrimitiveValueSerializerOptions options) throws SerializerException {
+    try {
+      final String result = type.valueToString(value,
+          options.isNullable(), options.getMaxLength(),
+          options.getPrecision(), options.getScale(), options.isUnicode());
+      return new ByteArrayInputStream(result.getBytes("UTF-8"));
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new SerializerException("Error in primitive-value formatting.", e,
+          SerializerException.MessageKeys.WRONG_PRIMITIVE_VALUE,
+          type.getFullQualifiedName().getFullQualifiedNameAsString(), value.toString());
+    } catch (final UnsupportedEncodingException e) {
+      throw new SerializerException("Encoding exception.", e, SerializerException.MessageKeys.IO_EXCEPTION);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java
deleted file mode 100644
index 5138669..0000000
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/ODataXmlSerializerImpl.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.olingo.server.core.serializer;
-
-import java.io.InputStream;
-import java.util.List;
-
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-
-import org.apache.olingo.commons.api.data.Entity;
-import org.apache.olingo.commons.api.data.EntitySet;
-import org.apache.olingo.commons.api.data.Property;
-import org.apache.olingo.commons.api.edm.Edm;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
-import org.apache.olingo.commons.api.edm.EdmProperty;
-import org.apache.olingo.server.api.ODataServerError;
-import org.apache.olingo.server.api.ServiceMetadata;
-import org.apache.olingo.server.api.serializer.ODataSerializer;
-import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
-import org.apache.olingo.server.api.uri.UriParameter;
-import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
-import org.apache.olingo.server.api.uri.queryoption.SelectOption;
-import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
-import org.apache.olingo.server.core.serializer.utils.ContextURLHelper;
-import org.apache.olingo.server.core.serializer.xml.MetadataDocumentXmlSerializer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ODataXmlSerializerImpl implements ODataSerializer {
-
-  private static final Logger log = LoggerFactory.getLogger(ODataXmlSerializerImpl.class);
-
-  @Override
-  public InputStream serviceDocument(final Edm edm, final String serviceRoot) throws SerializerException {
-    throw new SerializerException("Service Document not implemented for XML format",
-        SerializerException.MessageKeys.NOT_IMPLEMENTED);
-  }
-
-  @Override
-  public InputStream metadataDocument(final ServiceMetadata serviceMetadata) throws SerializerException {
-    CircleStreamBuffer buffer;
-    XMLStreamWriter xmlStreamWriter = null;
-
-    // TODO: move stream initialization into separate method
-    try {
-      buffer = new CircleStreamBuffer();
-      xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET);
-      MetadataDocumentXmlSerializer serializer = new MetadataDocumentXmlSerializer(serviceMetadata);
-      serializer.writeMetadataDocument(xmlStreamWriter);
-      xmlStreamWriter.flush();
-      xmlStreamWriter.close();
-
-      return buffer.getInputStream();
-    } catch (final XMLStreamException e) {
-      log.error(e.getMessage(), e);
-      throw new SerializerException("An I/O exception occurred.", e,
-          SerializerException.MessageKeys.IO_EXCEPTION);
-    } finally {
-      if (xmlStreamWriter != null) {
-        try {
-          xmlStreamWriter.close();
-        } catch (XMLStreamException e) {
-          throw new SerializerException("An I/O exception occurred.", e,
-              SerializerException.MessageKeys.IO_EXCEPTION);
-        }
-      }
-    }
-  }
-
-  @Override
-  public InputStream entity(final EdmEntitySet edmEntitySet, final Entity entity,
-      final ODataSerializerOptions options) throws SerializerException {
-    throw new SerializerException("Entity serialization not implemented for XML format",
-        SerializerException.MessageKeys.NOT_IMPLEMENTED);
-  }
-
-  @Override
-  public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
-      final ODataSerializerOptions options) throws SerializerException {
-    throw new SerializerException("Entityset serialization not implemented for XML format",
-        SerializerException.MessageKeys.NOT_IMPLEMENTED);
-  }
-
-  @Override
-  public InputStream error(ODataServerError error) throws SerializerException {
-    throw new SerializerException("error serialization not implemented for XML format",
-        SerializerException.MessageKeys.NOT_IMPLEMENTED);
-  }
-
-  @Override
-  public  InputStream entityProperty(EdmProperty edmProperty, Property property,
-    ODataSerializerOptions options) throws SerializerException{
-    throw new SerializerException("error serialization not implemented for XML format",
-      SerializerException.MessageKeys.NOT_IMPLEMENTED);
-  }
-
-  @Override
-  public String buildContextURLSelectList(final EdmEntitySet edmEntitySet,
-      final ExpandOption expand, final SelectOption select) throws SerializerException {
-    return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select);
-  }
-
-  @Override
-  public String buildContextURLKeyPredicate(final List<UriParameter> keys) throws SerializerException {
-    return ContextURLHelper.buildKeyPredicate(keys);
-  }
-}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/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 d549ff0..aae934c 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
@@ -20,6 +20,7 @@ package org.apache.olingo.server.core.serializer.json;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
@@ -28,24 +29,28 @@ import org.apache.olingo.commons.api.data.ContextURL;
 import org.apache.olingo.commons.api.data.Entity;
 import org.apache.olingo.commons.api.data.EntitySet;
 import org.apache.olingo.commons.api.data.Link;
+import org.apache.olingo.commons.api.data.Linked;
 import org.apache.olingo.commons.api.data.LinkedComplexValue;
 import org.apache.olingo.commons.api.data.Property;
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmComplexType;
-import org.apache.olingo.commons.api.edm.EdmEntitySet;
 import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
 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.format.ODataFormat;
 import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
 import org.apache.olingo.server.api.ODataServerError;
 import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
 import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
 import org.apache.olingo.server.api.serializer.SerializerException;
-import org.apache.olingo.server.api.serializer.ODataSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
 import org.apache.olingo.server.api.uri.UriParameter;
 import org.apache.olingo.server.api.uri.queryoption.ExpandItem;
 import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
@@ -129,14 +134,14 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   @Override
-  public InputStream entitySet(final EdmEntitySet edmEntitySet, final EntitySet entitySet,
-      final ODataSerializerOptions options) throws SerializerException {
+  public InputStream entityCollection(final EdmEntityType entityType, final EntitySet entitySet,
+      final EntityCollectionSerializerOptions options) throws SerializerException {
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
       json.writeStartObject();
 
-      final ContextURL contextURL = checkContextURL(options);
+      final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
       if (contextURL != null) {
         json.writeStringField(Constants.JSON_CONTEXT,
             ContextURLBuilder.create(contextURL).toASCIIString());
@@ -147,7 +152,7 @@ public class ODataJsonSerializer implements ODataSerializer {
         json.writeNumberField(Constants.JSON_COUNT, entitySet.getCount());
       }
       json.writeFieldName(Constants.VALUE);
-      writeEntitySet(edmEntitySet.getEntityType(), entitySet,
+      writeEntitySet(entityType, entitySet,
           options == null ? null : options.getExpand(), options == null ? null : options.getSelect(), json);
       if (entitySet.getNext() != null) {
         json.writeStringField(Constants.JSON_NEXT_LINK, entitySet.getNext().toASCIIString());
@@ -161,13 +166,13 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   @Override
-  public InputStream entity(final EdmEntitySet edmEntitySet, final Entity entity,
-      final ODataSerializerOptions options) throws SerializerException {
-    final ContextURL contextURL = checkContextURL(options);
+  public InputStream entity(final EdmEntityType entityType, final Entity entity,
+      final EntitySerializerOptions options) throws SerializerException {
+    final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
-      writeEntity(edmEntitySet.getEntityType(), entity, contextURL,
+      writeEntity(entityType, entity, contextURL,
           options == null ? null : options.getExpand(), options == null ? null : options.getSelect(), json);
       json.close();
     } catch (final IOException e) {
@@ -177,16 +182,13 @@ public class ODataJsonSerializer implements ODataSerializer {
     return buffer.getInputStream();
   }
 
-  private ContextURL checkContextURL(final ODataSerializerOptions options) throws SerializerException {
+  private ContextURL checkContextURL(final ContextURL contextURL) throws SerializerException {
     if (format == ODataFormat.JSON_NO_METADATA) {
       return null;
-    } else {
-      final ContextURL contextURL = options == null ? null : options.getContextURL();
-      if (contextURL == null) {
-        throw new SerializerException("ContextURL null!", SerializerException.MessageKeys.NO_CONTEXT_URL);
-      }
-      return contextURL;
+    } else if (contextURL == null) {
+      throw new SerializerException("ContextURL null!", SerializerException.MessageKeys.NO_CONTEXT_URL);
     }
+    return contextURL;
   }
 
   protected void writeEntitySet(final EdmEntityType entityType, final EntitySet entitySet,
@@ -219,20 +221,20 @@ public class ODataJsonSerializer implements ODataSerializer {
         }
       }
     }
-    writeProperties(entityType, entity, select, json);
+    writeProperties(entityType, entity.getProperties(), select, json);
     writeNavigationProperties(entityType, entity, expand, json);
     json.writeEndObject();
   }
 
-  protected void writeProperties(final EdmEntityType entityType, final Entity entity, final SelectOption select,
-      JsonGenerator json) throws IOException, SerializerException {
+  protected void writeProperties(final EdmStructuredType type, final List<Property> properties,
+      final SelectOption select, JsonGenerator json) throws IOException, SerializerException {
     final boolean all = ExpandSelectHelper.isAll(select);
     final Set<String> selected = all ? null :
         ExpandSelectHelper.getSelectedPropertyNames(select.getSelectItems());
-    for (final String propertyName : entityType.getPropertyNames()) {
+    for (final String propertyName : type.getPropertyNames()) {
       if (all || selected.contains(propertyName)) {
-        final EdmProperty edmProperty = entityType.getStructuralProperty(propertyName);
-        final Property property = entity.getProperty(propertyName);
+        final EdmProperty edmProperty = type.getStructuralProperty(propertyName);
+        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);
@@ -240,16 +242,16 @@ public class ODataJsonSerializer implements ODataSerializer {
     }
   }
 
-  protected void writeNavigationProperties(final EdmEntityType entityType, final Entity entity,
+  protected void writeNavigationProperties(final EdmStructuredType type, final Linked linked,
       final ExpandOption expand, final JsonGenerator json) throws SerializerException, IOException {
     if (ExpandSelectHelper.hasExpand(expand)) {
       final boolean expandAll = ExpandSelectHelper.isExpandAll(expand);
       final Set<String> expanded = expandAll ? null :
           ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems());
-      for (final String propertyName : entityType.getNavigationPropertyNames()) {
+      for (final String propertyName : type.getNavigationPropertyNames()) {
         if (expandAll || expanded.contains(propertyName)) {
-          final EdmNavigationProperty property = entityType.getNavigationProperty(propertyName);
-          final Link navigationLink = entity.getNavigationLink(property.getName());
+          final EdmNavigationProperty property = type.getNavigationProperty(propertyName);
+          final Link navigationLink = linked.getNavigationLink(property.getName());
           final ExpandItem innerOptions = expandAll ? null :
               ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName);
           if (innerOptions != null && (innerOptions.isRef() || innerOptions.getLevelsOption() != null)) {
@@ -304,14 +306,25 @@ public class ODataJsonSerializer implements ODataSerializer {
       final Property property, final Set<List<String>> selectedPaths,
       final JsonGenerator json) throws IOException, SerializerException {
     try {
-      if (edmProperty.isCollection()) {
-        writeCollection(edmProperty, property, selectedPaths, json);
-      } else if (edmProperty.isPrimitive()) {
-        writePrimitive(edmProperty, property, json);
+      if (edmProperty.isPrimitive()) {
+        if (edmProperty.isCollection()) {
+          writePrimitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
+              edmProperty.isNullable(), edmProperty.getMaxLength(),
+              edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
+              json);
+        } else {
+          writePrimitive((EdmPrimitiveType) edmProperty.getType(), property,
+              edmProperty.isNullable(), edmProperty.getMaxLength(),
+              edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode(),
+              json);
+        }
+      } else if (edmProperty.isCollection()) {
+        writeComplexCollection((EdmComplexType) edmProperty.getType(), property, selectedPaths, json);
       } else if (property.isLinkedComplex()) {
-        writeComplexValue(edmProperty, property.asLinkedComplex().getValue(), selectedPaths, json);
+        writeComplexValue((EdmComplexType) edmProperty.getType(), property.asLinkedComplex().getValue(),
+            selectedPaths, json);
       } else if (property.isComplex()) {
-        writeComplexValue(edmProperty, property.asComplex(), selectedPaths, json);
+        writeComplexValue((EdmComplexType) edmProperty.getType(), property.asComplex(), selectedPaths, json);
       } else {
         throw new SerializerException("Property type not yet supported!",
             SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
@@ -323,56 +336,75 @@ public class ODataJsonSerializer implements ODataSerializer {
     }
   }
 
-  private void writeCollection(final EdmProperty edmProperty, final Property property,
-      final Set<List<String>> selectedPaths, JsonGenerator json)
-      throws IOException, EdmPrimitiveTypeException, SerializerException {
+  private void writePrimitiveCollection(final EdmPrimitiveType type, final Property property,
+      final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
+      final Boolean isUnicode,
+      JsonGenerator json) throws IOException, EdmPrimitiveTypeException, SerializerException {
     json.writeStartArray();
     for (Object value : property.asCollection()) {
       switch (property.getValueType()) {
       case COLLECTION_PRIMITIVE:
-        writePrimitiveValue(edmProperty, value, json);
+        writePrimitiveValue(type, value, isNullable, maxLength, precision, scale, isUnicode, json);
         break;
       case COLLECTION_GEOSPATIAL:
         throw new SerializerException("Property type not yet supported!",
-            SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
+            SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
       case COLLECTION_ENUM:
         json.writeString(value.toString());
         break;
+      default:
+        throw new SerializerException("Property type not yet supported!",
+            SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
+      }
+    }
+    json.writeEndArray();
+  }
+
+  private void writeComplexCollection(final EdmComplexType type, final Property property,
+      final Set<List<String>> selectedPaths, JsonGenerator json)
+      throws IOException, EdmPrimitiveTypeException, SerializerException {
+    json.writeStartArray();
+    for (Object value : property.asCollection()) {
+      switch (property.getValueType()) {
       case COLLECTION_LINKED_COMPLEX:
-        writeComplexValue(edmProperty, ((LinkedComplexValue) value).getValue(), selectedPaths, json);
+        writeComplexValue(type, ((LinkedComplexValue) value).getValue(), selectedPaths, json);
         break;
       case COLLECTION_COMPLEX:
-        writeComplexValue(edmProperty, property.asComplex(), selectedPaths, json);
+        writeComplexValue(type, property.asComplex(), selectedPaths, json);
         break;
       default:
         throw new SerializerException("Property type not yet supported!",
-            SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
+            SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
       }
     }
     json.writeEndArray();
   }
 
-  private void writePrimitive(EdmProperty edmProperty, Property property, JsonGenerator json)
+  private void writePrimitive(final EdmPrimitiveType type, final Property property,
+      final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
+      final Boolean isUnicode, JsonGenerator json)
       throws EdmPrimitiveTypeException, IOException, SerializerException {
     if (property.isPrimitive()) {
-      writePrimitiveValue(edmProperty, property.asPrimitive(), json);
+      writePrimitiveValue(type, property.asPrimitive(),
+          isNullable, maxLength, precision, scale, isUnicode, json);
     } else if (property.isGeospatial()) {
       throw new SerializerException("Property type not yet supported!",
-          SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, edmProperty.getName());
+          SerializerException.MessageKeys.UNSUPPORTED_PROPERTY_TYPE, property.getName());
     } else if (property.isEnum()) {
-      writePrimitiveValue(edmProperty, property.asEnum(), json);
+      writePrimitiveValue(type, property.asEnum(),
+          isNullable, maxLength, precision, scale, isUnicode, json);
     } else {
       throw new SerializerException("Inconsistent property type!",
-          SerializerException.MessageKeys.INCONSISTENT_PROPERTY_TYPE, edmProperty.getName());
+          SerializerException.MessageKeys.INCONSISTENT_PROPERTY_TYPE, property.getName());
     }
   }
 
-  protected void writePrimitiveValue(final EdmProperty edmProperty, final Object primitiveValue,
+  protected void writePrimitiveValue(final EdmPrimitiveType type, final Object primitiveValue,
+      final Boolean isNullable, final Integer maxLength, final Integer precision, final Integer scale,
+      final Boolean isUnicode,
       final JsonGenerator json) throws EdmPrimitiveTypeException, IOException {
-    final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
     final String value = type.valueToString(primitiveValue,
-        edmProperty.isNullable(), edmProperty.getMaxLength(),
-        edmProperty.getPrecision(), edmProperty.getScale(), edmProperty.isUnicode());
+        isNullable, maxLength, precision, scale, isUnicode);
     if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Boolean)) {
       json.writeBoolean(Boolean.parseBoolean(value));
     } else if (type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte)
@@ -389,18 +421,10 @@ public class ODataJsonSerializer implements ODataSerializer {
     }
   }
 
-  protected void writeComplexValue(final EdmProperty edmProperty, final List<Property> properties,
+  protected void writeComplexValue(final EdmComplexType type, final List<Property> properties,
       final Set<List<String>> selectedPaths, JsonGenerator json)
       throws IOException, EdmPrimitiveTypeException, SerializerException {
     json.writeStartObject();
-    writePropertyValues(edmProperty, properties, selectedPaths, json);
-    json.writeEndObject();
-  }
-
-  private void writePropertyValues(final EdmProperty edmProperty,
-                                   final List<Property> properties, final Set<List<String>> selectedPaths,
-                                   JsonGenerator json) throws IOException, SerializerException {
-    final EdmComplexType type = (EdmComplexType) edmProperty.getType();
     for (final String propertyName : type.getPropertyNames()) {
       final Property property = findProperty(propertyName, properties);
       if (selectedPaths == null || ExpandSelectHelper.isSelected(selectedPaths, propertyName)) {
@@ -409,6 +433,7 @@ public class ODataJsonSerializer implements ODataSerializer {
             json);
       }
     }
+    json.writeEndObject();
   }
 
   private Property findProperty(final String propertyName, final List<Property> properties) {
@@ -421,9 +446,9 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   @Override
-  public InputStream entityProperty(final EdmProperty edmProperty, final Property property,
-      final ODataSerializerOptions options) throws SerializerException {
-    final ContextURL contextURL = checkContextURL(options);
+  public InputStream primitive(final EdmPrimitiveType type, final Property property,
+      final PrimitiveSerializerOptions options) throws SerializerException {
+    final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
     CircleStreamBuffer buffer = new CircleStreamBuffer();
     try {
       JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
@@ -431,15 +456,45 @@ public class ODataJsonSerializer implements ODataSerializer {
       if (contextURL != null) {
         json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
       }
-      if (property.isPrimitive() && property.isNull()) {
+      if (property.isNull()) {
         throw new SerializerException("Property value can not be null.", SerializerException.MessageKeys.NULL_INPUT);
-      } else if (property.isComplex() && !property.isNull()) {
-        writePropertyValues(edmProperty, property.asComplex(), null, json);
-      } else if (property.isLinkedComplex() && !property.isNull()) {
-        writePropertyValues(edmProperty, property.asLinkedComplex().getValue(), null, json);
       } else {
         json.writeFieldName(Constants.VALUE);
-        writePropertyValue(edmProperty, property, null, json);
+        writePrimitive(type, property,
+            options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(),
+            options.isUnicode(),
+            json);
+      }
+      json.writeEndObject();
+      json.close();
+    } catch (final IOException e) {
+      throw new SerializerException("An I/O exception occurred.", e,
+          SerializerException.MessageKeys.IO_EXCEPTION);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new SerializerException("Wrong value for property!", e,
+          SerializerException.MessageKeys.WRONG_PROPERTY_VALUE,
+          property.getName(), property.getValue().toString());
+    }
+    return buffer.getInputStream();
+  }
+
+  @Override
+  public InputStream complex(final EdmComplexType type, final Property property,
+      final ComplexSerializerOptions options) throws SerializerException {
+    final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
+    CircleStreamBuffer buffer = new CircleStreamBuffer();
+    try {
+      JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
+      json.writeStartObject();
+      if (contextURL != null) {
+        json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
+      }
+      final List<Property> values = property.isNull() ? Collections.<Property> emptyList() :
+          property.isComplex() ? property.asComplex() : property.asLinkedComplex().getValue();
+      writeProperties(type, values, options == null ? null : options.getSelect(), json);
+      if (!property.isNull() && property.isLinkedComplex()) {
+        writeNavigationProperties(type, property.asLinkedComplex(),
+            options == null ? null : options.getExpand(), json);
       }
       json.writeEndObject();
       json.close();
@@ -451,9 +506,64 @@ public class ODataJsonSerializer implements ODataSerializer {
   }
 
   @Override
-  public String buildContextURLSelectList(final EdmEntitySet edmEntitySet,
+  public InputStream primitiveCollection(final EdmPrimitiveType type, final Property property,
+      final PrimitiveSerializerOptions options) throws SerializerException {
+    final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
+    CircleStreamBuffer buffer = new CircleStreamBuffer();
+    try {
+      JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
+      json.writeStartObject();
+      if (contextURL != null) {
+        json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
+      }
+      json.writeFieldName(Constants.VALUE);
+      writePrimitiveCollection(type, property,
+          options.isNullable(), options.getMaxLength(), options.getPrecision(), options.getScale(),
+          options.isUnicode(),
+          json);
+      json.writeEndObject();
+      json.close();
+    } catch (final IOException e) {
+      throw new SerializerException("An I/O exception occurred.", e,
+          SerializerException.MessageKeys.IO_EXCEPTION);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new SerializerException("Wrong value for property!", e,
+          SerializerException.MessageKeys.WRONG_PROPERTY_VALUE,
+          property.getName(), property.getValue().toString());
+    }
+    return buffer.getInputStream();
+  }
+
+  @Override
+  public InputStream complexCollection(final EdmComplexType type, final Property property,
+      final ComplexSerializerOptions options) throws SerializerException {
+    final ContextURL contextURL = checkContextURL(options == null ? null : options.getContextURL());
+    CircleStreamBuffer buffer = new CircleStreamBuffer();
+    try {
+      JsonGenerator json = new JsonFactory().createGenerator(buffer.getOutputStream());
+      json.writeStartObject();
+      if (contextURL != null) {
+        json.writeStringField(Constants.JSON_CONTEXT, ContextURLBuilder.create(contextURL).toASCIIString());
+      }
+      json.writeFieldName(Constants.VALUE);
+      writeComplexCollection(type, property, null, json);
+      json.writeEndObject();
+      json.close();
+    } catch (final IOException e) {
+      throw new SerializerException("An I/O exception occurred.", e,
+          SerializerException.MessageKeys.IO_EXCEPTION);
+    } catch (final EdmPrimitiveTypeException e) {
+      throw new SerializerException("Wrong value for property!", e,
+          SerializerException.MessageKeys.WRONG_PROPERTY_VALUE,
+          property.getName(), property.getValue().toString());
+    }
+    return buffer.getInputStream();
+  }
+
+  @Override
+  public String buildContextURLSelectList(final EdmStructuredType type,
       final ExpandOption expand, final SelectOption select) throws SerializerException {
-    return ContextURLHelper.buildSelectList(edmEntitySet.getEntityType(), expand, select);
+    return ContextURLHelper.buildSelectList(type, expand, select);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
index 9bfac40..4a3f82a 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLBuilder.java
@@ -56,12 +56,12 @@ public final class ContextURLBuilder {
     if (contextURL.getKeyPath() != null) {
       result.append('(').append(contextURL.getKeyPath()).append(')');
     }
-    if (contextURL.getSelectList() != null) {
-      result.append('(').append(contextURL.getSelectList()).append(')');
-    }
     if (contextURL.getNavOrPropertyPath() != null) {
       result.append('/').append(contextURL.getNavOrPropertyPath());
     }
+    if (contextURL.getSelectList() != null) {
+      result.append('(').append(contextURL.getSelectList()).append(')');
+    }
     if (contextURL.isReference()) {
       if (contextURL.getEntitySetOrSingletonOrType() != null) {
         throw new IllegalArgumentException("ContextURL: $ref with Entity Set");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
index 80c13de..e9eb880 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/utils/ContextURLHelper.java
@@ -24,8 +24,8 @@ import java.util.List;
 import java.util.Set;
 
 import org.apache.olingo.commons.api.edm.EdmComplexType;
-import org.apache.olingo.commons.api.edm.EdmEntityType;
 import org.apache.olingo.commons.api.edm.EdmProperty;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
 import org.apache.olingo.commons.core.Encoder;
 import org.apache.olingo.server.api.serializer.SerializerException;
 import org.apache.olingo.server.api.uri.UriParameter;
@@ -39,37 +39,37 @@ public final class ContextURLHelper {
   /** Builds a list of selected Properties for the ContextURL,
    *  taking care to preserve the order as defined in the EDM;
    *  returns NULL if no selection has taken place.
-   * @param entityType the Entity Type
-   * @param expand     the Expand option (from the URL's $expand query option)
-   * @param select     the Select option (from the URL's $select query option)
+   * @param type   the structured type
+   * @param expand the Expand option (from the URL's $expand query option)
+   * @param select the Select option (from the URL's $select query option)
    * @return a select-list String
    * @throws SerializerException if an unsupported feature is used
    */
-  public static String buildSelectList(final EdmEntityType entityType,
+  public static String buildSelectList(final EdmStructuredType type,
       final ExpandOption expand, final SelectOption select) throws SerializerException {
     StringBuilder result = new StringBuilder();
     if (ExpandSelectHelper.hasSelect(select)) {
-      handleSelect(entityType, select, result);
+      handleSelect(type, select, result);
     }
 
     if (ExpandSelectHelper.hasExpand(expand) && !ExpandSelectHelper.isExpandAll(expand)) {
-      handleExpand(entityType, expand, result);
+      handleExpand(type, expand, result);
     }
     return result.length() == 0 ? null : result.toString();
   }
 
-  private static void handleSelect(final EdmEntityType entityType, final SelectOption select, StringBuilder result) {
+  private static void handleSelect(final EdmStructuredType type, final SelectOption select, StringBuilder result) {
     if (ExpandSelectHelper.isAll(select)) {
       result.append('*');
     } else {
       final List<SelectItem> selectItems = select.getSelectItems();
       final Set<String> selectedPropertyNames = ExpandSelectHelper.getSelectedPropertyNames(selectItems);
-      for (final String propertyName : entityType.getPropertyNames()) {
+      for (final String propertyName : type.getPropertyNames()) {
         if (selectedPropertyNames.contains(propertyName)) {
           if (result.length() > 0) {
             result.append(',');
           }
-          final EdmProperty edmProperty = (EdmProperty) entityType.getProperty(propertyName);
+          final EdmProperty edmProperty = type.getStructuralProperty(propertyName);
           final Set<List<String>> selectedPaths = ExpandSelectHelper.getSelectedPaths(selectItems, propertyName);
           if (selectedPaths == null) {
             result.append(Encoder.encode(propertyName));
@@ -98,16 +98,16 @@ public final class ContextURLHelper {
     }
   }
 
-  private static void handleExpand(final EdmEntityType entityType, final ExpandOption expand, StringBuilder result)
+  private static void handleExpand(final EdmStructuredType type, final ExpandOption expand, StringBuilder result)
       throws SerializerException {
     final Set<String> expandedPropertyNames = ExpandSelectHelper.getExpandedPropertyNames(expand.getExpandItems());
-    for (final String propertyName : entityType.getNavigationPropertyNames()) {
+    for (final String propertyName : type.getNavigationPropertyNames()) {
       if (expandedPropertyNames.contains(propertyName)) {
         final ExpandItem expandItem = ExpandSelectHelper.getExpandItem(expand.getExpandItems(), propertyName);
         if (ExpandSelectHelper.hasExpand(expandItem.getExpandOption())
             && !ExpandSelectHelper.isExpandAll(expandItem.getExpandOption())
             || ExpandSelectHelper.hasSelect(expandItem.getSelectOption())) {
-          final String innerSelectList = buildSelectList(entityType.getNavigationProperty(propertyName).getType(),
+          final String innerSelectList = buildSelectList(type.getNavigationProperty(propertyName).getType(),
               expandItem.getExpandOption(), expandItem.getSelectOption());
           if (innerSelectList != null) {
             if (result.length() > 0) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java
new file mode 100644
index 0000000..429a1d2
--- /dev/null
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/serializer/xml/ODataXmlSerializerImpl.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.serializer.xml;
+
+import java.io.InputStream;
+import java.util.List;
+
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.Property;
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.EdmComplexType;
+import org.apache.olingo.commons.api.edm.EdmEntityType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmStructuredType;
+import org.apache.olingo.server.api.ODataServerError;
+import org.apache.olingo.server.api.ServiceMetadata;
+import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
+import org.apache.olingo.server.api.serializer.EntityCollectionSerializerOptions;
+import org.apache.olingo.server.api.serializer.ODataSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.apache.olingo.server.api.serializer.EntitySerializerOptions;
+import org.apache.olingo.server.api.uri.UriParameter;
+import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
+import org.apache.olingo.server.api.uri.queryoption.SelectOption;
+import org.apache.olingo.server.core.serializer.utils.CircleStreamBuffer;
+import org.apache.olingo.server.core.serializer.utils.ContextURLHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ODataXmlSerializerImpl implements ODataSerializer {
+
+  /** The default character set is UTF-8. */
+  public static final String DEFAULT_CHARSET = "UTF-8";
+
+  private static final Logger log = LoggerFactory.getLogger(ODataXmlSerializerImpl.class);
+
+  @Override
+  public InputStream serviceDocument(final Edm edm, final String serviceRoot) throws SerializerException {
+    throw new SerializerException("Service Document not implemented for XML format",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public InputStream metadataDocument(final ServiceMetadata serviceMetadata) throws SerializerException {
+    CircleStreamBuffer buffer;
+    XMLStreamWriter xmlStreamWriter = null;
+
+    // TODO: move stream initialization into separate method
+    try {
+      buffer = new CircleStreamBuffer();
+      xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer.getOutputStream(), DEFAULT_CHARSET);
+      MetadataDocumentXmlSerializer serializer = new MetadataDocumentXmlSerializer(serviceMetadata);
+      serializer.writeMetadataDocument(xmlStreamWriter);
+      xmlStreamWriter.flush();
+      xmlStreamWriter.close();
+
+      return buffer.getInputStream();
+    } catch (final XMLStreamException e) {
+      log.error(e.getMessage(), e);
+      throw new SerializerException("An I/O exception occurred.", e,
+          SerializerException.MessageKeys.IO_EXCEPTION);
+    } finally {
+      if (xmlStreamWriter != null) {
+        try {
+          xmlStreamWriter.close();
+        } catch (XMLStreamException e) {
+          throw new SerializerException("An I/O exception occurred.", e,
+              SerializerException.MessageKeys.IO_EXCEPTION);
+        }
+      }
+    }
+  }
+
+  @Override
+  public InputStream entity(final EdmEntityType entityType, final Entity entity,
+      final EntitySerializerOptions options) throws SerializerException {
+    throw new SerializerException("Entity serialization not implemented for XML format",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public InputStream entityCollection(final EdmEntityType entityType, final EntitySet entitySet,
+      final EntityCollectionSerializerOptions options) throws SerializerException {
+    throw new SerializerException("Entityset serialization not implemented for XML format",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public InputStream error(ODataServerError error) throws SerializerException {
+    throw new SerializerException("error serialization not implemented for XML format",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public InputStream primitive(final EdmPrimitiveType type, final Property property,
+      final PrimitiveSerializerOptions options) throws SerializerException {
+    throw new SerializerException("Serialization not implemented for XML format.",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public InputStream complex(final EdmComplexType type, final Property property,
+      final ComplexSerializerOptions options) throws SerializerException {
+    throw new SerializerException("Serialization not implemented for XML format.",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public InputStream primitiveCollection(final EdmPrimitiveType type, final Property property,
+      final PrimitiveSerializerOptions options) throws SerializerException {
+    throw new SerializerException("Serialization not implemented for XML format.",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public InputStream complexCollection(final EdmComplexType type, final Property property,
+      final ComplexSerializerOptions options) throws SerializerException {
+    throw new SerializerException("Serialization not implemented for XML format.",
+        SerializerException.MessageKeys.NOT_IMPLEMENTED);
+  }
+
+  @Override
+  public String buildContextURLSelectList(final EdmStructuredType type,
+      final ExpandOption expand, final SelectOption select) throws SerializerException {
+    return ContextURLHelper.buildSelectList(type, expand, select);
+  }
+
+  @Override
+  public String buildContextURLKeyPredicate(final List<UriParameter> keys) throws SerializerException {
+    return ContextURLHelper.buildKeyPredicate(keys);
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
index 15f4ab8..522c3a0 100644
--- a/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
+++ b/lib/server-core/src/main/resources/server-core-exceptions-i18n.properties
@@ -94,3 +94,4 @@ SerializerException.UNSUPPORTED_PROPERTY_TYPE=The type of the property '%1$s' is
 SerializerException.INCONSISTENT_PROPERTY_TYPE=An inconsistency has been detected in the type definition of property '%1$s'.
 SerializerException.MISSING_PROPERTY=The non-nullable property '%1$s' is missing.
 SerializerException.WRONG_PROPERTY_VALUE=The value '%2$s' is not valid for property '%1$s'.
+SerializerException.WRONG_PRIMITIVE_VALUE=The value '%2$s' is not valid for the primitive type '%1$s' and the given facets.

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/c2c8bf19/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerTest.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerTest.java b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerTest.java
new file mode 100644
index 0000000..ce319fc
--- /dev/null
+++ b/lib/server-core/src/test/java/org/apache/olingo/server/core/serializer/FixedFormatSerializerTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.olingo.server.core.serializer;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
+import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
+import org.apache.olingo.server.api.serializer.SerializerException;
+import org.junit.Test;
+
+public class FixedFormatSerializerTest {
+
+  private final FixedFormatSerializer serializer;
+
+  public FixedFormatSerializerTest() throws SerializerException {
+    serializer = OData.newInstance().createFixedFormatSerializer();
+  }
+
+  @Test
+  public void binary() throws Exception {
+    assertEquals("ABC", IOUtils.toString(serializer.binary(new byte [] { 0x41, 0x42, 0x43 })));
+  }
+
+  @Test
+  public void count() throws Exception {
+    assertEquals("42", IOUtils.toString(serializer.count(42)));
+  }
+
+  @Test
+  public void primitiveValue() throws Exception {
+    final EdmPrimitiveType type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int32);
+    assertEquals("42", IOUtils.toString(serializer.primitiveValue(type, 42,
+        PrimitiveValueSerializerOptions.with().nullable(true).build())));
+  }
+}